1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature
2 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
3 // RUN: -disable-O0-optnone -ffp-contract=fast -emit-llvm -o - %s | opt -S -passes=mem2reg \
6 // REQUIRES: aarch64-registered-target
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
17 // CHECK-LABEL: define {{[^@]+}}@test_vstrq_p128
18 // CHECK-SAME: (ptr noundef [[PTR:%.*]], i128 noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] {
20 // CHECK-NEXT: store i128 [[VAL]], ptr [[PTR]], align 16
21 // CHECK-NEXT: ret void
23 void test_vstrq_p128(poly128_t
* ptr
, poly128_t val
) {
28 // CHECK-LABEL: define {{[^@]+}}@test_vldrq_p128
29 // CHECK-SAME: (ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
31 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr [[PTR]], align 16
32 // CHECK-NEXT: ret i128 [[TMP0]]
34 poly128_t
test_vldrq_p128(poly128_t
* ptr
) {
35 return vldrq_p128(ptr
);
39 // CHECK-LABEL: define {{[^@]+}}@test_ld_st_p128
40 // CHECK-SAME: (ptr noundef [[PTR:%.*]]) #[[ATTR0]] {
42 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr [[PTR]], align 16
43 // CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i128, ptr [[PTR]], i64 1
44 // CHECK-NEXT: store i128 [[TMP0]], ptr [[ADD_PTR]], align 16
45 // CHECK-NEXT: ret void
47 void test_ld_st_p128(poly128_t
* ptr
) {
48 vstrq_p128(ptr
+1, vldrq_p128(ptr
));
52 // CHECK-LABEL: define {{[^@]+}}@test_vmull_p64
53 // CHECK-SAME: (i64 noundef [[A:%.*]], i64 noundef [[B:%.*]]) #[[ATTR1:[0-9]+]] {
55 // CHECK-NEXT: [[VMULL_P64_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 [[A]], i64 [[B]])
56 // CHECK-NEXT: [[VMULL_P641_I:%.*]] = bitcast <16 x i8> [[VMULL_P64_I]] to i128
57 // CHECK-NEXT: ret i128 [[VMULL_P641_I]]
59 __attribute__((target("aes"))) poly128_t
test_vmull_p64(poly64_t a
, poly64_t b
) {
60 return vmull_p64(a
, b
);
63 // CHECK-LABEL: define {{[^@]+}}@test_vmull_high_p64
64 // CHECK-SAME: (<2 x i64> noundef [[A:%.*]], <2 x i64> noundef [[B:%.*]]) #[[ATTR2:[0-9]+]] {
66 // CHECK-NEXT: [[SHUFFLE_I5:%.*]] = shufflevector <2 x i64> [[A]], <2 x i64> [[A]], <1 x i32> <i32 1>
67 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x i64> [[SHUFFLE_I5]] to i64
68 // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <2 x i64> [[B]], <2 x i64> [[B]], <1 x i32> <i32 1>
69 // CHECK-NEXT: [[TMP1:%.*]] = bitcast <1 x i64> [[SHUFFLE_I]] to i64
70 // CHECK-NEXT: [[VMULL_P64_I_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 [[TMP0]], i64 [[TMP1]])
71 // CHECK-NEXT: [[VMULL_P641_I_I:%.*]] = bitcast <16 x i8> [[VMULL_P64_I_I]] to i128
72 // CHECK-NEXT: ret i128 [[VMULL_P641_I_I]]
74 __attribute__((target("aes"))) poly128_t
test_vmull_high_p64(poly64x2_t a
, poly64x2_t b
) {
75 return vmull_high_p64(a
, b
);
78 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_s8
79 // CHECK-SAME: (<16 x i8> noundef [[A:%.*]]) #[[ATTR3:[0-9]+]] {
81 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A]] to i128
82 // CHECK-NEXT: ret i128 [[TMP0]]
84 poly128_t
test_vreinterpretq_p128_s8(int8x16_t a
) {
85 return vreinterpretq_p128_s8(a
);
88 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_s16
89 // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR3]] {
91 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to i128
92 // CHECK-NEXT: ret i128 [[TMP0]]
94 poly128_t
test_vreinterpretq_p128_s16(int16x8_t a
) {
95 return vreinterpretq_p128_s16(a
);
98 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_s32
99 // CHECK-SAME: (<4 x i32> noundef [[A:%.*]]) #[[ATTR3]] {
100 // CHECK-NEXT: entry:
101 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to i128
102 // CHECK-NEXT: ret i128 [[TMP0]]
104 poly128_t
test_vreinterpretq_p128_s32(int32x4_t a
) {
105 return vreinterpretq_p128_s32(a
);
108 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_s64
109 // CHECK-SAME: (<2 x i64> noundef [[A:%.*]]) #[[ATTR3]] {
110 // CHECK-NEXT: entry:
111 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to i128
112 // CHECK-NEXT: ret i128 [[TMP0]]
114 poly128_t
test_vreinterpretq_p128_s64(int64x2_t a
) {
115 return vreinterpretq_p128_s64(a
);
118 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_u8
119 // CHECK-SAME: (<16 x i8> noundef [[A:%.*]]) #[[ATTR3]] {
120 // CHECK-NEXT: entry:
121 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A]] to i128
122 // CHECK-NEXT: ret i128 [[TMP0]]
124 poly128_t
test_vreinterpretq_p128_u8(uint8x16_t a
) {
125 return vreinterpretq_p128_u8(a
);
128 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_u16
129 // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR3]] {
130 // CHECK-NEXT: entry:
131 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to i128
132 // CHECK-NEXT: ret i128 [[TMP0]]
134 poly128_t
test_vreinterpretq_p128_u16(uint16x8_t a
) {
135 return vreinterpretq_p128_u16(a
);
138 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_u32
139 // CHECK-SAME: (<4 x i32> noundef [[A:%.*]]) #[[ATTR3]] {
140 // CHECK-NEXT: entry:
141 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to i128
142 // CHECK-NEXT: ret i128 [[TMP0]]
144 poly128_t
test_vreinterpretq_p128_u32(uint32x4_t a
) {
145 return vreinterpretq_p128_u32(a
);
148 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_u64
149 // CHECK-SAME: (<2 x i64> noundef [[A:%.*]]) #[[ATTR3]] {
150 // CHECK-NEXT: entry:
151 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to i128
152 // CHECK-NEXT: ret i128 [[TMP0]]
154 poly128_t
test_vreinterpretq_p128_u64(uint64x2_t a
) {
155 return vreinterpretq_p128_u64(a
);
158 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_f32
159 // CHECK-SAME: (<4 x float> noundef [[A:%.*]]) #[[ATTR3]] {
160 // CHECK-NEXT: entry:
161 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to i128
162 // CHECK-NEXT: ret i128 [[TMP0]]
164 poly128_t
test_vreinterpretq_p128_f32(float32x4_t a
) {
165 return vreinterpretq_p128_f32(a
);
168 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_f64
169 // CHECK-SAME: (<2 x double> noundef [[A:%.*]]) #[[ATTR3]] {
170 // CHECK-NEXT: entry:
171 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[A]] to i128
172 // CHECK-NEXT: ret i128 [[TMP0]]
174 poly128_t
test_vreinterpretq_p128_f64(float64x2_t a
) {
175 return vreinterpretq_p128_f64(a
);
178 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_p8
179 // CHECK-SAME: (<16 x i8> noundef [[A:%.*]]) #[[ATTR3]] {
180 // CHECK-NEXT: entry:
181 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A]] to i128
182 // CHECK-NEXT: ret i128 [[TMP0]]
184 poly128_t
test_vreinterpretq_p128_p8(poly8x16_t a
) {
185 return vreinterpretq_p128_p8(a
);
188 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_p16
189 // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR3]] {
190 // CHECK-NEXT: entry:
191 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to i128
192 // CHECK-NEXT: ret i128 [[TMP0]]
194 poly128_t
test_vreinterpretq_p128_p16(poly16x8_t a
) {
195 return vreinterpretq_p128_p16(a
);
198 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_p64
199 // CHECK-SAME: (<2 x i64> noundef [[A:%.*]]) #[[ATTR3]] {
200 // CHECK-NEXT: entry:
201 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to i128
202 // CHECK-NEXT: ret i128 [[TMP0]]
204 poly128_t
test_vreinterpretq_p128_p64(poly64x2_t a
) {
205 return vreinterpretq_p128_p64(a
);
208 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_s8_p128
209 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
210 // CHECK-NEXT: entry:
211 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <16 x i8>
212 // CHECK-NEXT: ret <16 x i8> [[TMP0]]
214 int8x16_t
test_vreinterpretq_s8_p128(poly128_t a
) {
215 return vreinterpretq_s8_p128(a
);
218 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_s16_p128
219 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
220 // CHECK-NEXT: entry:
221 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <8 x i16>
222 // CHECK-NEXT: ret <8 x i16> [[TMP0]]
224 int16x8_t
test_vreinterpretq_s16_p128(poly128_t a
) {
225 return vreinterpretq_s16_p128(a
);
228 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_s32_p128
229 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
230 // CHECK-NEXT: entry:
231 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <4 x i32>
232 // CHECK-NEXT: ret <4 x i32> [[TMP0]]
234 int32x4_t
test_vreinterpretq_s32_p128(poly128_t a
) {
235 return vreinterpretq_s32_p128(a
);
238 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_s64_p128
239 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
240 // CHECK-NEXT: entry:
241 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <2 x i64>
242 // CHECK-NEXT: ret <2 x i64> [[TMP0]]
244 int64x2_t
test_vreinterpretq_s64_p128(poly128_t a
) {
245 return vreinterpretq_s64_p128(a
);
248 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_u8_p128
249 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
250 // CHECK-NEXT: entry:
251 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <16 x i8>
252 // CHECK-NEXT: ret <16 x i8> [[TMP0]]
254 uint8x16_t
test_vreinterpretq_u8_p128(poly128_t a
) {
255 return vreinterpretq_u8_p128(a
);
258 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_u16_p128
259 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
260 // CHECK-NEXT: entry:
261 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <8 x i16>
262 // CHECK-NEXT: ret <8 x i16> [[TMP0]]
264 uint16x8_t
test_vreinterpretq_u16_p128(poly128_t a
) {
265 return vreinterpretq_u16_p128(a
);
268 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_u32_p128
269 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
270 // CHECK-NEXT: entry:
271 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <4 x i32>
272 // CHECK-NEXT: ret <4 x i32> [[TMP0]]
274 uint32x4_t
test_vreinterpretq_u32_p128(poly128_t a
) {
275 return vreinterpretq_u32_p128(a
);
278 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_u64_p128
279 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
280 // CHECK-NEXT: entry:
281 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <2 x i64>
282 // CHECK-NEXT: ret <2 x i64> [[TMP0]]
284 uint64x2_t
test_vreinterpretq_u64_p128(poly128_t a
) {
285 return vreinterpretq_u64_p128(a
);
288 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_f32_p128
289 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
290 // CHECK-NEXT: entry:
291 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <4 x float>
292 // CHECK-NEXT: ret <4 x float> [[TMP0]]
294 float32x4_t
test_vreinterpretq_f32_p128(poly128_t a
) {
295 return vreinterpretq_f32_p128(a
);
298 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_f64_p128
299 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
300 // CHECK-NEXT: entry:
301 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <2 x double>
302 // CHECK-NEXT: ret <2 x double> [[TMP0]]
304 float64x2_t
test_vreinterpretq_f64_p128(poly128_t a
) {
305 return vreinterpretq_f64_p128(a
);
308 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p8_p128
309 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
310 // CHECK-NEXT: entry:
311 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <16 x i8>
312 // CHECK-NEXT: ret <16 x i8> [[TMP0]]
314 poly8x16_t
test_vreinterpretq_p8_p128(poly128_t a
) {
315 return vreinterpretq_p8_p128(a
);
318 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p16_p128
319 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
320 // CHECK-NEXT: entry:
321 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <8 x i16>
322 // CHECK-NEXT: ret <8 x i16> [[TMP0]]
324 poly16x8_t
test_vreinterpretq_p16_p128(poly128_t a
) {
325 return vreinterpretq_p16_p128(a
);
328 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p64_p128
329 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR3]] {
330 // CHECK-NEXT: entry:
331 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <2 x i64>
332 // CHECK-NEXT: ret <2 x i64> [[TMP0]]
334 poly64x2_t
test_vreinterpretq_p64_p128(poly128_t a
) {
335 return vreinterpretq_p64_p128(a
);