(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
aarch64/
vneg_s.c
       1  /* Test vneg works correctly.  */
       2  /* { dg-do run } */
       3  /* { dg-options "-std=gnu99 -O3 -Wno-div-by-zero --save-temps" } */
       4  
       5  #include <arm_neon.h>
       6  #include <limits.h>
       7  
       8  /* Used to force a variable to a SIMD register.  Also acts as a stronger
       9     inhibitor of optimization than the below - necessary for int64x1_t
      10     because more of the implementation is in terms of gcc vector extensions
      11     (which support constant propagation) than for other types.  */
      12  #define force_simd(V1)   asm volatile ("mov %d0, %1.d[0]"	\
      13  	   : "=w"(V1)						\
      14  	   : "w"(V1)						\
      15  	   : /* No clobbers */);
      16  #define INHIB_OPTIMIZATION asm volatile ("" : : : "memory")
      17  
      18  #define TEST0 0
      19  #define TEST1 1
      20  #define TEST2 -1
      21  #define TEST3 10
      22  #define TEST4 -10
      23  #define TEST5 0
      24  
      25  #define ANSW0 0
      26  #define ANSW1 -1
      27  #define ANSW2 1
      28  #define ANSW3 -10
      29  #define ANSW4 10
      30  #define ANSW5 0
      31  
      32  extern void abort (void);
      33  
      34  #define BUILD_TEST(type, size, lanes)			   \
      35  int __attribute__((noipa,noinline))			   \
      36  run_test##type##size##x##lanes (int##size##_t* test_set,   \
      37  		       int##size##_t* answ_set,		   \
      38  		       int reg_len, int data_len, int n)   \
      39  {							   \
      40    int i;						   \
      41    int##size##x##lanes##_t a = vld1##type##size (test_set); \
      42    int##size##x##lanes##_t b = vld1##type##size (answ_set); \
      43    a = vneg##type##size (a);				   \
      44    for (i = 0; i < n; i++)				   \
      45    {				    \
      46      INHIB_OPTIMIZATION;		    \
      47      if (a[i] != b[i])		    \
      48      return 1;			    \
      49    }				    \
      50    return 0;			    \
      51  }				    \
      52  
      53  #define RUN_TEST_SCALAR(test_val, answ_val, a, b)     \
      54    {                                                   \
      55      int64_t res;                                      \
      56      INHIB_OPTIMIZATION;                               \
      57      a = test_val;                                     \
      58      b = answ_val;                                     \
      59      force_simd (b);                                   \
      60      force_simd (a);                                   \
      61      res = vnegd_s64 (a);                              \
      62      force_simd (res);                                 \
      63    }
      64  
      65  BUILD_TEST (_s, 8, 8)
      66  BUILD_TEST (_s, 16, 4)
      67  BUILD_TEST (_s, 32, 2)
      68  BUILD_TEST (_s, 64, 1)
      69  
      70  BUILD_TEST (q_s, 8, 16)
      71  BUILD_TEST (q_s, 16, 8)
      72  BUILD_TEST (q_s, 32, 4)
      73  BUILD_TEST (q_s, 64, 2)
      74  
      75  int __attribute__ ((noinline))
      76  test_vneg_s8 ()
      77  {
      78    int8_t test_set0[8] = {
      79      TEST0, TEST1, TEST2, TEST3, TEST4, TEST5, SCHAR_MAX, SCHAR_MIN
      80    };
      81    int8_t answ_set0[8] = {
      82      ANSW0, ANSW1, ANSW2, ANSW3, ANSW4, ANSW5, SCHAR_MIN + 1, SCHAR_MIN
      83    };
      84  
      85    int o1 = run_test_s8x8 (test_set0, answ_set0, 64, 8, 8);
      86  
      87    return o1;
      88  }
      89  
      90  /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.8b, v\[0-9\]+\.8b" 1 } } */
      91  
      92  int __attribute__ ((noinline))
      93  test_vneg_s16 ()
      94  {
      95    int16_t test_set0[4] = { TEST0, TEST1, TEST2, TEST3 };
      96    int16_t test_set1[4] = { TEST4, TEST5, SHRT_MAX, SHRT_MIN };
      97  
      98    int16_t answ_set0[4] = { ANSW0, ANSW1, ANSW2, ANSW3 };
      99    int16_t answ_set1[4] = { ANSW4, ANSW5, SHRT_MIN + 1, SHRT_MIN };
     100  
     101    int o1 = run_test_s16x4 (test_set0, answ_set0, 64, 16, 4);
     102    int o2 = run_test_s16x4 (test_set1, answ_set1, 64, 16, 4);
     103  
     104    return o1||o2;
     105  }
     106  
     107  /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.4h, v\[0-9\]+\.4h" 1 } } */
     108  
     109  int __attribute__ ((noinline))
     110  test_vneg_s32 ()
     111  {
     112    int32_t test_set0[2] = { TEST0, TEST1 };
     113    int32_t test_set1[2] = { TEST2, TEST3 };
     114    int32_t test_set2[2] = { TEST4, TEST5 };
     115    int32_t test_set3[2] = { INT_MAX, INT_MIN };
     116  
     117    int32_t answ_set0[2] = { ANSW0, ANSW1 };
     118    int32_t answ_set1[2] = { ANSW2, ANSW3 };
     119    int32_t answ_set2[2] = { ANSW4, ANSW5 };
     120    int32_t answ_set3[2] = { INT_MIN + 1, INT_MIN };
     121  
     122    int o1 = run_test_s32x2 (test_set0, answ_set0, 64, 32, 2);
     123    int o2 = run_test_s32x2 (test_set1, answ_set1, 64, 32, 2);
     124    int o3 = run_test_s32x2 (test_set2, answ_set2, 64, 32, 2);
     125    int o4 = run_test_s32x2 (test_set3, answ_set3, 64, 32, 2);
     126  
     127    return o1||o2||o3||o4;
     128  }
     129  
     130  /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" 1 } } */
     131  
     132  int __attribute__ ((noinline))
     133  test_vneg_s64 ()
     134  {
     135    int64_t test_set0[1] = { TEST0 };
     136    int64_t test_set1[1] = { TEST1 };
     137    int64_t test_set2[1] = { TEST2 };
     138    int64_t test_set3[1] = { TEST3 };
     139    int64_t test_set4[1] = { TEST4 };
     140    int64_t test_set5[1] = { TEST5 };
     141    int64_t test_set6[1] = { LLONG_MAX };
     142    int64_t test_set7[1] = { LLONG_MIN };
     143  
     144    int64_t answ_set0[1] = { ANSW0 };
     145    int64_t answ_set1[1] = { ANSW1 };
     146    int64_t answ_set2[1] = { ANSW2 };
     147    int64_t answ_set3[1] = { ANSW3 };
     148    int64_t answ_set4[1] = { ANSW4 };
     149    int64_t answ_set5[1] = { ANSW5 };
     150    int64_t answ_set6[1] = { LLONG_MIN + 1 };
     151    int64_t answ_set7[1] = { LLONG_MIN };
     152  
     153    int o1 = run_test_s64x1 (test_set0, answ_set0, 64, 64, 1);
     154    int o2 = run_test_s64x1  (test_set1, answ_set1, 64, 64, 1);
     155    int o3 = run_test_s64x1 (test_set2, answ_set2, 64, 64, 1);
     156    int o4 = run_test_s64x1 (test_set3, answ_set3, 64, 64, 1);
     157    int o5 = run_test_s64x1 (test_set4, answ_set4, 64, 64, 1);
     158    int o6 = run_test_s64x1 (test_set5, answ_set5, 64, 64, 1);
     159    int o7 = run_test_s64x1 (test_set6, answ_set6, 64, 64, 1);
     160    int o8 = run_test_s64x1 (test_set7, answ_set7, 64, 64, 1);
     161  
     162    return o1||o2||o3||o4||o5||o6||o7||o8;
     163  }
     164  
     165  int __attribute__ ((noinline))
     166  test_vnegd_s64 ()
     167  {
     168    int64_t a, b;
     169  
     170    RUN_TEST_SCALAR (TEST0, ANSW0, a, b);
     171    RUN_TEST_SCALAR (TEST1, ANSW1, a, b);
     172    RUN_TEST_SCALAR (TEST2, ANSW2, a, b);
     173    RUN_TEST_SCALAR (TEST3, ANSW3, a, b);
     174    RUN_TEST_SCALAR (TEST4, ANSW4, a, b);
     175    RUN_TEST_SCALAR (TEST5, ANSW5, a, b);
     176    RUN_TEST_SCALAR (LLONG_MAX, LLONG_MIN + 1, a, b);
     177    RUN_TEST_SCALAR (LLONG_MIN, LLONG_MIN, a, b);
     178  
     179    return 0;
     180  }
     181  
     182  /* { dg-final { scan-assembler-times "neg\\td\[0-9\]+, d\[0-9\]+" 8 } } */
     183  
     184  int __attribute__ ((noinline))
     185  test_vnegq_s8 ()
     186  {
     187    int8_t test_set0[16] = {
     188      TEST0, TEST1, TEST2, TEST3, TEST4, TEST5, SCHAR_MAX, SCHAR_MIN,
     189      4, 8, 15, 16, 23, 42, -1, -2
     190    };
     191  
     192    int8_t answ_set0[16] = {
     193      ANSW0, ANSW1, ANSW2, ANSW3, ANSW4, ANSW5, SCHAR_MIN + 1, SCHAR_MIN,
     194      -4, -8, -15, -16, -23, -42, 1, 2
     195    };
     196  
     197    int o1 = run_testq_s8x16 (test_set0, answ_set0, 128, 8, 8);
     198  
     199    return o1;
     200  }
     201  
     202  /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b" 1 } } */
     203  
     204  int __attribute__ ((noinline))
     205  test_vnegq_s16 ()
     206  {
     207    int16_t test_set0[8] = {
     208      TEST0, TEST1, TEST2, TEST3, TEST4, TEST5, SHRT_MAX, SHRT_MIN
     209    };
     210    int16_t answ_set0[8] = {
     211      ANSW0, ANSW1, ANSW2, ANSW3, ANSW4, ANSW5, SHRT_MIN + 1, SHRT_MIN
     212    };
     213  
     214    int o1 = run_testq_s16x8 (test_set0, answ_set0, 128, 16, 8);
     215  
     216    return o1;
     217  }
     218  
     219  /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h" 1 } } */
     220  
     221  int __attribute__ ((noinline))
     222  test_vnegq_s32 ()
     223  {
     224    int32_t test_set0[4] = { TEST0, TEST1, TEST2, TEST3 };
     225    int32_t test_set1[4] = { TEST4, TEST5, INT_MAX, INT_MIN };
     226  
     227    int32_t answ_set0[4] = { ANSW0, ANSW1, ANSW2, ANSW3 };
     228    int32_t answ_set1[4] = { ANSW4, ANSW5, INT_MIN + 1, INT_MIN };
     229  
     230    int o1 = run_testq_s32x4 (test_set0, answ_set0, 128, 32, 4);
     231    int o2 = run_testq_s32x4 (test_set1, answ_set1, 128, 32, 4);
     232  
     233    return o1||o2;
     234  }
     235  
     236  /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" 1 } } */
     237  
     238  int __attribute__ ((noinline))
     239  test_vnegq_s64 ()
     240  {
     241    int64_t test_set0[2] = { TEST0, TEST1 };
     242    int64_t test_set1[2] = { TEST2, TEST3 };
     243    int64_t test_set2[2] = { TEST4, TEST5 };
     244    int64_t test_set3[2] = { LLONG_MAX, LLONG_MIN };
     245  
     246    int64_t answ_set0[2] = { ANSW0, ANSW1 };
     247    int64_t answ_set1[2] = { ANSW2, ANSW3 };
     248    int64_t answ_set2[2] = { ANSW4, ANSW5 };
     249    int64_t answ_set3[2] = { LLONG_MIN + 1, LLONG_MIN };
     250  
     251    int o1 = run_testq_s64x2 (test_set0, answ_set0, 128, 64, 2);
     252    int o2 = run_testq_s64x2 (test_set1, answ_set1, 128, 64, 2);
     253    int o3 = run_testq_s64x2 (test_set2, answ_set2, 128, 64, 2);
     254    int o4 = run_testq_s64x2 (test_set3, answ_set3, 128, 64, 2);
     255  
     256    return o1||o2||o2||o4;
     257  }
     258  
     259  /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" 1 } } */
     260  
     261  int
     262  main (int argc, char **argv)
     263  {
     264    if (test_vneg_s8 ())
     265      abort ();
     266  
     267    if (test_vneg_s16 ())
     268      abort ();
     269  
     270    if (test_vneg_s32 ())
     271      abort ();
     272  
     273    if (test_vneg_s64 ())
     274      abort ();
     275  
     276    if (test_vnegd_s64 ())
     277      abort ();
     278  
     279    if (test_vnegq_s8 ())
     280      abort ();
     281  
     282    if (test_vnegq_s16 ())
     283      abort ();
     284  
     285    if (test_vnegq_s32 ())
     286      abort ();
     287  
     288    if (test_vnegq_s64 ())
     289      abort ();
     290  
     291    return 0;
     292  }
     293