tree-optimization/116791 - Elementwise SLP vectorization
[official-gcc.git] / gcc / testsuite / gcc.target / aarch64 / vneg_s.c
blob8ddc4d21c1f89d6c66624a33ee0386cb3a28c512
1 /* Test vneg works correctly. */
2 /* { dg-do run } */
3 /* { dg-options "-std=gnu99 -O3 -Wno-div-by-zero --save-temps" } */
5 #include <arm_neon.h>
6 #include <limits.h>
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")
18 #define TEST0 0
19 #define TEST1 1
20 #define TEST2 -1
21 #define TEST3 10
22 #define TEST4 -10
23 #define TEST5 0
25 #define ANSW0 0
26 #define ANSW1 -1
27 #define ANSW2 1
28 #define ANSW3 -10
29 #define ANSW4 10
30 #define ANSW5 0
32 extern void abort (void);
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 } \
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); \
65 BUILD_TEST (_s, 8, 8)
66 BUILD_TEST (_s, 16, 4)
67 BUILD_TEST (_s, 32, 2)
68 BUILD_TEST (_s, 64, 1)
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)
75 int __attribute__ ((noinline))
76 test_vneg_s8 ()
78 int8_t test_set0[8] = {
79 TEST0, TEST1, TEST2, TEST3, TEST4, TEST5, SCHAR_MAX, SCHAR_MIN
81 int8_t answ_set0[8] = {
82 ANSW0, ANSW1, ANSW2, ANSW3, ANSW4, ANSW5, SCHAR_MIN + 1, SCHAR_MIN
85 int o1 = run_test_s8x8 (test_set0, answ_set0, 64, 8, 8);
87 return o1;
90 /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.8b, v\[0-9\]+\.8b" 1 } } */
92 int __attribute__ ((noinline))
93 test_vneg_s16 ()
95 int16_t test_set0[4] = { TEST0, TEST1, TEST2, TEST3 };
96 int16_t test_set1[4] = { TEST4, TEST5, SHRT_MAX, SHRT_MIN };
98 int16_t answ_set0[4] = { ANSW0, ANSW1, ANSW2, ANSW3 };
99 int16_t answ_set1[4] = { ANSW4, ANSW5, SHRT_MIN + 1, SHRT_MIN };
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);
104 return o1||o2;
107 /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.4h, v\[0-9\]+\.4h" 1 } } */
109 int __attribute__ ((noinline))
110 test_vneg_s32 ()
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 };
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 };
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);
127 return o1||o2||o3||o4;
130 /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" 1 } } */
132 int __attribute__ ((noinline))
133 test_vneg_s64 ()
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 };
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 };
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);
162 return o1||o2||o3||o4||o5||o6||o7||o8;
165 int __attribute__ ((noinline))
166 test_vnegd_s64 ()
168 int64_t a, b;
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);
179 return 0;
182 /* { dg-final { scan-assembler-times "neg\\td\[0-9\]+, d\[0-9\]+" 8 } } */
184 int __attribute__ ((noinline))
185 test_vnegq_s8 ()
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
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
197 int o1 = run_testq_s8x16 (test_set0, answ_set0, 128, 8, 8);
199 return o1;
202 /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.16b, v\[0-9\]+\.16b" 1 } } */
204 int __attribute__ ((noinline))
205 test_vnegq_s16 ()
207 int16_t test_set0[8] = {
208 TEST0, TEST1, TEST2, TEST3, TEST4, TEST5, SHRT_MAX, SHRT_MIN
210 int16_t answ_set0[8] = {
211 ANSW0, ANSW1, ANSW2, ANSW3, ANSW4, ANSW5, SHRT_MIN + 1, SHRT_MIN
214 int o1 = run_testq_s16x8 (test_set0, answ_set0, 128, 16, 8);
216 return o1;
219 /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h" 1 } } */
221 int __attribute__ ((noinline))
222 test_vnegq_s32 ()
224 int32_t test_set0[4] = { TEST0, TEST1, TEST2, TEST3 };
225 int32_t test_set1[4] = { TEST4, TEST5, INT_MAX, INT_MIN };
227 int32_t answ_set0[4] = { ANSW0, ANSW1, ANSW2, ANSW3 };
228 int32_t answ_set1[4] = { ANSW4, ANSW5, INT_MIN + 1, INT_MIN };
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);
233 return o1||o2;
236 /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" 1 } } */
238 int __attribute__ ((noinline))
239 test_vnegq_s64 ()
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 };
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 };
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);
256 return o1||o2||o2||o4;
259 /* { dg-final { scan-assembler-times "neg\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" 1 } } */
262 main (int argc, char **argv)
264 if (test_vneg_s8 ())
265 abort ();
267 if (test_vneg_s16 ())
268 abort ();
270 if (test_vneg_s32 ())
271 abort ();
273 if (test_vneg_s64 ())
274 abort ();
276 if (test_vnegd_s64 ())
277 abort ();
279 if (test_vnegq_s8 ())
280 abort ();
282 if (test_vnegq_s16 ())
283 abort ();
285 if (test_vnegq_s32 ())
286 abort ();
288 if (test_vnegq_s64 ())
289 abort ();
291 return 0;