(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
aarch64/
vect-vfmaxv.c
       1  /* { dg-do run } */
       2  /* { dg-options "-O3 --save-temps -ffast-math" } */
       3  
       4  #include <arm_neon.h>
       5  
       6  extern void abort (void);
       7  
       8  extern float fabsf (float);
       9  extern double fabs (double);
      10  extern int isnan (double);
      11  extern float fmaxf (float, float);
      12  extern float fminf (float, float);
      13  extern double fmax (double, double);
      14  extern double fmin (double, double);
      15  
      16  #define NUM_TESTS 16
      17  #define DELTA 0.000001
      18  #define NAN (0.0 / 0.0)
      19  
      20  float input_float32[] = {0.1f, -0.1f, 0.4f, 10.3f,
      21  			 200.0f, -800.0f, -13.0f, -0.5f,
      22  			 NAN, -870.0f, 10.4f, 310.11f,
      23  			 0.0f, -865.0f, -2213.0f, -1.5f};
      24  
      25  double input_float64[] = {0.1, -0.1, 0.4, 10.3,
      26  			  200.0, -800.0, -13.0, -0.5,
      27  			  NAN, -870.0, 10.4, 310.11,
      28  			  0.0, -865.0, -2213.0, -1.5};
      29  
      30  #define EQUALF(a, b) (fabsf (a - b) < DELTA)
      31  #define EQUALD(a, b) (fabs (a - b) < DELTA)
      32  
      33  /* Floating point 'unordered' variants.  */
      34  
      35  #undef TEST
      36  #define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES, FLOAT)		\
      37  int									\
      38  test_v##MAXMIN##v##SUFFIX##_##TYPE##x##LANES##_t (void)			\
      39  {									\
      40    int i, j;								\
      41    int moves = (NUM_TESTS - LANES) + 1;					\
      42    TYPE##_t out_l[NUM_TESTS];						\
      43    TYPE##_t out_v[NUM_TESTS];						\
      44  									\
      45    /* Calculate linearly.  */						\
      46    for (i = 0; i < moves; i++)						\
      47      {									\
      48        out_l[i] = input_##TYPE[i];					\
      49        for (j = 0; j < LANES; j++)					\
      50  	{								\
      51  	  if (isnan (out_l[i]))						\
      52  	    continue;							\
      53  	  if (isnan (input_##TYPE[i + j])				\
      54  	      || input_##TYPE[i + j] CMP_OP out_l[i])			\
      55  	    out_l[i] = input_##TYPE[i + j];				\
      56  	}								\
      57      }									\
      58  									\
      59    /* Calculate using vector reduction intrinsics.  */			\
      60    for (i = 0; i < moves; i++)						\
      61      {									\
      62        TYPE##x##LANES##_t t1 = vld1##Q##_##SUFFIX (input_##TYPE + i);	\
      63        out_v[i] = v##MAXMIN##v##Q##_##SUFFIX (t1);			\
      64      }									\
      65  									\
      66    /* Compare.  */							\
      67    for (i = 0; i < moves; i++)						\
      68      {									\
      69        if (!EQUAL##FLOAT (out_v[i], out_l[i])				\
      70  			 && !(isnan (out_v[i]) && isnan (out_l[i])))	\
      71  	return 0;							\
      72      }									\
      73    return 1;								\
      74  }
      75  
      76  #define BUILD_VARIANTS(TYPE, STYPE, W32, W64, F)	\
      77  TEST (max, >, STYPE,  , TYPE, W32, F)			\
      78  TEST (max, >, STYPE, q, TYPE, W64, F)			\
      79  TEST (min, <, STYPE,  , TYPE, W32, F)			\
      80  TEST (min, <, STYPE, q, TYPE, W64, F)
      81  
      82  BUILD_VARIANTS (float32, f32, 2, 4, F)
      83  /* { dg-final { scan-assembler "fmaxp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */
      84  /* { dg-final { scan-assembler "fminp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */
      85  /* { dg-final { scan-assembler "fmaxv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */
      86  /* { dg-final { scan-assembler "fminv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */
      87  TEST (max, >, f64, q, float64, 2, D)
      88  /* { dg-final { scan-assembler "fmaxp\\td\[0-9\]+, v\[0-9\]+\.2d" } } */
      89  TEST (min, <, f64, q, float64, 2, D)
      90  /* { dg-final { scan-assembler "fminp\\td\[0-9\]+, v\[0-9\]+\.2d" } } */
      91  
      92  /* Floating point 'nm' variants.  */
      93  
      94  #undef TEST
      95  #define TEST(MAXMIN, F, SUFFIX, Q, TYPE, LANES, FLOAT)			\
      96  int									\
      97  test_v##MAXMIN##nmv##SUFFIX##_##TYPE##x##LANES##_t (void)		\
      98  {									\
      99    int i, j;								\
     100    int moves = (NUM_TESTS - LANES) + 1;					\
     101    TYPE##_t out_l[NUM_TESTS];						\
     102    TYPE##_t out_v[NUM_TESTS];						\
     103  									\
     104    /* Calculate linearly.  */						\
     105    for (i = 0; i < moves; i++)						\
     106      {									\
     107        out_l[i] = input_##TYPE[i];					\
     108        for (j = 0; j < LANES; j++)					\
     109  	out_l[i] = f##MAXMIN##F (input_##TYPE[i + j],  out_l[i]);	\
     110      }									\
     111  									\
     112    /* Calculate using vector reduction intrinsics.  */			\
     113    for (i = 0; i < moves; i++)						\
     114      {									\
     115        TYPE##x##LANES##_t t1 = vld1##Q##_##SUFFIX (input_##TYPE + i);	\
     116        out_v[i] = v##MAXMIN##nmv##Q##_##SUFFIX (t1);			\
     117      }									\
     118  									\
     119    /* Compare.  */							\
     120    for (i = 0; i < moves; i++)						\
     121      {									\
     122        if (!EQUAL##FLOAT (out_v[i], out_l[i]))				\
     123  	return 0;							\
     124      }									\
     125    return 1;								\
     126  }
     127  
     128  TEST (max, f, f32, , float32, 2, D)
     129  /* { dg-final { scan-assembler "fmaxnmp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */
     130  TEST (min, f, f32, , float32, 2, D)
     131  /* { dg-final { scan-assembler "fminnmp\\ts\[0-9\]+, v\[0-9\]+\.2s" } } */
     132  TEST (max, f, f32, q, float32, 4, D)
     133  /* { dg-final { scan-assembler "fmaxnmv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */
     134  TEST (min, f, f32, q, float32, 4, D)
     135  /* { dg-final { scan-assembler "fminnmv\\ts\[0-9\]+, v\[0-9\]+\.4s" } } */
     136  TEST (max, , f64, q, float64, 2, D)
     137  /* { dg-final { scan-assembler "fmaxnmp\\td\[0-9\]+, v\[0-9\]+\.2d" } } */
     138  TEST (min, , f64, q, float64, 2, D)
     139  /* { dg-final { scan-assembler "fminnmp\\td\[0-9\]+, v\[0-9\]+\.2d" } } */
     140  
     141  #undef TEST
     142  #define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES, FLOAT)		\
     143  {									\
     144    if (!test_v##MAXMIN##v##SUFFIX##_##TYPE##x##LANES##_t ())		\
     145      abort ();								\
     146  }
     147  
     148  int
     149  main (int argc, char **argv)
     150  {
     151    BUILD_VARIANTS (float32, f32, 2, 4, F)
     152    TEST (max, >, f64, q, float64, 2, D)
     153    TEST (min, <, f64, q, float64, 2, D)
     154  
     155  #undef TEST
     156  #define TEST(MAXMIN, CMP_OP, SUFFIX, Q, TYPE, LANES, FLOAT)		\
     157  {									\
     158    if (!test_v##MAXMIN##nmv##SUFFIX##_##TYPE##x##LANES##_t ())		\
     159      abort ();								\
     160  }
     161  
     162    BUILD_VARIANTS (float32, f32, 2, 4, F)
     163    TEST (max, >, f64, q, float64, 2, D)
     164    TEST (min, <, f64, q, float64, 2, D)
     165  
     166    return 0;
     167  }
     168