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_cls
179 // ARM: call i32 @llvm.arm.cls(i32 %t)
180 unsigned test_cls(uint32_t t) {
181   return __cls(t);
182 }
183 
184 // ARM-LABEL: test_clsl
185 // AArch32: call i32 @llvm.arm.cls(i32 %t)
186 // AArch64: call i32 @llvm.arm.cls64(i64 %t)
187 unsigned test_clsl(unsigned long t) {
188   return __clsl(t);
189 }
190 // ARM-LABEL: test_clsll
191 // ARM: call i32 @llvm.arm.cls64(i64 %t)
192 unsigned test_clsll(uint64_t t) {
193   return __clsll(t);
194 }
195 
196 // ARM-LABEL: test_rev
197 // ARM: call i32 @llvm.bswap.i32(i32 %t)
198 uint32_t test_rev(uint32_t t) {
199   return __rev(t);
200 }
201 
202 // ARM-LABEL: test_revl
203 // AArch32: call i32 @llvm.bswap.i32(i32 %t)
204 // AArch64: call i64 @llvm.bswap.i64(i64 %t)
205 long test_revl(long t) {
206   return __revl(t);
207 }
208 
209 // ARM-LABEL: test_revll
210 // ARM: call i64 @llvm.bswap.i64(i64 %t)
211 uint64_t test_revll(uint64_t t) {
212   return __revll(t);
213 }
214 
215 // ARM-LABEL: test_rev16
216 // ARM: llvm.bswap
217 // ARM-LEGACY: lshr {{.*}}, 16
218 // ARM-LEGACY: shl {{.*}}, 16
219 // ARM-LEGACY: or
220 // ARM-NEWPM: call i32 @llvm.fshl.i32(i32 %0, i32 %0, i32 16)
221 uint32_t test_rev16(uint32_t t) {
222   return __rev16(t);
223 }
224 
225 // ARM-LABEL: test_rev16l
226 // AArch32: llvm.bswap
227 // AArch32-LEGACY: lshr {{.*}}, 16
228 // AArch32-LEGACY: shl {{.*}}, 16
229 // AArch32-LEGACY: or
230 // AArch32-NEWPM: call i32 @llvm.fshl.i32(i32 %0, i32 %0, i32 16)
231 // AArch64: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32
232 // AArch64: [[T2:%.*]] = trunc i64 [[T1]] to i32
233 // AArch64: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]])
234 // AArch64-LEGACY: [[T4:%.*]] = lshr i32 [[T3]], 16
235 // AArch64-LEGACY: [[T5:%.*]] = shl i32 [[T3]], 16
236 // AArch64-LEGACY: [[T6:%.*]] = or i32 [[T5]], [[T4]]
237 // AArch64-NEWPM: [[T6:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T3]], i32 [[T3]], i32 16)
238 // AArch64: [[T7:%.*]] = zext i32 [[T6]] to i64
239 // AArch64: [[T8:%.*]] = shl nuw i64 [[T7]], 32
240 // AArch64: [[T9:%.*]] = trunc i64 [[IN]] to i32
241 // AArch64: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]])
242 // AArch64-LEGACY: [[T11:%.*]] = lshr i32 [[T10]], 16
243 // AArch64-LEGACY: [[T12:%.*]] = shl i32 [[T10]], 16
244 // AArch64-LEGACY: [[T13:%.*]] = or i32 [[T12]], [[T11]]
245 // AArch64-NEWPM: [[T13:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T10]], i32 [[T10]], i32 16)
246 // AArch64: [[T14:%.*]] = zext i32 [[T13]] to i64
247 // AArch64: [[T15:%.*]] = or i64 [[T8]], [[T14]]
248 long test_rev16l(long t) {
249   return __rev16l(t);
250 }
251 
252 // ARM-LABEL: test_rev16ll
253 // ARM: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32
254 // ARM: [[T2:%.*]] = trunc i64 [[T1]] to i32
255 // ARM: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]])
256 // ARM-LEGACY: [[T4:%.*]] = lshr i32 [[T3]], 16
257 // ARM-LEGACY: [[T5:%.*]] = shl i32 [[T3]], 16
258 // ARM-LEGACY: [[T6:%.*]] = or i32 [[T5]], [[T4]]
259 // ARM-NEWPM: [[T6:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T3]], i32 [[T3]], i32 16)
260 // ARM: [[T7:%.*]] = zext i32 [[T6]] to i64
261 // ARM: [[T8:%.*]] = shl nuw i64 [[T7]], 32
262 // ARM: [[T9:%.*]] = trunc i64 [[IN]] to i32
263 // ARM: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]])
264 // ARM-LEGACY: [[T11:%.*]] = lshr i32 [[T10]], 16
265 // ARM-LEGACY: [[T12:%.*]] = shl i32 [[T10]], 16
266 // ARM-LEGACY: [[T13:%.*]] = or i32 [[T12]], [[T11]]
267 // ARM-NEWPM: [[T13:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T10]], i32 [[T10]], i32 16)
268 // ARM: [[T14:%.*]] = zext i32 [[T13]] to i64
269 // ARM: [[T15:%.*]] = or i64 [[T8]], [[T14]]
270 uint64_t test_rev16ll(uint64_t t) {
271   return __rev16ll(t);
272 }
273 
274 // ARM-LABEL: test_revsh
275 // ARM: call i16 @llvm.bswap.i16(i16 %t)
276 int16_t test_revsh(int16_t t) {
277   return __revsh(t);
278 }
279 
280 // ARM-LABEL: test_rbit
281 // AArch32: call i32 @llvm.bitreverse.i32
282 // AArch64: call i32 @llvm.bitreverse.i32
283 uint32_t test_rbit(uint32_t t) {
284   return __rbit(t);
285 }
286 
287 // ARM-LABEL: test_rbitl
288 // AArch32: call i32 @llvm.bitreverse.i32
289 // AArch64: call i64 @llvm.bitreverse.i64
290 long test_rbitl(long t) {
291   return __rbitl(t);
292 }
293 
294 // ARM-LABEL: test_rbitll
295 // AArch32: call i32 @llvm.bitreverse.i32
296 // AArch32: call i32 @llvm.bitreverse.i32
297 // AArch64: call i64 @llvm.bitreverse.i64
298 uint64_t test_rbitll(uint64_t t) {
299   return __rbitll(t);
300 }
301 
302 /* 9.4 Saturating intrinsics */
303 #ifdef __ARM_FEATURE_SAT
304 /* 9.4.1 Width-specified saturation intrinsics */
305 // AArch32-LABEL: test_ssat
306 // AArch32: call i32 @llvm.arm.ssat(i32 %t, i32 1)
307 int32_t test_ssat(int32_t t) {
308   return __ssat(t, 1);
309 }
310 
311 // AArch32-LABEL: test_usat
312 // AArch32: call i32 @llvm.arm.usat(i32 %t, i32 2)
313 uint32_t test_usat(int32_t t) {
314   return __usat(t, 2);
315 }
316 #endif
317 
318 /* 9.4.2 Saturating addition and subtraction intrinsics */
319 #ifdef __ARM_FEATURE_DSP
320 // AArch32-LABEL: test_qadd
321 // AArch32: call i32 @llvm.arm.qadd(i32 %a, i32 %b)
322 int32_t test_qadd(int32_t a, int32_t b) {
323   return __qadd(a, b);
324 }
325 
326 // AArch32-LABEL: test_qsub
327 // AArch32: call i32 @llvm.arm.qsub(i32 %a, i32 %b)
328 int32_t test_qsub(int32_t a, int32_t b) {
329   return __qsub(a, b);
330 }
331 
332 extern int32_t f();
333 // AArch32-LABEL: test_qdbl
334 // AArch32: [[VAR:%[a-z0-9]+]] = {{.*}} call {{.*}} @f
335 // AArch32-NOT: call {{.*}} @f
336 // AArch32: call i32 @llvm.arm.qadd(i32 [[VAR]], i32 [[VAR]])
337 int32_t test_qdbl() {
338   return __qdbl(f());
339 }
340 #endif
341 
342 /*
343  * 9.3 16-bit multiplications
344  */
345 #if __ARM_FEATURE_DSP
346 // AArch32-LABEL: test_smulbb
347 // AArch32: call i32 @llvm.arm.smulbb
348 int32_t test_smulbb(int32_t a, int32_t b) {
349   return __smulbb(a, b);
350 }
351 // AArch32-LABEL: test_smulbt
352 // AArch32: call i32 @llvm.arm.smulbt
353 int32_t test_smulbt(int32_t a, int32_t b) {
354   return __smulbt(a, b);
355 }
356 // AArch32-LABEL: test_smultb
357 // AArch32: call i32 @llvm.arm.smultb
358 int32_t test_smultb(int32_t a, int32_t b) {
359   return __smultb(a, b);
360 }
361 // AArch32-LABEL: test_smultt
362 // AArch32: call i32 @llvm.arm.smultt
363 int32_t test_smultt(int32_t a, int32_t b) {
364   return __smultt(a, b);
365 }
366 // AArch32-LABEL: test_smulwb
367 // AArch32: call i32 @llvm.arm.smulwb
368 int32_t test_smulwb(int32_t a, int32_t b) {
369   return __smulwb(a, b);
370 }
371 // AArch32-LABEL: test_smulwt
372 // AArch32: call i32 @llvm.arm.smulwt
373 int32_t test_smulwt(int32_t a, int32_t b) {
374   return __smulwt(a, b);
375 }
376 #endif
377 
378 /* 9.4.3 Accumultating multiplications */
379 #if __ARM_FEATURE_DSP
380 // AArch32-LABEL: test_smlabb
381 // AArch32: call i32 @llvm.arm.smlabb(i32 %a, i32 %b, i32 %c)
382 int32_t test_smlabb(int32_t a, int32_t b, int32_t c) {
383   return __smlabb(a, b, c);
384 }
385 // AArch32-LABEL: test_smlabt
386 // AArch32: call i32 @llvm.arm.smlabt(i32 %a, i32 %b, i32 %c)
387 int32_t test_smlabt(int32_t a, int32_t b, int32_t c) {
388   return __smlabt(a, b, c);
389 }
390 // AArch32-LABEL: test_smlatb
391 // AArch32: call i32 @llvm.arm.smlatb(i32 %a, i32 %b, i32 %c)
392 int32_t test_smlatb(int32_t a, int32_t b, int32_t c) {
393   return __smlatb(a, b, c);
394 }
395 // AArch32-LABEL: test_smlatt
396 // AArch32: call i32 @llvm.arm.smlatt(i32 %a, i32 %b, i32 %c)
397 int32_t test_smlatt(int32_t a, int32_t b, int32_t c) {
398   return __smlatt(a, b, c);
399 }
400 // AArch32-LABEL: test_smlawb
401 // AArch32: call i32 @llvm.arm.smlawb(i32 %a, i32 %b, i32 %c)
402 int32_t test_smlawb(int32_t a, int32_t b, int32_t c) {
403   return __smlawb(a, b, c);
404 }
405 // AArch32-LABEL: test_smlawt
406 // AArch32: call i32 @llvm.arm.smlawt(i32 %a, i32 %b, i32 %c)
407 int32_t test_smlawt(int32_t a, int32_t b, int32_t c) {
408   return __smlawt(a, b, c);
409 }
410 #endif
411 
412 /* 9.5.4 Parallel 16-bit saturation */
413 #if __ARM_FEATURE_SIMD32
414 // AArch32-LABEL: test_ssat16
415 // AArch32: call i32 @llvm.arm.ssat16
416 int16x2_t test_ssat16(int16x2_t a) {
417   return __ssat16(a, 15);
418 }
419 // AArch32-LABEL: test_usat16
420 // AArch32: call i32 @llvm.arm.usat16
421 uint16x2_t test_usat16(int16x2_t a) {
422   return __usat16(a, 15);
423 }
424 #endif
425 
426 /* 9.5.5 Packing and unpacking */
427 #if __ARM_FEATURE_SIMD32
428 // AArch32-LABEL: test_sxtab16
429 // AArch32: call i32 @llvm.arm.sxtab16
430 int16x2_t test_sxtab16(int16x2_t a, int8x4_t b) {
431   return __sxtab16(a, b);
432 }
433 // AArch32-LABEL: test_sxtb16
434 // AArch32: call i32 @llvm.arm.sxtb16
435 int16x2_t test_sxtb16(int8x4_t a) {
436   return __sxtb16(a);
437 }
438 // AArch32-LABEL: test_uxtab16
439 // AArch32: call i32 @llvm.arm.uxtab16
440 int16x2_t test_uxtab16(int16x2_t a, int8x4_t b) {
441   return __uxtab16(a, b);
442 }
443 // AArch32-LABEL: test_uxtb16
444 // AArch32: call i32 @llvm.arm.uxtb16
445 int16x2_t test_uxtb16(int8x4_t a) {
446   return __uxtb16(a);
447 }
448 #endif
449 
450 /* 9.5.6 Parallel selection */
451 #if __ARM_FEATURE_SIMD32
452 // AArch32-LABEL: test_sel
453 // AArch32: call i32 @llvm.arm.sel
454 uint8x4_t test_sel(uint8x4_t a, uint8x4_t b) {
455   return __sel(a, b);
456 }
457 #endif
458 
459 /* 9.5.7 Parallel 8-bit addition and subtraction */
460 #if __ARM_FEATURE_SIMD32
461 // AArch32-LABEL: test_qadd8
462 // AArch32: call i32 @llvm.arm.qadd8
463 int16x2_t test_qadd8(int8x4_t a, int8x4_t b) {
464   return __qadd8(a, b);
465 }
466 // AArch32-LABEL: test_qsub8
467 // AArch32: call i32 @llvm.arm.qsub8
468 int8x4_t test_qsub8(int8x4_t a, int8x4_t b) {
469   return __qsub8(a, b);
470 }
471 // AArch32-LABEL: test_sadd8
472 // AArch32: call i32 @llvm.arm.sadd8
473 int8x4_t test_sadd8(int8x4_t a, int8x4_t b) {
474   return __sadd8(a, b);
475 }
476 // AArch32-LABEL: test_shadd8
477 // AArch32: call i32 @llvm.arm.shadd8
478 int8x4_t test_shadd8(int8x4_t a, int8x4_t b) {
479   return __shadd8(a, b);
480 }
481 // AArch32-LABEL: test_shsub8
482 // AArch32: call i32 @llvm.arm.shsub8
483 int8x4_t test_shsub8(int8x4_t a, int8x4_t b) {
484   return __shsub8(a, b);
485 }
486 // AArch32-LABEL: test_ssub8
487 // AArch32: call i32 @llvm.arm.ssub8
488 int8x4_t test_ssub8(int8x4_t a, int8x4_t b) {
489   return __ssub8(a, b);
490 }
491 // AArch32-LABEL: test_uadd8
492 // AArch32: call i32 @llvm.arm.uadd8
493 uint8x4_t test_uadd8(uint8x4_t a, uint8x4_t b) {
494   return __uadd8(a, b);
495 }
496 // AArch32-LABEL: test_uhadd8
497 // AArch32: call i32 @llvm.arm.uhadd8
498 uint8x4_t test_uhadd8(uint8x4_t a, uint8x4_t b) {
499   return __uhadd8(a, b);
500 }
501 // AArch32-LABEL: test_uhsub8
502 // AArch32: call i32 @llvm.arm.uhsub8
503 uint8x4_t test_uhsub8(uint8x4_t a, uint8x4_t b) {
504   return __uhsub8(a, b);
505 }
506 // AArch32-LABEL: test_uqadd8
507 // AArch32: call i32 @llvm.arm.uqadd8
508 uint8x4_t test_uqadd8(uint8x4_t a, uint8x4_t b) {
509   return __uqadd8(a, b);
510 }
511 // AArch32-LABEL: test_uqsub8
512 // AArch32: call i32 @llvm.arm.uqsub8
513 uint8x4_t test_uqsub8(uint8x4_t a, uint8x4_t b) {
514   return __uqsub8(a, b);
515 }
516 // AArch32-LABEL: test_usub8
517 // AArch32: call i32 @llvm.arm.usub8
518 uint8x4_t test_usub8(uint8x4_t a, uint8x4_t b) {
519   return __usub8(a, b);
520 }
521 #endif
522 
523 /* 9.5.8 Sum of 8-bit absolute differences */
524 #if __ARM_FEATURE_SIMD32
525 // AArch32-LABEL: test_usad8
526 // AArch32: call i32 @llvm.arm.usad8
527 uint32_t test_usad8(uint8x4_t a, uint8x4_t b) {
528   return __usad8(a, b);
529 }
530 // AArch32-LABEL: test_usada8
531 // AArch32: call i32 @llvm.arm.usada8
532 uint32_t test_usada8(uint8_t a, uint8_t b, uint8_t c) {
533   return __usada8(a, b, c);
534 }
535 #endif
536 
537 /* 9.5.9 Parallel 16-bit addition and subtraction */
538 #if __ARM_FEATURE_SIMD32
539 // AArch32-LABEL: test_qadd16
540 // AArch32: call i32 @llvm.arm.qadd16
541 int16x2_t test_qadd16(int16x2_t a, int16x2_t b) {
542   return __qadd16(a, b);
543 }
544 // AArch32-LABEL: test_qasx
545 // AArch32: call i32 @llvm.arm.qasx
546 int16x2_t test_qasx(int16x2_t a, int16x2_t b) {
547   return __qasx(a, b);
548 }
549 // AArch32-LABEL: test_qsax
550 // AArch32: call i32 @llvm.arm.qsax
551 int16x2_t test_qsax(int16x2_t a, int16x2_t b) {
552   return __qsax(a, b);
553 }
554 // AArch32-LABEL: test_qsub16
555 // AArch32: call i32 @llvm.arm.qsub16
556 int16x2_t test_qsub16(int16x2_t a, int16x2_t b) {
557   return __qsub16(a, b);
558 }
559 // AArch32-LABEL: test_sadd16
560 // AArch32: call i32 @llvm.arm.sadd16
561 int16x2_t test_sadd16(int16x2_t a, int16x2_t b) {
562   return __sadd16(a, b);
563 }
564 // AArch32-LABEL: test_sasx
565 // AArch32: call i32 @llvm.arm.sasx
566 int16x2_t test_sasx(int16x2_t a, int16x2_t b) {
567   return __sasx(a, b);
568 }
569 // AArch32-LABEL: test_shadd16
570 // AArch32: call i32 @llvm.arm.shadd16
571 int16x2_t test_shadd16(int16x2_t a, int16x2_t b) {
572   return __shadd16(a, b);
573 }
574 // AArch32-LABEL: test_shasx
575 // AArch32: call i32 @llvm.arm.shasx
576 int16x2_t test_shasx(int16x2_t a, int16x2_t b) {
577   return __shasx(a, b);
578 }
579 // AArch32-LABEL: test_shsax
580 // AArch32: call i32 @llvm.arm.shsax
581 int16x2_t test_shsax(int16x2_t a, int16x2_t b) {
582   return __shsax(a, b);
583 }
584 // AArch32-LABEL: test_shsub16
585 // AArch32: call i32 @llvm.arm.shsub16
586 int16x2_t test_shsub16(int16x2_t a, int16x2_t b) {
587   return __shsub16(a, b);
588 }
589 // AArch32-LABEL: test_ssax
590 // AArch32: call i32 @llvm.arm.ssax
591 int16x2_t test_ssax(int16x2_t a, int16x2_t b) {
592   return __ssax(a, b);
593 }
594 // AArch32-LABEL: test_ssub16
595 // AArch32: call i32 @llvm.arm.ssub16
596 int16x2_t test_ssub16(int16x2_t a, int16x2_t b) {
597   return __ssub16(a, b);
598 }
599 // AArch32-LABEL: test_uadd16
600 // AArch32: call i32 @llvm.arm.uadd16
601 uint16x2_t test_uadd16(uint16x2_t a, uint16x2_t b) {
602   return __uadd16(a, b);
603 }
604 // AArch32-LABEL: test_uasx
605 // AArch32: call i32 @llvm.arm.uasx
606 uint16x2_t test_uasx(uint16x2_t a, uint16x2_t b) {
607   return __uasx(a, b);
608 }
609 // AArch32-LABEL: test_uhadd16
610 // AArch32: call i32 @llvm.arm.uhadd16
611 uint16x2_t test_uhadd16(uint16x2_t a, uint16x2_t b) {
612   return __uhadd16(a, b);
613 }
614 // AArch32-LABEL: test_uhasx
615 // AArch32: call i32 @llvm.arm.uhasx
616 uint16x2_t test_uhasx(uint16x2_t a, uint16x2_t b) {
617   return __uhasx(a, b);
618 }
619 // AArch32-LABEL: test_uhsax
620 // AArch32: call i32 @llvm.arm.uhsax
621 uint16x2_t test_uhsax(uint16x2_t a, uint16x2_t b) {
622   return __uhsax(a, b);
623 }
624 // AArch32-LABEL: test_uhsub16
625 // AArch32: call i32 @llvm.arm.uhsub16
626 uint16x2_t test_uhsub16(uint16x2_t a, uint16x2_t b) {
627   return __uhsub16(a, b);
628 }
629 // AArch32-LABEL: test_uqadd16
630 // AArch32: call i32 @llvm.arm.uqadd16
631 uint16x2_t test_uqadd16(uint16x2_t a, uint16x2_t b) {
632   return __uqadd16(a, b);
633 }
634 // AArch32-LABEL: test_uqasx
635 // AArch32: call i32 @llvm.arm.uqasx
636 uint16x2_t test_uqasx(uint16x2_t a, uint16x2_t b) {
637   return __uqasx(a, b);
638 }
639 // AArch32-LABEL: test_uqsax
640 // AArch32: call i32 @llvm.arm.uqsax
641 uint16x2_t test_uqsax(uint16x2_t a, uint16x2_t b) {
642   return __uqsax(a, b);
643 }
644 // AArch32-LABEL: test_uqsub16
645 // AArch32: call i32 @llvm.arm.uqsub16
646 uint16x2_t test_uqsub16(uint16x2_t a, uint16x2_t b) {
647   return __uqsub16(a, b);
648 }
649 // AArch32-LABEL: test_usax
650 // AArch32: call i32 @llvm.arm.usax
651 uint16x2_t test_usax(uint16x2_t a, uint16x2_t b) {
652   return __usax(a, b);
653 }
654 // AArch32-LABEL: test_usub16
655 // AArch32: call i32 @llvm.arm.usub16
656 uint16x2_t test_usub16(uint16x2_t a, uint16x2_t b) {
657   return __usub16(a, b);
658 }
659 #endif
660 
661 /* 9.5.10 Parallel 16-bit multiplications */
662 #if __ARM_FEATURE_SIMD32
663 // AArch32-LABEL: test_smlad
664 // AArch32: call i32 @llvm.arm.smlad
665 int32_t test_smlad(int16x2_t a, int16x2_t b, int32_t c) {
666   return __smlad(a, b, c);
667 }
668 // AArch32-LABEL: test_smladx
669 // AArch32: call i32 @llvm.arm.smladx
670 int32_t test_smladx(int16x2_t a, int16x2_t b, int32_t c) {
671   return __smladx(a, b, c);
672 }
673 // AArch32-LABEL: test_smlald
674 // AArch32: call i64 @llvm.arm.smlald
675 int64_t test_smlald(int16x2_t a, int16x2_t b, int64_t c) {
676   return __smlald(a, b, c);
677 }
678 // AArch32-LABEL: test_smlaldx
679 // AArch32: call i64 @llvm.arm.smlaldx
680 int64_t test_smlaldx(int16x2_t a, int16x2_t b, int64_t c) {
681   return __smlaldx(a, b, c);
682 }
683 // AArch32-LABEL: test_smlsd
684 // AArch32: call i32 @llvm.arm.smlsd
685 int32_t test_smlsd(int16x2_t a, int16x2_t b, int32_t c) {
686   return __smlsd(a, b, c);
687 }
688 // AArch32-LABEL: test_smlsdx
689 // AArch32: call i32 @llvm.arm.smlsdx
690 int32_t test_smlsdx(int16x2_t a, int16x2_t b, int32_t c) {
691   return __smlsdx(a, b, c);
692 }
693 // AArch32-LABEL: test_smlsld
694 // AArch32: call i64 @llvm.arm.smlsld
695 int64_t test_smlsld(int16x2_t a, int16x2_t b, int64_t c) {
696   return __smlsld(a, b, c);
697 }
698 // AArch32-LABEL: test_smlsldx
699 // AArch32: call i64 @llvm.arm.smlsldx
700 int64_t test_smlsldx(int16x2_t a, int16x2_t b, int64_t c) {
701   return __smlsldx(a, b, c);
702 }
703 // AArch32-LABEL: test_smuad
704 // AArch32: call i32 @llvm.arm.smuad
705 int32_t test_smuad(int16x2_t a, int16x2_t b) {
706   return __smuad(a, b);
707 }
708 // AArch32-LABEL: test_smuadx
709 // AArch32: call i32 @llvm.arm.smuadx
710 int32_t test_smuadx(int16x2_t a, int16x2_t b) {
711   return __smuadx(a, b);
712 }
713 // AArch32-LABEL: test_smusd
714 // AArch32: call i32 @llvm.arm.smusd
715 int32_t test_smusd(int16x2_t a, int16x2_t b) {
716   return __smusd(a, b);
717 }
718 // AArch32-LABEL: test_smusdx
719 // AArch32: call i32 @llvm.arm.smusdx
720 int32_t test_smusdx(int16x2_t a, int16x2_t b) {
721   return __smusdx(a, b);
722 }
723 #endif
724 
725 /* 9.7 CRC32 intrinsics */
726 // ARM-LABEL: test_crc32b
727 // AArch32: call i32 @llvm.arm.crc32b
728 // AArch64: call i32 @llvm.aarch64.crc32b
729 uint32_t test_crc32b(uint32_t a, uint8_t b) {
730   return __crc32b(a, b);
731 }
732 
733 // ARM-LABEL: test_crc32h
734 // AArch32: call i32 @llvm.arm.crc32h
735 // AArch64: call i32 @llvm.aarch64.crc32h
736 uint32_t test_crc32h(uint32_t a, uint16_t b) {
737   return __crc32h(a, b);
738 }
739 
740 // ARM-LABEL: test_crc32w
741 // AArch32: call i32 @llvm.arm.crc32w
742 // AArch64: call i32 @llvm.aarch64.crc32w
743 uint32_t test_crc32w(uint32_t a, uint32_t b) {
744   return __crc32w(a, b);
745 }
746 
747 // ARM-LABEL: test_crc32d
748 // AArch32: call i32 @llvm.arm.crc32w
749 // AArch32: call i32 @llvm.arm.crc32w
750 // AArch64: call i32 @llvm.aarch64.crc32x
751 uint32_t test_crc32d(uint32_t a, uint64_t b) {
752   return __crc32d(a, b);
753 }
754 
755 // ARM-LABEL: test_crc32cb
756 // AArch32: call i32 @llvm.arm.crc32cb
757 // AArch64: call i32 @llvm.aarch64.crc32cb
758 uint32_t test_crc32cb(uint32_t a, uint8_t b) {
759   return __crc32cb(a, b);
760 }
761 
762 // ARM-LABEL: test_crc32ch
763 // AArch32: call i32 @llvm.arm.crc32ch
764 // AArch64: call i32 @llvm.aarch64.crc32ch
765 uint32_t test_crc32ch(uint32_t a, uint16_t b) {
766   return __crc32ch(a, b);
767 }
768 
769 // ARM-LABEL: test_crc32cw
770 // AArch32: call i32 @llvm.arm.crc32cw
771 // AArch64: call i32 @llvm.aarch64.crc32cw
772 uint32_t test_crc32cw(uint32_t a, uint32_t b) {
773   return __crc32cw(a, b);
774 }
775 
776 // ARM-LABEL: test_crc32cd
777 // AArch32: call i32 @llvm.arm.crc32cw
778 // AArch32: call i32 @llvm.arm.crc32cw
779 // AArch64: call i32 @llvm.aarch64.crc32cx
780 uint32_t test_crc32cd(uint32_t a, uint64_t b) {
781   return __crc32cd(a, b);
782 }
783 
784 /* 10.1 Special register intrinsics */
785 // ARM-LABEL: test_rsr
786 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]])
787 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M2:[0-9]]])
788 uint32_t test_rsr() {
789 #ifdef __ARM_32BIT_STATE
790   return __arm_rsr("cp1:2:c3:c4:5");
791 #else
792   return __arm_rsr("1:2:3:4:5");
793 #endif
794 }
795 
796 // ARM-LABEL: test_rsr64
797 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]])
798 // AArch32: call i64 @llvm.read_register.i64(metadata ![[M3:[0-9]]])
799 uint64_t test_rsr64() {
800 #ifdef __ARM_32BIT_STATE
801   return __arm_rsr64("cp1:2:c3");
802 #else
803   return __arm_rsr64("1:2:3:4:5");
804 #endif
805 }
806 
807 // ARM-LABEL: test_rsrp
808 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M1:[0-9]]])
809 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M4:[0-9]]])
810 void *test_rsrp() {
811   return __arm_rsrp("sysreg");
812 }
813 
814 // ARM-LABEL: test_wsr
815 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}})
816 // AArch32: call void @llvm.write_register.i32(metadata ![[M2:[0-9]]], i32 %{{.*}})
817 void test_wsr(uint32_t v) {
818 #ifdef __ARM_32BIT_STATE
819   __arm_wsr("cp1:2:c3:c4:5", v);
820 #else
821   __arm_wsr("1:2:3:4:5", v);
822 #endif
823 }
824 
825 // ARM-LABEL: test_wsr64
826 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}})
827 // AArch32: call void @llvm.write_register.i64(metadata ![[M3:[0-9]]], i64 %{{.*}})
828 void test_wsr64(uint64_t v) {
829 #ifdef __ARM_32BIT_STATE
830   __arm_wsr64("cp1:2:c3", v);
831 #else
832   __arm_wsr64("1:2:3:4:5", v);
833 #endif
834 }
835 
836 // ARM-LABEL: test_wsrp
837 // AArch64: call void @llvm.write_register.i64(metadata ![[M1:[0-9]]], i64 %{{.*}})
838 // AArch32: call void @llvm.write_register.i32(metadata ![[M4:[0-9]]], i32 %{{.*}})
839 void test_wsrp(void *v) {
840   __arm_wsrp("sysreg", v);
841 }
842 
843 // ARM-LABEL: test_rsrf
844 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]])
845 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M2:[0-9]]])
846 // ARM-NOT: uitofp
847 // ARM: bitcast
848 float test_rsrf() {
849 #ifdef __ARM_32BIT_STATE
850   return __arm_rsrf("cp1:2:c3:c4:5");
851 #else
852   return __arm_rsrf("1:2:3:4:5");
853 #endif
854 }
855 // ARM-LABEL: test_rsrf64
856 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]])
857 // AArch32: call i64 @llvm.read_register.i64(metadata ![[M3:[0-9]]])
858 // ARM-NOT: uitofp
859 // ARM: bitcast
860 double test_rsrf64() {
861 #ifdef __ARM_32BIT_STATE
862   return __arm_rsrf64("cp1:2:c3");
863 #else
864   return __arm_rsrf64("1:2:3:4:5");
865 #endif
866 }
867 // ARM-LABEL: test_wsrf
868 // ARM-NOT: fptoui
869 // ARM: bitcast
870 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}})
871 // AArch32: call void @llvm.write_register.i32(metadata ![[M2:[0-9]]], i32 %{{.*}})
872 void test_wsrf(float v) {
873 #ifdef __ARM_32BIT_STATE
874   __arm_wsrf("cp1:2:c3:c4:5", v);
875 #else
876   __arm_wsrf("1:2:3:4:5", v);
877 #endif
878 }
879 // ARM-LABEL: test_wsrf64
880 // ARM-NOT: fptoui
881 // ARM: bitcast
882 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}})
883 // AArch32: call void @llvm.write_register.i64(metadata ![[M3:[0-9]]], i64 %{{.*}})
884 void test_wsrf64(double v) {
885 #ifdef __ARM_32BIT_STATE
886   __arm_wsrf64("cp1:2:c3", v);
887 #else
888   __arm_wsrf64("1:2:3:4:5", v);
889 #endif
890 }
891 
892 // AArch32: ![[M2]] = !{!"cp1:2:c3:c4:5"}
893 // AArch32: ![[M3]] = !{!"cp1:2:c3"}
894 // AArch32: ![[M4]] = !{!"sysreg"}
895 
896 // AArch64: ![[M0]] = !{!"1:2:3:4:5"}
897 // AArch64: ![[M1]] = !{!"sysreg"}
898 
899 // AArch64-v8_3-LABEL: @test_jcvt(
900 // AArch64-v8_3: call i32 @llvm.aarch64.fjcvtzs
901 #ifdef __ARM_64BIT_STATE
902 int32_t test_jcvt(double v) {
903   return __jcvt(v);
904 }
905 #endif
906