1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature
2 // RUN: %clang_cc1 -no-opaque-pointers -triple arm64-none-linux-gnu -target-feature +neon \
3 // RUN: -disable-O0-optnone -ffp-contract=fast -emit-llvm -o - %s | opt -S -mem2reg \
4 // RUN: | FileCheck %s
5
6 // REQUIRES: aarch64-registered-target
7
8 // Test new aarch64 intrinsics with poly128
9 // FIXME: Currently, poly128_t equals to uint128, which will be spilt into
10 // two 64-bit GPR(eg X0, X1). Now moving data from X0, X1 to FPR128 will
11 // introduce 2 store and 1 load instructions(store X0, X1 to memory and
12 // then load back to Q0). If target has NEON, this is better replaced by
13 // FMOV or INS.
14
15 #include <arm_neon.h>
16
17 // CHECK-LABEL: define {{[^@]+}}@test_vstrq_p128
18 // CHECK-SAME: (i128* noundef [[PTR:%.*]], i128 noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] {
19 // CHECK-NEXT: entry:
20 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128* [[PTR]] to i8*
21 // CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i128*
22 // CHECK-NEXT: store i128 [[VAL]], i128* [[TMP1]], align 16
23 // CHECK-NEXT: ret void
24 //
test_vstrq_p128(poly128_t * ptr,poly128_t val)25 void test_vstrq_p128(poly128_t * ptr, poly128_t val) {
26 vstrq_p128(ptr, val);
27
28 }
29
30 // CHECK-LABEL: define {{[^@]+}}@test_vldrq_p128
31 // CHECK-SAME: (i128* noundef [[PTR:%.*]]) #[[ATTR0]] {
32 // CHECK-NEXT: entry:
33 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128* [[PTR]] to i8*
34 // CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i128*
35 // CHECK-NEXT: [[TMP2:%.*]] = load i128, i128* [[TMP1]], align 16
36 // CHECK-NEXT: ret i128 [[TMP2]]
37 //
test_vldrq_p128(poly128_t * ptr)38 poly128_t test_vldrq_p128(poly128_t * ptr) {
39 return vldrq_p128(ptr);
40
41 }
42
43 // CHECK-LABEL: define {{[^@]+}}@test_ld_st_p128
44 // CHECK-SAME: (i128* noundef [[PTR:%.*]]) #[[ATTR0]] {
45 // CHECK-NEXT: entry:
46 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128* [[PTR]] to i8*
47 // CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i128*
48 // CHECK-NEXT: [[TMP2:%.*]] = load i128, i128* [[TMP1]], align 16
49 // CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i128, i128* [[PTR]], i64 1
50 // CHECK-NEXT: [[TMP3:%.*]] = bitcast i128* [[ADD_PTR]] to i8*
51 // CHECK-NEXT: [[TMP4:%.*]] = bitcast i8* [[TMP3]] to i128*
52 // CHECK-NEXT: store i128 [[TMP2]], i128* [[TMP4]], align 16
53 // CHECK-NEXT: ret void
54 //
test_ld_st_p128(poly128_t * ptr)55 void test_ld_st_p128(poly128_t * ptr) {
56 vstrq_p128(ptr+1, vldrq_p128(ptr));
57
58 }
59
60 // CHECK-LABEL: define {{[^@]+}}@test_vmull_p64
61 // CHECK-SAME: (i64 noundef [[A:%.*]], i64 noundef [[B:%.*]]) #[[ATTR0]] {
62 // CHECK-NEXT: entry:
63 // CHECK-NEXT: [[VMULL_P64_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 [[A]], i64 [[B]])
64 // CHECK-NEXT: [[VMULL_P641_I:%.*]] = bitcast <16 x i8> [[VMULL_P64_I]] to i128
65 // CHECK-NEXT: ret i128 [[VMULL_P641_I]]
66 //
test_vmull_p64(poly64_t a,poly64_t b)67 poly128_t test_vmull_p64(poly64_t a, poly64_t b) {
68 return vmull_p64(a, b);
69 }
70
71 // CHECK-LABEL: define {{[^@]+}}@test_vmull_high_p64
72 // CHECK-SAME: (<2 x i64> noundef [[A:%.*]], <2 x i64> noundef [[B:%.*]]) #[[ATTR1:[0-9]+]] {
73 // CHECK-NEXT: entry:
74 // CHECK-NEXT: [[SHUFFLE_I5:%.*]] = shufflevector <2 x i64> [[A]], <2 x i64> [[A]], <1 x i32> <i32 1>
75 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x i64> [[SHUFFLE_I5]] to i64
76 // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <2 x i64> [[B]], <2 x i64> [[B]], <1 x i32> <i32 1>
77 // CHECK-NEXT: [[TMP1:%.*]] = bitcast <1 x i64> [[SHUFFLE_I]] to i64
78 // CHECK-NEXT: [[VMULL_P64_I_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 [[TMP0]], i64 [[TMP1]])
79 // CHECK-NEXT: [[VMULL_P641_I_I:%.*]] = bitcast <16 x i8> [[VMULL_P64_I_I]] to i128
80 // CHECK-NEXT: ret i128 [[VMULL_P641_I_I]]
81 //
test_vmull_high_p64(poly64x2_t a,poly64x2_t b)82 poly128_t test_vmull_high_p64(poly64x2_t a, poly64x2_t b) {
83 return vmull_high_p64(a, b);
84 }
85
86 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_s8
87 // CHECK-SAME: (<16 x i8> noundef [[A:%.*]]) #[[ATTR1]] {
88 // CHECK-NEXT: entry:
89 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A]] to i128
90 // CHECK-NEXT: ret i128 [[TMP0]]
91 //
test_vreinterpretq_p128_s8(int8x16_t a)92 poly128_t test_vreinterpretq_p128_s8(int8x16_t a) {
93 return vreinterpretq_p128_s8(a);
94 }
95
96 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_s16
97 // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR1]] {
98 // CHECK-NEXT: entry:
99 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to i128
100 // CHECK-NEXT: ret i128 [[TMP0]]
101 //
test_vreinterpretq_p128_s16(int16x8_t a)102 poly128_t test_vreinterpretq_p128_s16(int16x8_t a) {
103 return vreinterpretq_p128_s16(a);
104 }
105
106 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_s32
107 // CHECK-SAME: (<4 x i32> noundef [[A:%.*]]) #[[ATTR1]] {
108 // CHECK-NEXT: entry:
109 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to i128
110 // CHECK-NEXT: ret i128 [[TMP0]]
111 //
test_vreinterpretq_p128_s32(int32x4_t a)112 poly128_t test_vreinterpretq_p128_s32(int32x4_t a) {
113 return vreinterpretq_p128_s32(a);
114 }
115
116 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_s64
117 // CHECK-SAME: (<2 x i64> noundef [[A:%.*]]) #[[ATTR1]] {
118 // CHECK-NEXT: entry:
119 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to i128
120 // CHECK-NEXT: ret i128 [[TMP0]]
121 //
test_vreinterpretq_p128_s64(int64x2_t a)122 poly128_t test_vreinterpretq_p128_s64(int64x2_t a) {
123 return vreinterpretq_p128_s64(a);
124 }
125
126 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_u8
127 // CHECK-SAME: (<16 x i8> noundef [[A:%.*]]) #[[ATTR1]] {
128 // CHECK-NEXT: entry:
129 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A]] to i128
130 // CHECK-NEXT: ret i128 [[TMP0]]
131 //
test_vreinterpretq_p128_u8(uint8x16_t a)132 poly128_t test_vreinterpretq_p128_u8(uint8x16_t a) {
133 return vreinterpretq_p128_u8(a);
134 }
135
136 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_u16
137 // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR1]] {
138 // CHECK-NEXT: entry:
139 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to i128
140 // CHECK-NEXT: ret i128 [[TMP0]]
141 //
test_vreinterpretq_p128_u16(uint16x8_t a)142 poly128_t test_vreinterpretq_p128_u16(uint16x8_t a) {
143 return vreinterpretq_p128_u16(a);
144 }
145
146 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_u32
147 // CHECK-SAME: (<4 x i32> noundef [[A:%.*]]) #[[ATTR1]] {
148 // CHECK-NEXT: entry:
149 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to i128
150 // CHECK-NEXT: ret i128 [[TMP0]]
151 //
test_vreinterpretq_p128_u32(uint32x4_t a)152 poly128_t test_vreinterpretq_p128_u32(uint32x4_t a) {
153 return vreinterpretq_p128_u32(a);
154 }
155
156 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_u64
157 // CHECK-SAME: (<2 x i64> noundef [[A:%.*]]) #[[ATTR1]] {
158 // CHECK-NEXT: entry:
159 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to i128
160 // CHECK-NEXT: ret i128 [[TMP0]]
161 //
test_vreinterpretq_p128_u64(uint64x2_t a)162 poly128_t test_vreinterpretq_p128_u64(uint64x2_t a) {
163 return vreinterpretq_p128_u64(a);
164 }
165
166 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_f32
167 // CHECK-SAME: (<4 x float> noundef [[A:%.*]]) #[[ATTR1]] {
168 // CHECK-NEXT: entry:
169 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to i128
170 // CHECK-NEXT: ret i128 [[TMP0]]
171 //
test_vreinterpretq_p128_f32(float32x4_t a)172 poly128_t test_vreinterpretq_p128_f32(float32x4_t a) {
173 return vreinterpretq_p128_f32(a);
174 }
175
176 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_f64
177 // CHECK-SAME: (<2 x double> noundef [[A:%.*]]) #[[ATTR1]] {
178 // CHECK-NEXT: entry:
179 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[A]] to i128
180 // CHECK-NEXT: ret i128 [[TMP0]]
181 //
test_vreinterpretq_p128_f64(float64x2_t a)182 poly128_t test_vreinterpretq_p128_f64(float64x2_t a) {
183 return vreinterpretq_p128_f64(a);
184 }
185
186 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_p8
187 // CHECK-SAME: (<16 x i8> noundef [[A:%.*]]) #[[ATTR1]] {
188 // CHECK-NEXT: entry:
189 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A]] to i128
190 // CHECK-NEXT: ret i128 [[TMP0]]
191 //
test_vreinterpretq_p128_p8(poly8x16_t a)192 poly128_t test_vreinterpretq_p128_p8(poly8x16_t a) {
193 return vreinterpretq_p128_p8(a);
194 }
195
196 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_p16
197 // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR1]] {
198 // CHECK-NEXT: entry:
199 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to i128
200 // CHECK-NEXT: ret i128 [[TMP0]]
201 //
test_vreinterpretq_p128_p16(poly16x8_t a)202 poly128_t test_vreinterpretq_p128_p16(poly16x8_t a) {
203 return vreinterpretq_p128_p16(a);
204 }
205
206 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_p64
207 // CHECK-SAME: (<2 x i64> noundef [[A:%.*]]) #[[ATTR1]] {
208 // CHECK-NEXT: entry:
209 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to i128
210 // CHECK-NEXT: ret i128 [[TMP0]]
211 //
test_vreinterpretq_p128_p64(poly64x2_t a)212 poly128_t test_vreinterpretq_p128_p64(poly64x2_t a) {
213 return vreinterpretq_p128_p64(a);
214 }
215
216 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_s8_p128
217 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
218 // CHECK-NEXT: entry:
219 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <16 x i8>
220 // CHECK-NEXT: ret <16 x i8> [[TMP0]]
221 //
test_vreinterpretq_s8_p128(poly128_t a)222 int8x16_t test_vreinterpretq_s8_p128(poly128_t a) {
223 return vreinterpretq_s8_p128(a);
224 }
225
226 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_s16_p128
227 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
228 // CHECK-NEXT: entry:
229 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <8 x i16>
230 // CHECK-NEXT: ret <8 x i16> [[TMP0]]
231 //
test_vreinterpretq_s16_p128(poly128_t a)232 int16x8_t test_vreinterpretq_s16_p128(poly128_t a) {
233 return vreinterpretq_s16_p128(a);
234 }
235
236 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_s32_p128
237 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
238 // CHECK-NEXT: entry:
239 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <4 x i32>
240 // CHECK-NEXT: ret <4 x i32> [[TMP0]]
241 //
test_vreinterpretq_s32_p128(poly128_t a)242 int32x4_t test_vreinterpretq_s32_p128(poly128_t a) {
243 return vreinterpretq_s32_p128(a);
244 }
245
246 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_s64_p128
247 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
248 // CHECK-NEXT: entry:
249 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <2 x i64>
250 // CHECK-NEXT: ret <2 x i64> [[TMP0]]
251 //
test_vreinterpretq_s64_p128(poly128_t a)252 int64x2_t test_vreinterpretq_s64_p128(poly128_t a) {
253 return vreinterpretq_s64_p128(a);
254 }
255
256 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_u8_p128
257 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
258 // CHECK-NEXT: entry:
259 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <16 x i8>
260 // CHECK-NEXT: ret <16 x i8> [[TMP0]]
261 //
test_vreinterpretq_u8_p128(poly128_t a)262 uint8x16_t test_vreinterpretq_u8_p128(poly128_t a) {
263 return vreinterpretq_u8_p128(a);
264 }
265
266 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_u16_p128
267 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
268 // CHECK-NEXT: entry:
269 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <8 x i16>
270 // CHECK-NEXT: ret <8 x i16> [[TMP0]]
271 //
test_vreinterpretq_u16_p128(poly128_t a)272 uint16x8_t test_vreinterpretq_u16_p128(poly128_t a) {
273 return vreinterpretq_u16_p128(a);
274 }
275
276 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_u32_p128
277 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
278 // CHECK-NEXT: entry:
279 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <4 x i32>
280 // CHECK-NEXT: ret <4 x i32> [[TMP0]]
281 //
test_vreinterpretq_u32_p128(poly128_t a)282 uint32x4_t test_vreinterpretq_u32_p128(poly128_t a) {
283 return vreinterpretq_u32_p128(a);
284 }
285
286 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_u64_p128
287 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
288 // CHECK-NEXT: entry:
289 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <2 x i64>
290 // CHECK-NEXT: ret <2 x i64> [[TMP0]]
291 //
test_vreinterpretq_u64_p128(poly128_t a)292 uint64x2_t test_vreinterpretq_u64_p128(poly128_t a) {
293 return vreinterpretq_u64_p128(a);
294 }
295
296 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_f32_p128
297 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
298 // CHECK-NEXT: entry:
299 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <4 x float>
300 // CHECK-NEXT: ret <4 x float> [[TMP0]]
301 //
test_vreinterpretq_f32_p128(poly128_t a)302 float32x4_t test_vreinterpretq_f32_p128(poly128_t a) {
303 return vreinterpretq_f32_p128(a);
304 }
305
306 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_f64_p128
307 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
308 // CHECK-NEXT: entry:
309 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <2 x double>
310 // CHECK-NEXT: ret <2 x double> [[TMP0]]
311 //
test_vreinterpretq_f64_p128(poly128_t a)312 float64x2_t test_vreinterpretq_f64_p128(poly128_t a) {
313 return vreinterpretq_f64_p128(a);
314 }
315
316 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p8_p128
317 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
318 // CHECK-NEXT: entry:
319 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <16 x i8>
320 // CHECK-NEXT: ret <16 x i8> [[TMP0]]
321 //
test_vreinterpretq_p8_p128(poly128_t a)322 poly8x16_t test_vreinterpretq_p8_p128(poly128_t a) {
323 return vreinterpretq_p8_p128(a);
324 }
325
326 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p16_p128
327 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
328 // CHECK-NEXT: entry:
329 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <8 x i16>
330 // CHECK-NEXT: ret <8 x i16> [[TMP0]]
331 //
test_vreinterpretq_p16_p128(poly128_t a)332 poly16x8_t test_vreinterpretq_p16_p128(poly128_t a) {
333 return vreinterpretq_p16_p128(a);
334 }
335
336 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p64_p128
337 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] {
338 // CHECK-NEXT: entry:
339 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <2 x i64>
340 // CHECK-NEXT: ret <2 x i64> [[TMP0]]
341 //
test_vreinterpretq_p64_p128(poly128_t a)342 poly64x2_t test_vreinterpretq_p64_p128(poly128_t a) {
343 return vreinterpretq_p64_p128(a);
344 }
345
346
347