a49db3e963db5309c5dafc25a029ef7c557aaf3f
[gcc.git] / gcc / testsuite / gcc.target / aarch64 / vdup_lane_2.c
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))
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))
21 wrap_vdups_lane_f32_1 (float32x2_t a)
22 {
23 return vdups_lane_f32 (a, 1);
24 }
25
26 int __attribute__ ((noinline))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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
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