(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
aarch64/
vneg_f.c
       1  /* Test vneg works correctly.  */
       2  /* { dg-do run } */
       3  /* { dg-options "--save-temps" } */
       4  
       5  #include <arm_neon.h>
       6  
       7  #define FLT_EPSILON __FLT_EPSILON__
       8  #define DBL_EPSILON __DBL_EPSILON__
       9  #define FLT_MAX __FLT_MAX__
      10  #define FLT_MIN __FLT_MIN__
      11  #define DBL_MAX __DBL_MAX__
      12  #define DBL_MIN __DBL_MIN__
      13  
      14  #define TEST0 0
      15  /* 6 digits of pi.  */
      16  #define TEST1 3.14159
      17  /* 6 digits of -e.  */
      18  #define TEST2 -2.71828
      19  /* 2^25, float has 24 significand bits
      20     according to Single-precision floating-point format.  */
      21  #define TEST3_FLT 33554432
      22  /* 2^54, double has 53 significand bits
      23     according to Double-precision floating-point format.  */
      24  #define TEST3_DBL 18014398509481984
      25  
      26  extern void abort (void);
      27  
      28  #define FLT_INFINITY (__builtin_inff ())
      29  #define DBL_INFINITY (__builtin_inf ())
      30  
      31  #ifndef NAN
      32  #define NAN (0.0 / 0.0)
      33  #endif
      34  
      35  #define CONCAT(a, b) a##b
      36  #define CONCAT1(a, b) CONCAT (a, b)
      37  #define REG_INFEX64 _
      38  #define REG_INFEX128 q_
      39  #define REG_INFEX(reg_len) REG_INFEX##reg_len
      40  #define POSTFIX(reg_len, data_len) \
      41    CONCAT1 (REG_INFEX (reg_len), f##data_len)
      42  
      43  #define DATA_TYPE_32 float
      44  #define DATA_TYPE_64 double
      45  #define DATA_TYPE(data_len) DATA_TYPE_##data_len
      46  
      47  #define STORE_INST(reg_len, data_len) \
      48    CONCAT1 (vst1, POSTFIX (reg_len, data_len))
      49  #define LOAD_INST(reg_len, data_len) \
      50    CONCAT1 (vld1, POSTFIX (reg_len, data_len))
      51  #define NEG_INST(reg_len, data_len) \
      52    CONCAT1 (vneg, POSTFIX (reg_len, data_len))
      53  
      54  #define INHIB_OPTIMIZATION asm volatile ("" : : : "memory")
      55  #define RUN_TEST(test_set, reg_len, data_len, n, a, b, c) \
      56    {						       \
      57      int i;					       \
      58      (a) = LOAD_INST (reg_len, data_len) (test_set);    \
      59      (b) = NEG_INST (reg_len, data_len) (a);	       \
      60      STORE_INST (reg_len, data_len) (c, b);	       \
      61      for (i = 0; i < n; i++)			       \
      62        {						       \
      63  	DATA_TYPE (data_len) diff;		       \
      64  	INHIB_OPTIMIZATION;			       \
      65  	diff = test_set[i] + c[i];		       \
      66  	if (diff > EPSILON)			       \
      67  	    return 1;				       \
      68        }						       \
      69    }
      70  
      71  #define TEST3 TEST3_FLT
      72  #define EPSILON FLT_EPSILON
      73  #define VAR_MIN FLT_MIN
      74  #define VAR_MAX FLT_MAX
      75  #define INFINITY FLT_INFINITY
      76  
      77  int
      78  test_vneg_f32 ()
      79  {
      80    float32x2_t a;
      81    float32x2_t b;
      82    float32_t c[2];
      83  
      84    float32_t test_set0[2] = { TEST0, TEST1 };
      85    float32_t test_set1[2] = { TEST2, TEST3 };
      86    float32_t test_set2[2] = { VAR_MAX, VAR_MIN };
      87    float32_t test_set3[2] = { INFINITY, NAN };
      88  
      89    RUN_TEST (test_set0, 64, 32, 2, a, b, c);
      90    RUN_TEST (test_set1, 64, 32, 2, a, b, c);
      91    RUN_TEST (test_set2, 64, 32, 2, a, b, c);
      92    RUN_TEST (test_set3, 64, 32, 0, a, b, c);
      93  
      94    /* Since last test cannot be checked in a uniform way by adding
      95       negation result to original value, the number of lanes to be
      96       checked in RUN_TEST is 0 (last argument).  Instead, result
      97       will be checked manually.  */
      98  
      99    if (c[0] != -INFINITY)
     100      return 1;
     101  
     102    if (!__builtin_isnan (c[1]))
     103      return 1;
     104  
     105    return 0;
     106  }
     107  
     108  /* { dg-final { scan-assembler-times "fneg\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" 4 } } */
     109  
     110  #undef TEST3
     111  #undef EPSILON
     112  #undef VAR_MIN
     113  #undef VAR_MAX
     114  #undef INFINITY
     115  
     116  #define TEST3 TEST3_DBL
     117  #define EPSILON DBL_EPSILON
     118  #define VAR_MIN DBL_MIN
     119  #define VAR_MAX DBL_MAX
     120  #define INFINITY DBL_INFINITY
     121  
     122  int
     123  test_vneg_f64 ()
     124  {
     125    float64x1_t a;
     126    float64x1_t b;
     127    float64_t c[1];
     128  
     129    float64_t test_set0[1] = { TEST0 };
     130    float64_t test_set1[1] = { TEST1 };
     131    float64_t test_set2[1] = { TEST2 };
     132    float64_t test_set3[1] = { TEST3 };
     133    float64_t test_set4[1] = { VAR_MAX };
     134    float64_t test_set5[1] = { VAR_MIN };
     135    float64_t test_set6[1] = { INFINITY };
     136    float64_t test_set7[1] = { NAN };
     137  
     138    RUN_TEST (test_set0, 64, 64, 1, a, b, c);
     139    RUN_TEST (test_set1, 64, 64, 1, a, b, c);
     140    RUN_TEST (test_set2, 64, 64, 1, a, b, c);
     141    RUN_TEST (test_set3, 64, 64, 1, a, b, c);
     142    RUN_TEST (test_set4, 64, 64, 1, a, b, c);
     143    RUN_TEST (test_set5, 64, 64, 1, a, b, c);
     144    RUN_TEST (test_set6, 64, 64, 0, a, b, c);
     145  
     146    /* Since last test cannot be checked in a uniform way by adding
     147       negation result to original value, the number of lanes to be
     148       checked in RUN_TEST is 0 (last argument).  Instead, result
     149       will be checked manually.  */
     150  
     151    if (c[0] != -INFINITY)
     152      return 1;
     153  
     154    /* Same as above.  */
     155  
     156    RUN_TEST (test_set7, 64, 64, 0, a, b, c);
     157  
     158    if (!__builtin_isnan (c[0]))
     159      return 1;
     160  
     161    return 0;
     162  }
     163  
     164  /* { dg-final { scan-assembler-times "fneg\\td\[0-9\]+, d\[0-9\]+" 8 } } */
     165  
     166  #undef TEST3
     167  #undef EPSILON
     168  #undef VAR_MIN
     169  #undef VAR_MAX
     170  #undef INFINITY
     171  
     172  #define TEST3 TEST3_FLT
     173  #define EPSILON FLT_EPSILON
     174  #define VAR_MIN FLT_MIN
     175  #define VAR_MAX FLT_MAX
     176  #define INFINITY FLT_INFINITY
     177  
     178  int
     179  test_vnegq_f32 ()
     180  {
     181    float32x4_t a;
     182    float32x4_t b;
     183    float32_t c[4];
     184  
     185    float32_t test_set0[4] = { TEST0, TEST1, TEST2, TEST3 };
     186    float32_t test_set1[4] = { FLT_MAX, FLT_MIN, INFINITY, NAN };
     187  
     188    RUN_TEST (test_set0, 128, 32, 4, a, b, c);
     189    RUN_TEST (test_set1, 128, 32, 2, a, b, c);
     190  
     191    /* Since last test cannot be fully checked in a uniform way by
     192       adding negation result to original value, the number of lanes
     193       to be checked in RUN_TEST is 0 (last argument).  Instead, result
     194       will be checked manually.  */
     195  
     196    if (c[2] != -INFINITY)
     197      return 1;
     198  
     199    if (!__builtin_isnan (c[3]))
     200      return 1;
     201  
     202    return 0;
     203  }
     204  
     205  /* { dg-final { scan-assembler-times "fneg\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" 2 } } */
     206  
     207  #undef TEST3
     208  #undef EPSILON
     209  #undef VAR_MIN
     210  #undef VAR_MAX
     211  #undef INFINITY
     212  
     213  #define TEST3 TEST3_DBL
     214  #define EPSILON DBL_EPSILON
     215  #define VAR_MIN DBL_MIN
     216  #define VAR_MAX DBL_MAX
     217  #define INFINITY DBL_INFINITY
     218  
     219  int
     220  test_vnegq_f64 ()
     221  {
     222    float64x2_t a;
     223    float64x2_t b;
     224    float64_t c[2];
     225  
     226    float64_t test_set0[2] = { TEST0, TEST1 };
     227    float64_t test_set1[2] = { TEST2, TEST3 };
     228    float64_t test_set2[2] = { FLT_MAX, FLT_MIN };
     229    float64_t test_set3[2] = { INFINITY, NAN };
     230  
     231    RUN_TEST (test_set0, 128, 64, 2, a, b, c);
     232    RUN_TEST (test_set1, 128, 64, 2, a, b, c);
     233    RUN_TEST (test_set2, 128, 64, 2, a, b, c);
     234    RUN_TEST (test_set3, 128, 64, 0, a, b, c);
     235  
     236    /* Since last test cannot be checked in a uniform way by adding
     237       negation result to original value, the number of lanes to be
     238       checked in RUN_TEST is 0 (last argument).  Instead, result
     239       will be checked manually.  */
     240  
     241    if (c[0] != -INFINITY)
     242      return 1;
     243  
     244    if (!__builtin_isnan (c[1]))
     245      return 1;
     246  
     247    return 0;
     248  }
     249  
     250  /* { dg-final { scan-assembler-times "fneg\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" 4 } } */
     251  
     252  int
     253  main (int argc, char **argv)
     254  {
     255    if (test_vneg_f32 ())
     256      abort ();
     257  
     258    if (test_vneg_f64 ())
     259      abort ();
     260  
     261    if (test_vnegq_f32 ())
     262      abort ();
     263  
     264    if (test_vnegq_f64 ())
     265      abort ();
     266  
     267    return 0;
     268  }
     269