1 /* Test vdup_lane intrinsics work correctly.  */
2 /* { dg-do run } */
3 /* { dg-options "-O1 --save-temps" } */
4 
5 #include <arm_neon.h>
6 
7 #define force_simd(V1) asm volatile ("mov %d0, %1.d[0]" \
8          : "=w"(V1)                                     \
9          : "w"(V1)                                      \
10          : /* No clobbers */)
11 
12 extern void abort (void);
13 
14 float32_t __attribute__ ((noinline))
wrap_vdups_lane_f32_0(float32x2_t dummy,float32x2_t a)15 wrap_vdups_lane_f32_0 (float32x2_t dummy, float32x2_t a)
16 {
17   return vdups_lane_f32 (a, 0);
18 }
19 
20 float32_t __attribute__ ((noinline))
wrap_vdups_lane_f32_1(float32x2_t a)21 wrap_vdups_lane_f32_1 (float32x2_t a)
22 {
23   return vdups_lane_f32 (a, 1);
24 }
25 
26 int __attribute__ ((noinline))
test_vdups_lane_f32()27 test_vdups_lane_f32 ()
28 {
29   float32x2_t a;
30   float32_t b;
31   float32_t c[2] = { 0.0, 1.0 };
32 
33   a = vld1_f32 (c);
34   b = wrap_vdups_lane_f32_0 (a, a);
35   if (c[0] != b)
36     return 1;
37   b = wrap_vdups_lane_f32_1 (a);
38   if (c[1] != b)
39     return 1;
40   return 0;
41 }
42 
43 float64_t __attribute__ ((noinline))
wrap_vdupd_lane_f64_0(float64x1_t dummy,float64x1_t a)44 wrap_vdupd_lane_f64_0 (float64x1_t dummy, float64x1_t a)
45 {
46   return vdupd_lane_f64 (a, 0);
47 }
48 
49 int __attribute__ ((noinline))
test_vdupd_lane_f64()50 test_vdupd_lane_f64 ()
51 {
52   float64x1_t a;
53   float64_t b;
54   float64_t c[1] = { 0.0 };
55   a = vld1_f64 (c);
56   b = wrap_vdupd_lane_f64_0 (a, a);
57   if (c[0] != b)
58     return 1;
59   return 0;
60 }
61 
62 int8_t __attribute__ ((noinline))
wrap_vdupb_lane_s8_0(int8x8_t dummy,int8x8_t a)63 wrap_vdupb_lane_s8_0 (int8x8_t dummy, int8x8_t a)
64 {
65   int8_t result = vdupb_lane_s8 (a, 0);
66   force_simd (result);
67   return result;
68 }
69 
70 int8_t __attribute__ ((noinline))
wrap_vdupb_lane_s8_1(int8x8_t a)71 wrap_vdupb_lane_s8_1 (int8x8_t a)
72 {
73   int8_t result = vdupb_lane_s8 (a, 1);
74   force_simd (result);
75   return result;
76 }
77 
78 int __attribute__ ((noinline))
test_vdupb_lane_s8()79 test_vdupb_lane_s8 ()
80 {
81   int8x8_t a;
82   int8_t b;
83   int8_t c[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
84 
85   a = vld1_s8 (c);
86   b = wrap_vdupb_lane_s8_0 (a, a);
87   if (c[0] != b)
88     return 1;
89   b = wrap_vdupb_lane_s8_1 (a);
90   if (c[1] != b)
91     return 1;
92 
93   return 0;
94 }
95 
96 uint8_t __attribute__ ((noinline))
wrap_vdupb_lane_u8_0(uint8x8_t dummy,uint8x8_t a)97 wrap_vdupb_lane_u8_0 (uint8x8_t dummy, uint8x8_t a)
98 {
99   uint8_t result = vdupb_lane_u8 (a, 0);
100   force_simd (result);
101   return result;
102 }
103 
104 uint8_t __attribute__ ((noinline))
wrap_vdupb_lane_u8_1(uint8x8_t a)105 wrap_vdupb_lane_u8_1 (uint8x8_t a)
106 {
107   uint8_t result = vdupb_lane_u8 (a, 1);
108   force_simd (result);
109   return result;
110 }
111 
112 int __attribute__ ((noinline))
test_vdupb_lane_u8()113 test_vdupb_lane_u8 ()
114 {
115   uint8x8_t a;
116   uint8_t b;
117   uint8_t c[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
118 
119   a = vld1_u8 (c);
120   b = wrap_vdupb_lane_u8_0 (a, a);
121   if (c[0] != b)
122     return 1;
123   b = wrap_vdupb_lane_u8_1 (a);
124   if (c[1] != b)
125     return 1;
126   return 0;
127 }
128 
129 int16_t __attribute__ ((noinline))
wrap_vduph_lane_s16_0(int16x4_t dummy,int16x4_t a)130 wrap_vduph_lane_s16_0 (int16x4_t dummy, int16x4_t a)
131 {
132   int16_t result = vduph_lane_s16 (a, 0);
133   force_simd (result);
134   return result;
135 }
136 
137 int16_t __attribute__ ((noinline))
wrap_vduph_lane_s16_1(int16x4_t a)138 wrap_vduph_lane_s16_1 (int16x4_t a)
139 {
140   int16_t result = vduph_lane_s16 (a, 1);
141   force_simd (result);
142   return result;
143 }
144 
145 int __attribute__ ((noinline))
test_vduph_lane_s16()146 test_vduph_lane_s16 ()
147 {
148   int16x4_t a;
149   int16_t b;
150   int16_t c[4] = { 0, 1, 2, 3 };
151 
152   a = vld1_s16 (c);
153   b = wrap_vduph_lane_s16_0 (a, a);
154   if (c[0] != b)
155     return 1;
156   b = wrap_vduph_lane_s16_1 (a);
157   if (c[1] != b)
158     return 1;
159   return 0;
160 }
161 
162 uint16_t __attribute__ ((noinline))
wrap_vduph_lane_u16_0(uint16x4_t dummy,uint16x4_t a)163 wrap_vduph_lane_u16_0 (uint16x4_t dummy, uint16x4_t a)
164 {
165   uint16_t result = vduph_lane_u16 (a, 0);
166   force_simd (result);
167   return result;
168 }
169 
170 uint16_t __attribute__ ((noinline))
wrap_vduph_lane_u16_1(uint16x4_t a)171 wrap_vduph_lane_u16_1 (uint16x4_t a)
172 {
173   uint16_t result = vduph_lane_u16 (a, 1);
174   force_simd (result);
175   return result;
176 }
177 
178 int __attribute__ ((noinline))
test_vduph_lane_u16()179 test_vduph_lane_u16 ()
180 {
181   uint16x4_t a;
182   uint16_t b;
183   uint16_t c[4] = { 0, 1, 2, 3 };
184 
185   a = vld1_u16 (c);
186   b = wrap_vduph_lane_u16_0 (a, a);
187   if (c[0] != b)
188     return 1;
189   b = wrap_vduph_lane_u16_1 (a);
190   if (c[1] != b)
191     return 1;
192   return 0;
193 }
194 
195 int32_t __attribute__ ((noinline))
wrap_vdups_lane_s32_0(int32x2_t dummy,int32x2_t a)196 wrap_vdups_lane_s32_0 (int32x2_t dummy, int32x2_t a)
197 {
198   int32_t result = vdups_lane_s32 (a, 0);
199   force_simd (result);
200   return result;
201 }
202 
203 int32_t __attribute__ ((noinline))
wrap_vdups_lane_s32_1(int32x2_t a)204 wrap_vdups_lane_s32_1 (int32x2_t a)
205 {
206   int32_t result = vdups_lane_s32 (a, 1);
207   force_simd (result);
208   return result;
209 }
210 
211 int __attribute__ ((noinline))
test_vdups_lane_s32()212 test_vdups_lane_s32 ()
213 {
214   int32x2_t a;
215   int32_t b;
216   int32_t c[2] = { 0, 1 };
217 
218   a = vld1_s32 (c);
219   b = wrap_vdups_lane_s32_0 (vcreate_s32 (0), a);
220   if (c[0] != b)
221     return 1;
222   b = wrap_vdups_lane_s32_1 (a);
223   if (c[1] != b)
224     return 1;
225   return 0;
226 }
227 
228 uint32_t __attribute__ ((noinline))
wrap_vdups_lane_u32_0(uint32x2_t dummy,uint32x2_t a)229 wrap_vdups_lane_u32_0 (uint32x2_t dummy, uint32x2_t a)
230 {
231   uint32_t result = vdups_lane_u32 (a, 0);
232   force_simd (result);
233   return result;
234 }
235 
236 uint32_t __attribute__ ((noinline))
wrap_vdups_lane_u32_1(uint32x2_t a)237 wrap_vdups_lane_u32_1 (uint32x2_t a)
238 {
239   uint32_t result = vdups_lane_u32 (a, 1);
240   force_simd (result);
241   return result;
242 }
243 
244 int __attribute__ ((noinline))
test_vdups_lane_u32()245 test_vdups_lane_u32 ()
246 {
247   uint32x2_t a;
248   uint32_t b;
249   uint32_t c[2] = { 0, 1 };
250   a = vld1_u32 (c);
251   b = wrap_vdups_lane_u32_0 (a, a);
252   if (c[0] != b)
253     return 1;
254   b = wrap_vdups_lane_u32_1 (a);
255   if (c[1] != b)
256     return 1;
257   return 0;
258 }
259 
260 uint64_t __attribute__ ((noinline))
wrap_vdupd_lane_u64_0(uint64x1_t dummy,uint64x1_t a)261 wrap_vdupd_lane_u64_0 (uint64x1_t dummy, uint64x1_t a)
262 {
263   return vdupd_lane_u64 (a, 0);;
264 }
265 
266 int __attribute__ ((noinline))
test_vdupd_lane_u64()267 test_vdupd_lane_u64 ()
268 {
269   uint64x1_t a;
270   uint64_t b;
271   uint64_t c[1] = { 0 };
272 
273   a = vld1_u64 (c);
274   b = wrap_vdupd_lane_u64_0 (a, a);
275   if (c[0] != b)
276     return 1;
277   return 0;
278 }
279 
280 int64_t __attribute__ ((noinline))
wrap_vdupd_lane_s64_0(int64x1_t dummy,int64x1_t a)281 wrap_vdupd_lane_s64_0 (int64x1_t dummy, int64x1_t a)
282 {
283   return vdupd_lane_s64 (a, 0);
284 }
285 
286 int __attribute__ ((noinline))
test_vdupd_lane_s64()287 test_vdupd_lane_s64 ()
288 {
289   int64x1_t a;
290   int64_t b;
291   int64_t c[1] = { 0 };
292 
293   a = vld1_s64 (c);
294   b = wrap_vdupd_lane_s64_0 (a, a);
295   if (c[0] != b)
296     return 1;
297   return 0;
298 }
299 
300 int
main()301 main ()
302 {
303   if (test_vdups_lane_f32 ())
304     abort ();
305   if (test_vdupd_lane_f64 ())
306     abort ();
307   if (test_vdupb_lane_s8 ())
308     abort ();
309   if (test_vdupb_lane_u8 ())
310     abort ();
311   if (test_vduph_lane_s16 ())
312     abort ();
313   if (test_vduph_lane_u16 ())
314     abort ();
315   if (test_vdups_lane_s32 ())
316     abort ();
317   if (test_vdups_lane_u32 ())
318     abort ();
319   if (test_vdupd_lane_s64 ())
320     abort ();
321   if (test_vdupd_lane_u64 ())
322     abort ();
323   return 0;
324 }
325 
326 /* Asm check for vdupb_lane_s8, vdupb_lane_u8.  */
327 /* { dg-final { scan-assembler-not "dup\\tb\[0-9\]+, v\[0-9\]+\.b\\\[0\\\]" } } */
328 /* { dg-final { scan-assembler-times "dup\\tb\[0-9\]+, v\[0-9\]+\.b\\\[1\\\]" 2 } } */
329 
330 /* Asm check for vduph_lane_h16, vduph_lane_h16.  */
331 /* { dg-final { scan-assembler-not "dup\\th\[0-9\]+, v\[0-9\]+\.h\\\[0\\\]" } } */
332 /* { dg-final { scan-assembler-times "dup\\th\[0-9\]+, v\[0-9\]+\.h\\\[1\\\]" 2 } } */
333 
334 /* Asm check for vdups_lane_f32, vdups_lane_s32, vdups_lane_u32.  */
335 /* Can't generate "dup s<n>, v<m>[0]" for vdups_lane_s32 and vdups_lane_u32.  */
336 /* { dg-final { scan-assembler-times "dup\\ts\[0-9\]+, v\[0-9\]+\.s\\\[0\\\]" 1} } */
337 /* { dg-final { scan-assembler-times "dup\\ts\[0-9\]+, v\[0-9\]+\.s\\\[1\\\]" 3 } } */
338 
339 /* Asm check for vdupd_lane_f64, vdupd_lane_s64, vdupd_lane_u64.  */
340 /* Attempts to make the compiler generate vdupd are not practical.  */
341 /* { dg-final { scan-assembler-not "dup\\td\[0-9\]+, v\[0-9\]+\.d\\\[0\\\]" } } */
342 
343