1 // RUN: %clang_cc1 -ffreestanding -triple armv8-eabi -target-cpu cortex-a57 -O -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch32
2 // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +neon -target-feature +crc -target-feature +crypto -O -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch64
6 /* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
7 /* 8.3 Memory Barriers */
9 // AArch32: call void @llvm.arm.dmb(i32 1)
10 // AArch64: call void @llvm.aarch64.dmb(i32 1)
15 // ARM-LABEL: test_dsb
16 // AArch32: call void @llvm.arm.dsb(i32 2)
17 // AArch64: call void @llvm.aarch64.dsb(i32 2)
22 // ARM-LABEL: test_isb
23 // AArch32: call void @llvm.arm.isb(i32 3)
24 // AArch64: call void @llvm.aarch64.isb(i32 3)
30 // ARM-LABEL: test_yield
31 // AArch32: call void @llvm.arm.hint(i32 1)
32 // AArch64: call void @llvm.aarch64.hint(i32 1)
33 void test_yield(void) {
37 // ARM-LABEL: test_wfe
38 // AArch32: call void @llvm.arm.hint(i32 2)
39 // AArch64: call void @llvm.aarch64.hint(i32 2)
44 // ARM-LABEL: test_wfi
45 // AArch32: call void @llvm.arm.hint(i32 3)
46 // AArch64: call void @llvm.aarch64.hint(i32 3)
51 // ARM-LABEL: test_sev
52 // AArch32: call void @llvm.arm.hint(i32 4)
53 // AArch64: call void @llvm.aarch64.hint(i32 4)
58 // ARM-LABEL: test_sevl
59 // AArch32: call void @llvm.arm.hint(i32 5)
60 // AArch64: call void @llvm.aarch64.hint(i32 5)
61 void test_sevl(void) {
66 // AArch32-LABEL: test_dbg
67 // AArch32: call void @llvm.arm.dbg(i32 0)
74 // ARM-LABEL: test_swp
75 // AArch32: call i32 @llvm.arm.ldrex
76 // AArch32: call i32 @llvm.arm.strex
77 // AArch64: call i64 @llvm.aarch64.ldxr
78 // AArch64: call i32 @llvm.aarch64.stxr
79 uint32_t test_swp(uint32_t x, volatile void *p) {
83 /* 8.6 Memory prefetch intrinsics */
84 /* 8.6.1 Data prefetch */
85 // ARM-LABEL: test_pld
86 // ARM: call void @llvm.prefetch(i8* null, i32 0, i32 3, i32 1)
91 // ARM-LABEL: test_pldx
92 // AArch32: call void @llvm.prefetch(i8* null, i32 1, i32 3, i32 1)
93 // AArch64: call void @llvm.prefetch(i8* null, i32 1, i32 1, i32 1)
98 /* 8.6.2 Instruction prefetch */
99 // ARM-LABEL: test_pli
100 // ARM: call void @llvm.prefetch(i8* null, i32 0, i32 3, i32 0)
105 // ARM-LABEL: test_plix
106 // AArch32: call void @llvm.prefetch(i8* null, i32 0, i32 3, i32 0)
107 // AArch64: call void @llvm.prefetch(i8* null, i32 0, i32 1, i32 0)
113 // ARM-LABEL: test_nop
114 // AArch32: call void @llvm.arm.hint(i32 0)
115 // AArch64: call void @llvm.aarch64.hint(i32 0)
116 void test_nop(void) {
120 /* 9 DATA-PROCESSING INTRINSICS */
121 /* 9.2 Miscellaneous data-processing intrinsics */
122 // ARM-LABEL: test_ror
127 uint32_t test_ror(uint32_t x, uint32_t y) {
131 // ARM-LABEL: test_rorl
136 unsigned long test_rorl(unsigned long x, uint32_t y) {
140 // ARM-LABEL: test_rorll
145 uint64_t test_rorll(uint64_t x, uint32_t y) {
146 return __rorll(x, y);
149 // ARM-LABEL: test_clz
150 // ARM: call i32 @llvm.ctlz.i32(i32 %t, i1 false)
151 uint32_t test_clz(uint32_t t) {
155 // ARM-LABEL: test_clzl
156 // AArch32: call i32 @llvm.ctlz.i32(i32 %t, i1 false)
157 // AArch64: call i64 @llvm.ctlz.i64(i64 %t, i1 false)
158 long test_clzl(long t) {
162 // ARM-LABEL: test_clzll
163 // ARM: call i64 @llvm.ctlz.i64(i64 %t, i1 false)
164 uint64_t test_clzll(uint64_t t) {
168 // ARM-LABEL: test_rev
169 // ARM: call i32 @llvm.bswap.i32(i32 %t)
170 uint32_t test_rev(uint32_t t) {
174 // ARM-LABEL: test_revl
175 // AArch32: call i32 @llvm.bswap.i32(i32 %t)
176 // AArch64: call i64 @llvm.bswap.i64(i64 %t)
177 long test_revl(long t) {
181 // ARM-LABEL: test_revll
182 // ARM: call i64 @llvm.bswap.i64(i64 %t)
183 uint64_t test_revll(uint64_t t) {
187 // ARM-LABEL: test_rev16
189 // ARM: lshr {{.*}}, 16
190 // ARM: shl {{.*}}, 16
192 uint32_t test_rev16(uint32_t t) {
196 // ARM-LABEL: test_rev16l
197 // AArch32: llvm.bswap
198 // AArch32: lshr {{.*}}, 16
199 // AArch32: shl {{.*}}, 16
201 // AArch64: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32
202 // AArch64: [[T2:%.*]] = trunc i64 [[T1]] to i32
203 // AArch64: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]])
204 // AArch64: [[T4:%.*]] = lshr i32 [[T3]], 16
205 // AArch64: [[T5:%.*]] = shl i32 [[T3]], 16
206 // AArch64: [[T6:%.*]] = or i32 [[T5]], [[T4]]
207 // AArch64: [[T7:%.*]] = zext i32 [[T6]] to i64
208 // AArch64: [[T8:%.*]] = shl nuw i64 [[T7]], 32
209 // AArch64: [[T9:%.*]] = trunc i64 [[IN]] to i32
210 // AArch64: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]])
211 // AArch64: [[T11:%.*]] = lshr i32 [[T10]], 16
212 // AArch64: [[T12:%.*]] = shl i32 [[T10]], 16
213 // AArch64: [[T13:%.*]] = or i32 [[T12]], [[T11]]
214 // AArch64: [[T14:%.*]] = zext i32 [[T13]] to i64
215 // AArch64: [[T15:%.*]] = or i64 [[T8]], [[T14]]
216 long test_rev16l(long t) {
220 // ARM-LABEL: test_rev16ll
221 // ARM: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32
222 // ARM: [[T2:%.*]] = trunc i64 [[T1]] to i32
223 // ARM: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]])
224 // ARM: [[T4:%.*]] = lshr i32 [[T3]], 16
225 // ARM: [[T5:%.*]] = shl i32 [[T3]], 16
226 // ARM: [[T6:%.*]] = or i32 [[T5]], [[T4]]
227 // ARM: [[T7:%.*]] = zext i32 [[T6]] to i64
228 // ARM: [[T8:%.*]] = shl nuw i64 [[T7]], 32
229 // ARM: [[T9:%.*]] = trunc i64 [[IN]] to i32
230 // ARM: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]])
231 // ARM: [[T11:%.*]] = lshr i32 [[T10]], 16
232 // ARM: [[T12:%.*]] = shl i32 [[T10]], 16
233 // ARM: [[T13:%.*]] = or i32 [[T12]], [[T11]]
234 // ARM: [[T14:%.*]] = zext i32 [[T13]] to i64
235 // ARM: [[T15:%.*]] = or i64 [[T8]], [[T14]]
236 uint64_t test_rev16ll(uint64_t t) {
240 // ARM-LABEL: test_revsh
241 // ARM: call i16 @llvm.bswap.i16(i16 %t)
242 int16_t test_revsh(int16_t t) {
246 // ARM-LABEL: test_rbit
247 // AArch32: call i32 @llvm.arm.rbit
248 // AArch64: call i32 @llvm.aarch64.rbit.i32
249 uint32_t test_rbit(uint32_t t) {
253 // ARM-LABEL: test_rbitl
254 // AArch32: call i32 @llvm.arm.rbit
255 // AArch64: call i64 @llvm.aarch64.rbit.i64
256 long test_rbitl(long t) {
260 // ARM-LABEL: test_rbitll
261 // AArch32: call i32 @llvm.arm.rbit
262 // AArch32: call i32 @llvm.arm.rbit
263 // AArch64: call i64 @llvm.aarch64.rbit.i64
264 uint64_t test_rbitll(uint64_t t) {
268 /* 9.4 Saturating intrinsics */
269 #ifdef __ARM_32BIT_STATE
271 /* 9.4.1 Width-specified saturation intrinsics */
272 // AArch32-LABEL: test_ssat
273 // AArch32: call i32 @llvm.arm.ssat(i32 %t, i32 1)
274 int32_t test_ssat(int32_t t) {
278 // AArch32-LABEL: test_usat
279 // AArch32: call i32 @llvm.arm.usat(i32 %t, i32 2)
280 int32_t test_usat(int32_t t) {
284 /* 9.4.2 Saturating addition and subtraction intrinsics */
285 // AArch32-LABEL: test_qadd
286 // AArch32: call i32 @llvm.arm.qadd(i32 %a, i32 %b)
287 int32_t test_qadd(int32_t a, int32_t b) {
291 // AArch32-LABEL: test_qsub
292 // AArch32: call i32 @llvm.arm.qsub(i32 %a, i32 %b)
293 int32_t test_qsub(int32_t a, int32_t b) {
298 // AArch32-LABEL: test_qdbl
299 // AArch32: [[VAR:%[a-z0-9]+]] = {{.*}} call {{.*}} @f
300 // AArch32-NOT: call {{.*}} @f
301 // AArch32: call i32 @llvm.arm.qadd(i32 [[VAR]], i32 [[VAR]])
302 int32_t test_qdbl() {
307 /* 9.7 CRC32 intrinsics */
308 // ARM-LABEL: test_crc32b
309 // AArch32: call i32 @llvm.arm.crc32b
310 // AArch64: call i32 @llvm.aarch64.crc32b
311 uint32_t test_crc32b(uint32_t a, uint8_t b) {
312 return __crc32b(a, b);
315 // ARM-LABEL: test_crc32h
316 // AArch32: call i32 @llvm.arm.crc32h
317 // AArch64: call i32 @llvm.aarch64.crc32h
318 uint32_t test_crc32h(uint32_t a, uint16_t b) {
319 return __crc32h(a, b);
322 // ARM-LABEL: test_crc32w
323 // AArch32: call i32 @llvm.arm.crc32w
324 // AArch64: call i32 @llvm.aarch64.crc32w
325 uint32_t test_crc32w(uint32_t a, uint32_t b) {
326 return __crc32w(a, b);
329 // ARM-LABEL: test_crc32d
330 // AArch32: call i32 @llvm.arm.crc32w
331 // AArch32: call i32 @llvm.arm.crc32w
332 // AArch64: call i32 @llvm.aarch64.crc32x
333 uint32_t test_crc32d(uint32_t a, uint64_t b) {
334 return __crc32d(a, b);
337 // ARM-LABEL: test_crc32cb
338 // AArch32: call i32 @llvm.arm.crc32cb
339 // AArch64: call i32 @llvm.aarch64.crc32cb
340 uint32_t test_crc32cb(uint32_t a, uint8_t b) {
341 return __crc32cb(a, b);
344 // ARM-LABEL: test_crc32ch
345 // AArch32: call i32 @llvm.arm.crc32ch
346 // AArch64: call i32 @llvm.aarch64.crc32ch
347 uint32_t test_crc32ch(uint32_t a, uint16_t b) {
348 return __crc32ch(a, b);
351 // ARM-LABEL: test_crc32cw
352 // AArch32: call i32 @llvm.arm.crc32cw
353 // AArch64: call i32 @llvm.aarch64.crc32cw
354 uint32_t test_crc32cw(uint32_t a, uint32_t b) {
355 return __crc32cw(a, b);
358 // ARM-LABEL: test_crc32cd
359 // AArch32: call i32 @llvm.arm.crc32cw
360 // AArch32: call i32 @llvm.arm.crc32cw
361 // AArch64: call i32 @llvm.aarch64.crc32cx
362 uint32_t test_crc32cd(uint32_t a, uint64_t b) {
363 return __crc32cd(a, b);
366 /* 10.1 Special register intrinsics */
367 // ARM-LABEL: test_rsr
368 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]])
369 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M2:[0-9]]])
370 uint32_t test_rsr() {
371 #ifdef __ARM_32BIT_STATE
372 return __arm_rsr("cp1:2:c3:c4:5");
374 return __arm_rsr("1:2:3:4:5");
378 // ARM-LABEL: test_rsr64
379 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]])
380 // AArch32: call i64 @llvm.read_register.i64(metadata ![[M3:[0-9]]])
381 uint64_t test_rsr64() {
382 #ifdef __ARM_32BIT_STATE
383 return __arm_rsr64("cp1:2:c3");
385 return __arm_rsr64("1:2:3:4:5");
389 // ARM-LABEL: test_rsrp
390 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M1:[0-9]]])
391 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M4:[0-9]]])
393 return __arm_rsrp("sysreg");
396 // ARM-LABEL: test_wsr
397 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}})
398 // AArch32: call void @llvm.write_register.i32(metadata ![[M2:[0-9]]], i32 %{{.*}})
399 void test_wsr(uint32_t v) {
400 #ifdef __ARM_32BIT_STATE
401 __arm_wsr("cp1:2:c3:c4:5", v);
403 __arm_wsr("1:2:3:4:5", v);
407 // ARM-LABEL: test_wsr64
408 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}})
409 // AArch32: call void @llvm.write_register.i64(metadata ![[M3:[0-9]]], i64 %{{.*}})
410 void test_wsr64(uint64_t v) {
411 #ifdef __ARM_32BIT_STATE
412 __arm_wsr64("cp1:2:c3", v);
414 __arm_wsr64("1:2:3:4:5", v);
418 // ARM-LABEL: test_wsrp
419 // AArch64: call void @llvm.write_register.i64(metadata ![[M1:[0-9]]], i64 %{{.*}})
420 // AArch32: call void @llvm.write_register.i32(metadata ![[M4:[0-9]]], i32 %{{.*}})
421 void test_wsrp(void *v) {
422 __arm_wsrp("sysreg", v);
425 // AArch32: ![[M2]] = !{!"cp1:2:c3:c4:5"}
426 // AArch32: ![[M3]] = !{!"cp1:2:c3"}
427 // AArch32: ![[M4]] = !{!"sysreg"}
429 // AArch64: ![[M0]] = !{!"1:2:3:4:5"}
430 // AArch64: ![[M1]] = !{!"sysreg"}