1 // RUN: %clang_cc1 -ffreestanding -triple armv8-eabi -target-cpu cortex-a57 -O2  -fno-experimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch32 -check-prefix=ARM-LEGACY -check-prefix=AArch32-LEGACY
2 // RUN: %clang_cc1 -ffreestanding -triple armv8-eabi -target-cpu cortex-a57 -O2  -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch32 -check-prefix=ARM-NEWPM -check-prefix=AArch32-NEWPM
3 // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +neon -target-feature +crc -target-feature +crypto -O2 -fno-experimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch64 -check-prefix=ARM-LEGACY -check-prefix=AArch64-LEGACY
4 // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +neon -target-feature +crc -target-feature +crypto -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch64 -check-prefix=ARM-NEWPM -check-prefix=AArch64-NEWPM
5 // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +v8.3a -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=AArch64-v8_3
6 // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +v8.4a -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=AArch64-v8_3
7 // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +v8.5a -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=AArch64-v8_3
8 
9 // REQUIRES: rewrite
10 
11 #include <arm_acle.h>
12 
13 /* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
14 /* 8.3 Memory Barriers */
15 // ARM-LABEL: test_dmb
16 // AArch32: call void @llvm.arm.dmb(i32 1)
17 // AArch64: call void @llvm.aarch64.dmb(i32 1)
18 void test_dmb(void) {
19   __dmb(1);
20 }
21 
22 // ARM-LABEL: test_dsb
23 // AArch32: call void @llvm.arm.dsb(i32 2)
24 // AArch64: call void @llvm.aarch64.dsb(i32 2)
25 void test_dsb(void) {
26   __dsb(2);
27 }
28 
29 // ARM-LABEL: test_isb
30 // AArch32: call void @llvm.arm.isb(i32 3)
31 // AArch64: call void @llvm.aarch64.isb(i32 3)
32 void test_isb(void) {
33   __isb(3);
34 }
35 
36 /* 8.4 Hints */
37 // ARM-LABEL: test_yield
38 // AArch32: call void @llvm.arm.hint(i32 1)
39 // AArch64: call void @llvm.aarch64.hint(i32 1)
40 void test_yield(void) {
41   __yield();
42 }
43 
44 // ARM-LABEL: test_wfe
45 // AArch32: call void @llvm.arm.hint(i32 2)
46 // AArch64: call void @llvm.aarch64.hint(i32 2)
47 void test_wfe(void) {
48   __wfe();
49 }
50 
51 // ARM-LABEL: test_wfi
52 // AArch32: call void @llvm.arm.hint(i32 3)
53 // AArch64: call void @llvm.aarch64.hint(i32 3)
54 void test_wfi(void) {
55   __wfi();
56 }
57 
58 // ARM-LABEL: test_sev
59 // AArch32: call void @llvm.arm.hint(i32 4)
60 // AArch64: call void @llvm.aarch64.hint(i32 4)
61 void test_sev(void) {
62   __sev();
63 }
64 
65 // ARM-LABEL: test_sevl
66 // AArch32: call void @llvm.arm.hint(i32 5)
67 // AArch64: call void @llvm.aarch64.hint(i32 5)
68 void test_sevl(void) {
69   __sevl();
70 }
71 
72 #if __ARM_32BIT_STATE
73 // AArch32-LABEL: test_dbg
74 // AArch32: call void @llvm.arm.dbg(i32 0)
75 void test_dbg(void) {
76   __dbg(0);
77 }
78 #endif
79 
80 /* 8.5 Swap */
81 // ARM-LABEL: test_swp
82 // AArch32: call i32 @llvm.arm.ldrex
83 // AArch32: call i32 @llvm.arm.strex
84 // AArch64: call i64 @llvm.aarch64.ldxr
85 // AArch64: call i32 @llvm.aarch64.stxr
86 void test_swp(uint32_t x, volatile void *p) {
87   __swp(x, p);
88 }
89 
90 /* 8.6 Memory prefetch intrinsics */
91 /* 8.6.1 Data prefetch */
92 // ARM-LABEL: test_pld
93 // ARM: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 1)
94 void test_pld() {
95   __pld(0);
96 }
97 
98 // ARM-LABEL: test_pldx
99 // AArch32: call void @llvm.prefetch.p0i8(i8* null, i32 1, i32 3, i32 1)
100 // AArch64: call void @llvm.prefetch.p0i8(i8* null, i32 1, i32 1, i32 1)
101 void test_pldx() {
102   __pldx(1, 2, 0, 0);
103 }
104 
105 /* 8.6.2 Instruction prefetch */
106 // ARM-LABEL: test_pli
107 // ARM: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0)
108 void test_pli() {
109   __pli(0);
110 }
111 
112 // ARM-LABEL: test_plix
113 // AArch32: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0)
114 // AArch64: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 1, i32 0)
115 void test_plix() {
116   __plix(2, 0, 0);
117 }
118 
119 /* 8.7 NOP */
120 // ARM-LABEL: test_nop
121 // AArch32: call void @llvm.arm.hint(i32 0)
122 // AArch64: call void @llvm.aarch64.hint(i32 0)
123 void test_nop(void) {
124   __nop();
125 }
126 
127 /* 9 DATA-PROCESSING INTRINSICS */
128 
129 /* 9.2 Miscellaneous data-processing intrinsics */
130 // ARM-LABEL: test_ror
131 // ARM-LEGACY: lshr
132 // ARM-LEGACY: sub
133 // ARM-LEGACY: shl
134 // ARM-LEGACY: or
135 // ARM-NEWPM: call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y)
136 uint32_t test_ror(uint32_t x, uint32_t y) {
137   return __ror(x, y);
138 }
139 
140 // ARM-LABEL: test_rorl
141 // ARM-LEGACY: lshr
142 // ARM-LEGACY: sub
143 // ARM-LEGACY: shl
144 // ARM-LEGACY: or
145 // AArch32-NEWPM: call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y)
146 unsigned long test_rorl(unsigned long x, uint32_t y) {
147   return __rorl(x, y);
148 }
149 
150 // ARM-LABEL: test_rorll
151 // ARM: lshr
152 // ARM: sub
153 // ARM: shl
154 // ARM: or
155 uint64_t test_rorll(uint64_t x, uint32_t y) {
156   return __rorll(x, y);
157 }
158 
159 // ARM-LABEL: test_clz
160 // ARM: call i32 @llvm.ctlz.i32(i32 %t, i1 false)
161 uint32_t test_clz(uint32_t t) {
162   return __clz(t);
163 }
164 
165 // ARM-LABEL: test_clzl
166 // AArch32: call i32 @llvm.ctlz.i32(i32 %t, i1 false)
167 // AArch64: call i64 @llvm.ctlz.i64(i64 %t, i1 false)
168 long test_clzl(long t) {
169   return __clzl(t);
170 }
171 
172 // ARM-LABEL: test_clzll
173 // ARM: call i64 @llvm.ctlz.i64(i64 %t, i1 false)
174 uint64_t test_clzll(uint64_t t) {
175   return __clzll(t);
176 }
177 
178 // ARM-LABEL: test_rev
179 // ARM: call i32 @llvm.bswap.i32(i32 %t)
180 uint32_t test_rev(uint32_t t) {
181   return __rev(t);
182 }
183 
184 // ARM-LABEL: test_revl
185 // AArch32: call i32 @llvm.bswap.i32(i32 %t)
186 // AArch64: call i64 @llvm.bswap.i64(i64 %t)
187 long test_revl(long t) {
188   return __revl(t);
189 }
190 
191 // ARM-LABEL: test_revll
192 // ARM: call i64 @llvm.bswap.i64(i64 %t)
193 uint64_t test_revll(uint64_t t) {
194   return __revll(t);
195 }
196 
197 // ARM-LABEL: test_rev16
198 // ARM: llvm.bswap
199 // ARM-LEGACY: lshr {{.*}}, 16
200 // ARM-LEGACY: shl {{.*}}, 16
201 // ARM-LEGACY: or
202 // ARM-NEWPM: call i32 @llvm.fshl.i32(i32 %0, i32 %0, i32 16)
203 uint32_t test_rev16(uint32_t t) {
204   return __rev16(t);
205 }
206 
207 // ARM-LABEL: test_rev16l
208 // AArch32: llvm.bswap
209 // AArch32-LEGACY: lshr {{.*}}, 16
210 // AArch32-LEGACY: shl {{.*}}, 16
211 // AArch32-LEGACY: or
212 // AArch32-NEWPM: call i32 @llvm.fshl.i32(i32 %0, i32 %0, i32 16)
213 // AArch64: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32
214 // AArch64: [[T2:%.*]] = trunc i64 [[T1]] to i32
215 // AArch64: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]])
216 // AArch64-LEGACY: [[T4:%.*]] = lshr i32 [[T3]], 16
217 // AArch64-LEGACY: [[T5:%.*]] = shl i32 [[T3]], 16
218 // AArch64-LEGACY: [[T6:%.*]] = or i32 [[T5]], [[T4]]
219 // AArch64-NEWPM: [[T6:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T3]], i32 [[T3]], i32 16)
220 // AArch64: [[T7:%.*]] = zext i32 [[T6]] to i64
221 // AArch64: [[T8:%.*]] = shl nuw i64 [[T7]], 32
222 // AArch64: [[T9:%.*]] = trunc i64 [[IN]] to i32
223 // AArch64: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]])
224 // AArch64-LEGACY: [[T11:%.*]] = lshr i32 [[T10]], 16
225 // AArch64-LEGACY: [[T12:%.*]] = shl i32 [[T10]], 16
226 // AArch64-LEGACY: [[T13:%.*]] = or i32 [[T12]], [[T11]]
227 // AArch64-NEWPM: [[T13:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T10]], i32 [[T10]], i32 16)
228 // AArch64: [[T14:%.*]] = zext i32 [[T13]] to i64
229 // AArch64: [[T15:%.*]] = or i64 [[T8]], [[T14]]
230 long test_rev16l(long t) {
231   return __rev16l(t);
232 }
233 
234 // ARM-LABEL: test_rev16ll
235 // ARM: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32
236 // ARM: [[T2:%.*]] = trunc i64 [[T1]] to i32
237 // ARM: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]])
238 // ARM-LEGACY: [[T4:%.*]] = lshr i32 [[T3]], 16
239 // ARM-LEGACY: [[T5:%.*]] = shl i32 [[T3]], 16
240 // ARM-LEGACY: [[T6:%.*]] = or i32 [[T5]], [[T4]]
241 // ARM-NEWPM: [[T6:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T3]], i32 [[T3]], i32 16)
242 // ARM: [[T7:%.*]] = zext i32 [[T6]] to i64
243 // ARM: [[T8:%.*]] = shl nuw i64 [[T7]], 32
244 // ARM: [[T9:%.*]] = trunc i64 [[IN]] to i32
245 // ARM: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]])
246 // ARM-LEGACY: [[T11:%.*]] = lshr i32 [[T10]], 16
247 // ARM-LEGACY: [[T12:%.*]] = shl i32 [[T10]], 16
248 // ARM-LEGACY: [[T13:%.*]] = or i32 [[T12]], [[T11]]
249 // ARM-NEWPM: [[T13:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T10]], i32 [[T10]], i32 16)
250 // ARM: [[T14:%.*]] = zext i32 [[T13]] to i64
251 // ARM: [[T15:%.*]] = or i64 [[T8]], [[T14]]
252 uint64_t test_rev16ll(uint64_t t) {
253   return __rev16ll(t);
254 }
255 
256 // ARM-LABEL: test_revsh
257 // ARM: call i16 @llvm.bswap.i16(i16 %t)
258 int16_t test_revsh(int16_t t) {
259   return __revsh(t);
260 }
261 
262 // ARM-LABEL: test_rbit
263 // AArch32: call i32 @llvm.bitreverse.i32
264 // AArch64: call i32 @llvm.bitreverse.i32
265 uint32_t test_rbit(uint32_t t) {
266   return __rbit(t);
267 }
268 
269 // ARM-LABEL: test_rbitl
270 // AArch32: call i32 @llvm.bitreverse.i32
271 // AArch64: call i64 @llvm.bitreverse.i64
272 long test_rbitl(long t) {
273   return __rbitl(t);
274 }
275 
276 // ARM-LABEL: test_rbitll
277 // AArch32: call i32 @llvm.bitreverse.i32
278 // AArch32: call i32 @llvm.bitreverse.i32
279 // AArch64: call i64 @llvm.bitreverse.i64
280 uint64_t test_rbitll(uint64_t t) {
281   return __rbitll(t);
282 }
283 
284 /* 9.4 Saturating intrinsics */
285 #ifdef __ARM_FEATURE_SAT
286 /* 9.4.1 Width-specified saturation intrinsics */
287 // AArch32-LABEL: test_ssat
288 // AArch32: call i32 @llvm.arm.ssat(i32 %t, i32 1)
289 int32_t test_ssat(int32_t t) {
290   return __ssat(t, 1);
291 }
292 
293 // AArch32-LABEL: test_usat
294 // AArch32: call i32 @llvm.arm.usat(i32 %t, i32 2)
295 uint32_t test_usat(int32_t t) {
296   return __usat(t, 2);
297 }
298 #endif
299 
300 /* 9.4.2 Saturating addition and subtraction intrinsics */
301 #ifdef __ARM_FEATURE_DSP
302 // AArch32-LABEL: test_qadd
303 // AArch32: call i32 @llvm.arm.qadd(i32 %a, i32 %b)
304 int32_t test_qadd(int32_t a, int32_t b) {
305   return __qadd(a, b);
306 }
307 
308 // AArch32-LABEL: test_qsub
309 // AArch32: call i32 @llvm.arm.qsub(i32 %a, i32 %b)
310 int32_t test_qsub(int32_t a, int32_t b) {
311   return __qsub(a, b);
312 }
313 
314 extern int32_t f();
315 // AArch32-LABEL: test_qdbl
316 // AArch32: [[VAR:%[a-z0-9]+]] = {{.*}} call {{.*}} @f
317 // AArch32-NOT: call {{.*}} @f
318 // AArch32: call i32 @llvm.arm.qadd(i32 [[VAR]], i32 [[VAR]])
319 int32_t test_qdbl() {
320   return __qdbl(f());
321 }
322 #endif
323 
324 /*
325  * 9.3 16-bit multiplications
326  */
327 #if __ARM_FEATURE_DSP
328 // AArch32-LABEL: test_smulbb
329 // AArch32: call i32 @llvm.arm.smulbb
330 int32_t test_smulbb(int32_t a, int32_t b) {
331   return __smulbb(a, b);
332 }
333 // AArch32-LABEL: test_smulbt
334 // AArch32: call i32 @llvm.arm.smulbt
335 int32_t test_smulbt(int32_t a, int32_t b) {
336   return __smulbt(a, b);
337 }
338 // AArch32-LABEL: test_smultb
339 // AArch32: call i32 @llvm.arm.smultb
340 int32_t test_smultb(int32_t a, int32_t b) {
341   return __smultb(a, b);
342 }
343 // AArch32-LABEL: test_smultt
344 // AArch32: call i32 @llvm.arm.smultt
345 int32_t test_smultt(int32_t a, int32_t b) {
346   return __smultt(a, b);
347 }
348 // AArch32-LABEL: test_smulwb
349 // AArch32: call i32 @llvm.arm.smulwb
350 int32_t test_smulwb(int32_t a, int32_t b) {
351   return __smulwb(a, b);
352 }
353 // AArch32-LABEL: test_smulwt
354 // AArch32: call i32 @llvm.arm.smulwt
355 int32_t test_smulwt(int32_t a, int32_t b) {
356   return __smulwt(a, b);
357 }
358 #endif
359 
360 /* 9.4.3 Accumultating multiplications */
361 #if __ARM_FEATURE_DSP
362 // AArch32-LABEL: test_smlabb
363 // AArch32: call i32 @llvm.arm.smlabb(i32 %a, i32 %b, i32 %c)
364 int32_t test_smlabb(int32_t a, int32_t b, int32_t c) {
365   return __smlabb(a, b, c);
366 }
367 // AArch32-LABEL: test_smlabt
368 // AArch32: call i32 @llvm.arm.smlabt(i32 %a, i32 %b, i32 %c)
369 int32_t test_smlabt(int32_t a, int32_t b, int32_t c) {
370   return __smlabt(a, b, c);
371 }
372 // AArch32-LABEL: test_smlatb
373 // AArch32: call i32 @llvm.arm.smlatb(i32 %a, i32 %b, i32 %c)
374 int32_t test_smlatb(int32_t a, int32_t b, int32_t c) {
375   return __smlatb(a, b, c);
376 }
377 // AArch32-LABEL: test_smlatt
378 // AArch32: call i32 @llvm.arm.smlatt(i32 %a, i32 %b, i32 %c)
379 int32_t test_smlatt(int32_t a, int32_t b, int32_t c) {
380   return __smlatt(a, b, c);
381 }
382 // AArch32-LABEL: test_smlawb
383 // AArch32: call i32 @llvm.arm.smlawb(i32 %a, i32 %b, i32 %c)
384 int32_t test_smlawb(int32_t a, int32_t b, int32_t c) {
385   return __smlawb(a, b, c);
386 }
387 // AArch32-LABEL: test_smlawt
388 // AArch32: call i32 @llvm.arm.smlawt(i32 %a, i32 %b, i32 %c)
389 int32_t test_smlawt(int32_t a, int32_t b, int32_t c) {
390   return __smlawt(a, b, c);
391 }
392 #endif
393 
394 /* 9.5.4 Parallel 16-bit saturation */
395 #if __ARM_FEATURE_SIMD32
396 // AArch32-LABEL: test_ssat16
397 // AArch32: call i32 @llvm.arm.ssat16
398 int16x2_t test_ssat16(int16x2_t a) {
399   return __ssat16(a, 15);
400 }
401 // AArch32-LABEL: test_usat16
402 // AArch32: call i32 @llvm.arm.usat16
403 uint16x2_t test_usat16(int16x2_t a) {
404   return __usat16(a, 15);
405 }
406 #endif
407 
408 /* 9.5.5 Packing and unpacking */
409 #if __ARM_FEATURE_SIMD32
410 // AArch32-LABEL: test_sxtab16
411 // AArch32: call i32 @llvm.arm.sxtab16
412 int16x2_t test_sxtab16(int16x2_t a, int8x4_t b) {
413   return __sxtab16(a, b);
414 }
415 // AArch32-LABEL: test_sxtb16
416 // AArch32: call i32 @llvm.arm.sxtb16
417 int16x2_t test_sxtb16(int8x4_t a) {
418   return __sxtb16(a);
419 }
420 // AArch32-LABEL: test_uxtab16
421 // AArch32: call i32 @llvm.arm.uxtab16
422 int16x2_t test_uxtab16(int16x2_t a, int8x4_t b) {
423   return __uxtab16(a, b);
424 }
425 // AArch32-LABEL: test_uxtb16
426 // AArch32: call i32 @llvm.arm.uxtb16
427 int16x2_t test_uxtb16(int8x4_t a) {
428   return __uxtb16(a);
429 }
430 #endif
431 
432 /* 9.5.6 Parallel selection */
433 #if __ARM_FEATURE_SIMD32
434 // AArch32-LABEL: test_sel
435 // AArch32: call i32 @llvm.arm.sel
436 uint8x4_t test_sel(uint8x4_t a, uint8x4_t b) {
437   return __sel(a, b);
438 }
439 #endif
440 
441 /* 9.5.7 Parallel 8-bit addition and subtraction */
442 #if __ARM_FEATURE_SIMD32
443 // AArch32-LABEL: test_qadd8
444 // AArch32: call i32 @llvm.arm.qadd8
445 int16x2_t test_qadd8(int8x4_t a, int8x4_t b) {
446   return __qadd8(a, b);
447 }
448 // AArch32-LABEL: test_qsub8
449 // AArch32: call i32 @llvm.arm.qsub8
450 int8x4_t test_qsub8(int8x4_t a, int8x4_t b) {
451   return __qsub8(a, b);
452 }
453 // AArch32-LABEL: test_sadd8
454 // AArch32: call i32 @llvm.arm.sadd8
455 int8x4_t test_sadd8(int8x4_t a, int8x4_t b) {
456   return __sadd8(a, b);
457 }
458 // AArch32-LABEL: test_shadd8
459 // AArch32: call i32 @llvm.arm.shadd8
460 int8x4_t test_shadd8(int8x4_t a, int8x4_t b) {
461   return __shadd8(a, b);
462 }
463 // AArch32-LABEL: test_shsub8
464 // AArch32: call i32 @llvm.arm.shsub8
465 int8x4_t test_shsub8(int8x4_t a, int8x4_t b) {
466   return __shsub8(a, b);
467 }
468 // AArch32-LABEL: test_ssub8
469 // AArch32: call i32 @llvm.arm.ssub8
470 int8x4_t test_ssub8(int8x4_t a, int8x4_t b) {
471   return __ssub8(a, b);
472 }
473 // AArch32-LABEL: test_uadd8
474 // AArch32: call i32 @llvm.arm.uadd8
475 uint8x4_t test_uadd8(uint8x4_t a, uint8x4_t b) {
476   return __uadd8(a, b);
477 }
478 // AArch32-LABEL: test_uhadd8
479 // AArch32: call i32 @llvm.arm.uhadd8
480 uint8x4_t test_uhadd8(uint8x4_t a, uint8x4_t b) {
481   return __uhadd8(a, b);
482 }
483 // AArch32-LABEL: test_uhsub8
484 // AArch32: call i32 @llvm.arm.uhsub8
485 uint8x4_t test_uhsub8(uint8x4_t a, uint8x4_t b) {
486   return __uhsub8(a, b);
487 }
488 // AArch32-LABEL: test_uqadd8
489 // AArch32: call i32 @llvm.arm.uqadd8
490 uint8x4_t test_uqadd8(uint8x4_t a, uint8x4_t b) {
491   return __uqadd8(a, b);
492 }
493 // AArch32-LABEL: test_uqsub8
494 // AArch32: call i32 @llvm.arm.uqsub8
495 uint8x4_t test_uqsub8(uint8x4_t a, uint8x4_t b) {
496   return __uqsub8(a, b);
497 }
498 // AArch32-LABEL: test_usub8
499 // AArch32: call i32 @llvm.arm.usub8
500 uint8x4_t test_usub8(uint8x4_t a, uint8x4_t b) {
501   return __usub8(a, b);
502 }
503 #endif
504 
505 /* 9.5.8 Sum of 8-bit absolute differences */
506 #if __ARM_FEATURE_SIMD32
507 // AArch32-LABEL: test_usad8
508 // AArch32: call i32 @llvm.arm.usad8
509 uint32_t test_usad8(uint8x4_t a, uint8x4_t b) {
510   return __usad8(a, b);
511 }
512 // AArch32-LABEL: test_usada8
513 // AArch32: call i32 @llvm.arm.usada8
514 uint32_t test_usada8(uint8_t a, uint8_t b, uint8_t c) {
515   return __usada8(a, b, c);
516 }
517 #endif
518 
519 /* 9.5.9 Parallel 16-bit addition and subtraction */
520 #if __ARM_FEATURE_SIMD32
521 // AArch32-LABEL: test_qadd16
522 // AArch32: call i32 @llvm.arm.qadd16
523 int16x2_t test_qadd16(int16x2_t a, int16x2_t b) {
524   return __qadd16(a, b);
525 }
526 // AArch32-LABEL: test_qasx
527 // AArch32: call i32 @llvm.arm.qasx
528 int16x2_t test_qasx(int16x2_t a, int16x2_t b) {
529   return __qasx(a, b);
530 }
531 // AArch32-LABEL: test_qsax
532 // AArch32: call i32 @llvm.arm.qsax
533 int16x2_t test_qsax(int16x2_t a, int16x2_t b) {
534   return __qsax(a, b);
535 }
536 // AArch32-LABEL: test_qsub16
537 // AArch32: call i32 @llvm.arm.qsub16
538 int16x2_t test_qsub16(int16x2_t a, int16x2_t b) {
539   return __qsub16(a, b);
540 }
541 // AArch32-LABEL: test_sadd16
542 // AArch32: call i32 @llvm.arm.sadd16
543 int16x2_t test_sadd16(int16x2_t a, int16x2_t b) {
544   return __sadd16(a, b);
545 }
546 // AArch32-LABEL: test_sasx
547 // AArch32: call i32 @llvm.arm.sasx
548 int16x2_t test_sasx(int16x2_t a, int16x2_t b) {
549   return __sasx(a, b);
550 }
551 // AArch32-LABEL: test_shadd16
552 // AArch32: call i32 @llvm.arm.shadd16
553 int16x2_t test_shadd16(int16x2_t a, int16x2_t b) {
554   return __shadd16(a, b);
555 }
556 // AArch32-LABEL: test_shasx
557 // AArch32: call i32 @llvm.arm.shasx
558 int16x2_t test_shasx(int16x2_t a, int16x2_t b) {
559   return __shasx(a, b);
560 }
561 // AArch32-LABEL: test_shsax
562 // AArch32: call i32 @llvm.arm.shsax
563 int16x2_t test_shsax(int16x2_t a, int16x2_t b) {
564   return __shsax(a, b);
565 }
566 // AArch32-LABEL: test_shsub16
567 // AArch32: call i32 @llvm.arm.shsub16
568 int16x2_t test_shsub16(int16x2_t a, int16x2_t b) {
569   return __shsub16(a, b);
570 }
571 // AArch32-LABEL: test_ssax
572 // AArch32: call i32 @llvm.arm.ssax
573 int16x2_t test_ssax(int16x2_t a, int16x2_t b) {
574   return __ssax(a, b);
575 }
576 // AArch32-LABEL: test_ssub16
577 // AArch32: call i32 @llvm.arm.ssub16
578 int16x2_t test_ssub16(int16x2_t a, int16x2_t b) {
579   return __ssub16(a, b);
580 }
581 // AArch32-LABEL: test_uadd16
582 // AArch32: call i32 @llvm.arm.uadd16
583 uint16x2_t test_uadd16(uint16x2_t a, uint16x2_t b) {
584   return __uadd16(a, b);
585 }
586 // AArch32-LABEL: test_uasx
587 // AArch32: call i32 @llvm.arm.uasx
588 uint16x2_t test_uasx(uint16x2_t a, uint16x2_t b) {
589   return __uasx(a, b);
590 }
591 // AArch32-LABEL: test_uhadd16
592 // AArch32: call i32 @llvm.arm.uhadd16
593 uint16x2_t test_uhadd16(uint16x2_t a, uint16x2_t b) {
594   return __uhadd16(a, b);
595 }
596 // AArch32-LABEL: test_uhasx
597 // AArch32: call i32 @llvm.arm.uhasx
598 uint16x2_t test_uhasx(uint16x2_t a, uint16x2_t b) {
599   return __uhasx(a, b);
600 }
601 // AArch32-LABEL: test_uhsax
602 // AArch32: call i32 @llvm.arm.uhsax
603 uint16x2_t test_uhsax(uint16x2_t a, uint16x2_t b) {
604   return __uhsax(a, b);
605 }
606 // AArch32-LABEL: test_uhsub16
607 // AArch32: call i32 @llvm.arm.uhsub16
608 uint16x2_t test_uhsub16(uint16x2_t a, uint16x2_t b) {
609   return __uhsub16(a, b);
610 }
611 // AArch32-LABEL: test_uqadd16
612 // AArch32: call i32 @llvm.arm.uqadd16
613 uint16x2_t test_uqadd16(uint16x2_t a, uint16x2_t b) {
614   return __uqadd16(a, b);
615 }
616 // AArch32-LABEL: test_uqasx
617 // AArch32: call i32 @llvm.arm.uqasx
618 uint16x2_t test_uqasx(uint16x2_t a, uint16x2_t b) {
619   return __uqasx(a, b);
620 }
621 // AArch32-LABEL: test_uqsax
622 // AArch32: call i32 @llvm.arm.uqsax
623 uint16x2_t test_uqsax(uint16x2_t a, uint16x2_t b) {
624   return __uqsax(a, b);
625 }
626 // AArch32-LABEL: test_uqsub16
627 // AArch32: call i32 @llvm.arm.uqsub16
628 uint16x2_t test_uqsub16(uint16x2_t a, uint16x2_t b) {
629   return __uqsub16(a, b);
630 }
631 // AArch32-LABEL: test_usax
632 // AArch32: call i32 @llvm.arm.usax
633 uint16x2_t test_usax(uint16x2_t a, uint16x2_t b) {
634   return __usax(a, b);
635 }
636 // AArch32-LABEL: test_usub16
637 // AArch32: call i32 @llvm.arm.usub16
638 uint16x2_t test_usub16(uint16x2_t a, uint16x2_t b) {
639   return __usub16(a, b);
640 }
641 #endif
642 
643 /* 9.5.10 Parallel 16-bit multiplications */
644 #if __ARM_FEATURE_SIMD32
645 // AArch32-LABEL: test_smlad
646 // AArch32: call i32 @llvm.arm.smlad
647 int32_t test_smlad(int16x2_t a, int16x2_t b, int32_t c) {
648   return __smlad(a, b, c);
649 }
650 // AArch32-LABEL: test_smladx
651 // AArch32: call i32 @llvm.arm.smladx
652 int32_t test_smladx(int16x2_t a, int16x2_t b, int32_t c) {
653   return __smladx(a, b, c);
654 }
655 // AArch32-LABEL: test_smlald
656 // AArch32: call i64 @llvm.arm.smlald
657 int64_t test_smlald(int16x2_t a, int16x2_t b, int64_t c) {
658   return __smlald(a, b, c);
659 }
660 // AArch32-LABEL: test_smlaldx
661 // AArch32: call i64 @llvm.arm.smlaldx
662 int64_t test_smlaldx(int16x2_t a, int16x2_t b, int64_t c) {
663   return __smlaldx(a, b, c);
664 }
665 // AArch32-LABEL: test_smlsd
666 // AArch32: call i32 @llvm.arm.smlsd
667 int32_t test_smlsd(int16x2_t a, int16x2_t b, int32_t c) {
668   return __smlsd(a, b, c);
669 }
670 // AArch32-LABEL: test_smlsdx
671 // AArch32: call i32 @llvm.arm.smlsdx
672 int32_t test_smlsdx(int16x2_t a, int16x2_t b, int32_t c) {
673   return __smlsdx(a, b, c);
674 }
675 // AArch32-LABEL: test_smlsld
676 // AArch32: call i64 @llvm.arm.smlsld
677 int64_t test_smlsld(int16x2_t a, int16x2_t b, int64_t c) {
678   return __smlsld(a, b, c);
679 }
680 // AArch32-LABEL: test_smlsldx
681 // AArch32: call i64 @llvm.arm.smlsldx
682 int64_t test_smlsldx(int16x2_t a, int16x2_t b, int64_t c) {
683   return __smlsldx(a, b, c);
684 }
685 // AArch32-LABEL: test_smuad
686 // AArch32: call i32 @llvm.arm.smuad
687 int32_t test_smuad(int16x2_t a, int16x2_t b) {
688   return __smuad(a, b);
689 }
690 // AArch32-LABEL: test_smuadx
691 // AArch32: call i32 @llvm.arm.smuadx
692 int32_t test_smuadx(int16x2_t a, int16x2_t b) {
693   return __smuadx(a, b);
694 }
695 // AArch32-LABEL: test_smusd
696 // AArch32: call i32 @llvm.arm.smusd
697 int32_t test_smusd(int16x2_t a, int16x2_t b) {
698   return __smusd(a, b);
699 }
700 // AArch32-LABEL: test_smusdx
701 // AArch32: call i32 @llvm.arm.smusdx
702 int32_t test_smusdx(int16x2_t a, int16x2_t b) {
703   return __smusdx(a, b);
704 }
705 #endif
706 
707 /* 9.7 CRC32 intrinsics */
708 // ARM-LABEL: test_crc32b
709 // AArch32: call i32 @llvm.arm.crc32b
710 // AArch64: call i32 @llvm.aarch64.crc32b
711 uint32_t test_crc32b(uint32_t a, uint8_t b) {
712   return __crc32b(a, b);
713 }
714 
715 // ARM-LABEL: test_crc32h
716 // AArch32: call i32 @llvm.arm.crc32h
717 // AArch64: call i32 @llvm.aarch64.crc32h
718 uint32_t test_crc32h(uint32_t a, uint16_t b) {
719   return __crc32h(a, b);
720 }
721 
722 // ARM-LABEL: test_crc32w
723 // AArch32: call i32 @llvm.arm.crc32w
724 // AArch64: call i32 @llvm.aarch64.crc32w
725 uint32_t test_crc32w(uint32_t a, uint32_t b) {
726   return __crc32w(a, b);
727 }
728 
729 // ARM-LABEL: test_crc32d
730 // AArch32: call i32 @llvm.arm.crc32w
731 // AArch32: call i32 @llvm.arm.crc32w
732 // AArch64: call i32 @llvm.aarch64.crc32x
733 uint32_t test_crc32d(uint32_t a, uint64_t b) {
734   return __crc32d(a, b);
735 }
736 
737 // ARM-LABEL: test_crc32cb
738 // AArch32: call i32 @llvm.arm.crc32cb
739 // AArch64: call i32 @llvm.aarch64.crc32cb
740 uint32_t test_crc32cb(uint32_t a, uint8_t b) {
741   return __crc32cb(a, b);
742 }
743 
744 // ARM-LABEL: test_crc32ch
745 // AArch32: call i32 @llvm.arm.crc32ch
746 // AArch64: call i32 @llvm.aarch64.crc32ch
747 uint32_t test_crc32ch(uint32_t a, uint16_t b) {
748   return __crc32ch(a, b);
749 }
750 
751 // ARM-LABEL: test_crc32cw
752 // AArch32: call i32 @llvm.arm.crc32cw
753 // AArch64: call i32 @llvm.aarch64.crc32cw
754 uint32_t test_crc32cw(uint32_t a, uint32_t b) {
755   return __crc32cw(a, b);
756 }
757 
758 // ARM-LABEL: test_crc32cd
759 // AArch32: call i32 @llvm.arm.crc32cw
760 // AArch32: call i32 @llvm.arm.crc32cw
761 // AArch64: call i32 @llvm.aarch64.crc32cx
762 uint32_t test_crc32cd(uint32_t a, uint64_t b) {
763   return __crc32cd(a, b);
764 }
765 
766 /* 10.1 Special register intrinsics */
767 // ARM-LABEL: test_rsr
768 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]])
769 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M2:[0-9]]])
770 uint32_t test_rsr() {
771 #ifdef __ARM_32BIT_STATE
772   return __arm_rsr("cp1:2:c3:c4:5");
773 #else
774   return __arm_rsr("1:2:3:4:5");
775 #endif
776 }
777 
778 // ARM-LABEL: test_rsr64
779 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]])
780 // AArch32: call i64 @llvm.read_register.i64(metadata ![[M3:[0-9]]])
781 uint64_t test_rsr64() {
782 #ifdef __ARM_32BIT_STATE
783   return __arm_rsr64("cp1:2:c3");
784 #else
785   return __arm_rsr64("1:2:3:4:5");
786 #endif
787 }
788 
789 // ARM-LABEL: test_rsrp
790 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M1:[0-9]]])
791 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M4:[0-9]]])
792 void *test_rsrp() {
793   return __arm_rsrp("sysreg");
794 }
795 
796 // ARM-LABEL: test_wsr
797 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}})
798 // AArch32: call void @llvm.write_register.i32(metadata ![[M2:[0-9]]], i32 %{{.*}})
799 void test_wsr(uint32_t v) {
800 #ifdef __ARM_32BIT_STATE
801   __arm_wsr("cp1:2:c3:c4:5", v);
802 #else
803   __arm_wsr("1:2:3:4:5", v);
804 #endif
805 }
806 
807 // ARM-LABEL: test_wsr64
808 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}})
809 // AArch32: call void @llvm.write_register.i64(metadata ![[M3:[0-9]]], i64 %{{.*}})
810 void test_wsr64(uint64_t v) {
811 #ifdef __ARM_32BIT_STATE
812   __arm_wsr64("cp1:2:c3", v);
813 #else
814   __arm_wsr64("1:2:3:4:5", v);
815 #endif
816 }
817 
818 // ARM-LABEL: test_wsrp
819 // AArch64: call void @llvm.write_register.i64(metadata ![[M1:[0-9]]], i64 %{{.*}})
820 // AArch32: call void @llvm.write_register.i32(metadata ![[M4:[0-9]]], i32 %{{.*}})
821 void test_wsrp(void *v) {
822   __arm_wsrp("sysreg", v);
823 }
824 
825 // AArch32: ![[M2]] = !{!"cp1:2:c3:c4:5"}
826 // AArch32: ![[M3]] = !{!"cp1:2:c3"}
827 // AArch32: ![[M4]] = !{!"sysreg"}
828 
829 // AArch64: ![[M0]] = !{!"1:2:3:4:5"}
830 // AArch64: ![[M1]] = !{!"sysreg"}
831 
832 // AArch64-v8_3-LABEL: @test_jcvt(
833 // AArch64-v8_3: call i32 @llvm.aarch64.fjcvtzs
834 #ifdef __ARM_64BIT_STATE
835 int32_t test_jcvt(double v) {
836   return __jcvt(v);
837 }
838 #endif
839