(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
aarch64/
vect-vrnd.c
       1  /* { dg-do run } */
       2  /* { dg-options "-O3 --save-temps" } */
       3  
       4  #include <arm_neon.h>
       5  
       6  extern void abort (void);
       7  extern float fabsf (float);
       8  extern double fabs (double);
       9  
      10  extern double trunc (double);
      11  extern double round (double);
      12  extern double nearbyint (double);
      13  extern double floor (double);
      14  extern double ceil (double);
      15  extern double rint (double);
      16  
      17  extern float truncf (float);
      18  extern float roundf (float);
      19  extern float nearbyintf (float);
      20  extern float floorf (float);
      21  extern float ceilf (float);
      22  extern float rintf (float);
      23  
      24  #define NUM_TESTS 8
      25  #define DELTA 0.000001
      26  
      27  float input_f32[] = {0.1f, -0.1f, 0.4f, 10.3f,
      28  		     200.0f, -800.0f, -13.0f, -0.5f};
      29  double input_f64[] = {0.1, -0.1, 0.4, 10.3,
      30  		      200.0, -800.0, -13.0, -0.5};
      31  
      32  #define TEST(SUFFIX, Q, WIDTH, LANES, C_FN, F)		     		\
      33  int									\
      34  test_vrnd##SUFFIX##_float##WIDTH##x##LANES##_t (void)			\
      35  {									\
      36    int ret = 1;								\
      37    int i = 0;								\
      38    int nlanes = LANES;							\
      39    float##WIDTH##_t expected_out[NUM_TESTS];				\
      40    float##WIDTH##_t actual_out[NUM_TESTS];				\
      41  									\
      42    for (i = 0; i < NUM_TESTS; i++)					\
      43      {									\
      44        expected_out[i] = C_FN##F (input_f##WIDTH[i]);			\
      45        /* Don't vectorize this.  */					\
      46        asm volatile ("" : : : "memory");					\
      47      }									\
      48  									\
      49    /* Prevent the compiler from noticing these two loops do the same	\
      50       thing and optimizing away the comparison.  */			\
      51    asm volatile ("" : : : "memory");					\
      52  									\
      53    for (i = 0; i < NUM_TESTS; i+=nlanes)					\
      54      {									\
      55        float##WIDTH##x##LANES##_t out =					\
      56  	vrnd##SUFFIX##Q##_f##WIDTH					\
      57  		(vld1##Q##_f##WIDTH (input_f##WIDTH + i));		\
      58        vst1##Q##_f##WIDTH (actual_out + i, out);				\
      59      }									\
      60  									\
      61    for (i = 0; i < NUM_TESTS; i++)					\
      62      ret &= fabs##F (expected_out[i] - actual_out[i]) < DELTA;		\
      63  									\
      64    return ret;								\
      65  }									\
      66  
      67  
      68  #define BUILD_VARIANTS(SUFFIX, C_FN)	\
      69  TEST (SUFFIX,  , 32, 2, C_FN, f)	\
      70  TEST (SUFFIX, q, 32, 4, C_FN, f)	\
      71  TEST (SUFFIX, q, 64, 2, C_FN,  )	\
      72  
      73  BUILD_VARIANTS ( , trunc)
      74  /* { dg-final { scan-assembler "frintz\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */
      75  /* { dg-final { scan-assembler "frintz\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */
      76  /* { dg-final { scan-assembler "frintz\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */
      77  BUILD_VARIANTS (a, round)
      78  /* { dg-final { scan-assembler "frinta\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */
      79  /* { dg-final { scan-assembler "frinta\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */
      80  /* { dg-final { scan-assembler "frinta\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */
      81  BUILD_VARIANTS (i, nearbyint)
      82  /* { dg-final { scan-assembler "frinti\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */
      83  /* { dg-final { scan-assembler "frinti\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */
      84  /* { dg-final { scan-assembler "frinti\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */
      85  BUILD_VARIANTS (m, floor)
      86  /* { dg-final { scan-assembler "frintm\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */
      87  /* { dg-final { scan-assembler "frintm\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */
      88  /* { dg-final { scan-assembler "frintm\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */
      89  BUILD_VARIANTS (p, ceil)
      90  /* { dg-final { scan-assembler "frintp\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */
      91  /* { dg-final { scan-assembler "frintp\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */
      92  /* { dg-final { scan-assembler "frintp\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */
      93  BUILD_VARIANTS (x, rint)
      94  /* { dg-final { scan-assembler "frintx\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" } } */
      95  /* { dg-final { scan-assembler "frintx\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" } } */
      96  /* { dg-final { scan-assembler "frintx\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */
      97  
      98  #undef TEST
      99  #define TEST(SUFFIX, Q, WIDTH, LANES, C_FN, F)			\
     100  {								\
     101    if (!test_vrnd##SUFFIX##_float##WIDTH##x##LANES##_t ())	\
     102      abort ();							\
     103  }
     104  
     105  int
     106  main (int argc, char **argv)
     107  {
     108    BUILD_VARIANTS ( , trunc)
     109    BUILD_VARIANTS (a, round)
     110    BUILD_VARIANTS (i, nearbyint)
     111    BUILD_VARIANTS (m, floor)
     112    BUILD_VARIANTS (p, ceil)
     113    BUILD_VARIANTS (x, rint)
     114    return 0;
     115  }
     116