1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // RUN: %clang_cc1 -ffreestanding -triple armv8a-none-eabi -target-feature +crc -target-feature +dsp -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch32
3 // RUN: %clang_cc1 -ffreestanding -Wno-error=implicit-function-declaration -triple aarch64-none-elf -target-feature +neon -target-feature +crc -target-feature +crypto -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch64
4 // RUN: %clang_cc1 -ffreestanding -triple aarch64-none-elf -target-feature +v8.3a -target-feature +crc -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch64,AArch6483
5 // RUN: %clang_cc1 -ffreestanding -triple aarch64-none-elf -target-feature +v8.5a -target-feature +crc -target-feature +rand -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch64,AArch6483,AArch6485
6 // RUN: %clang_cc1 -ffreestanding -triple aarch64-none-elf -target-feature +v9.4a -target-feature +crc -target-feature +rand -target-feature +d128 -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch64,AArch6483,AArch6485,AArch6494D128
11 // REQUIRES: arm-registered-target,aarch64-registered-target
13 /* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
14 /* 8.3 Memory Barriers */
16 // AArch32-LABEL: @test_dmb(
17 // AArch32-NEXT: entry:
18 // AArch32-NEXT: call void @llvm.arm.dmb(i32 1)
19 // AArch32-NEXT: ret void
21 // AArch64-LABEL: @test_dmb(
22 // AArch64-NEXT: entry:
23 // AArch64-NEXT: call void @llvm.aarch64.dmb(i32 1)
24 // AArch64-NEXT: ret void
30 // AArch32-LABEL: @test_dsb(
31 // AArch32-NEXT: entry:
32 // AArch32-NEXT: call void @llvm.arm.dsb(i32 2)
33 // AArch32-NEXT: ret void
35 // AArch64-LABEL: @test_dsb(
36 // AArch64-NEXT: entry:
37 // AArch64-NEXT: call void @llvm.aarch64.dsb(i32 2)
38 // AArch64-NEXT: ret void
44 // AArch32-LABEL: @test_isb(
45 // AArch32-NEXT: entry:
46 // AArch32-NEXT: call void @llvm.arm.isb(i32 3)
47 // AArch32-NEXT: ret void
49 // AArch64-LABEL: @test_isb(
50 // AArch64-NEXT: entry:
51 // AArch64-NEXT: call void @llvm.aarch64.isb(i32 3)
52 // AArch64-NEXT: ret void
59 // AArch32-LABEL: @test_yield(
60 // AArch32-NEXT: entry:
61 // AArch32-NEXT: call void @llvm.arm.hint(i32 1)
62 // AArch32-NEXT: ret void
64 // AArch64-LABEL: @test_yield(
65 // AArch64-NEXT: entry:
66 // AArch64-NEXT: call void @llvm.aarch64.hint(i32 1)
67 // AArch64-NEXT: ret void
69 void test_yield(void) {
73 // AArch32-LABEL: @test_wfe(
74 // AArch32-NEXT: entry:
75 // AArch32-NEXT: call void @llvm.arm.hint(i32 2)
76 // AArch32-NEXT: ret void
78 // AArch64-LABEL: @test_wfe(
79 // AArch64-NEXT: entry:
80 // AArch64-NEXT: call void @llvm.aarch64.hint(i32 2)
81 // AArch64-NEXT: ret void
87 // AArch32-LABEL: @test_wfi(
88 // AArch32-NEXT: entry:
89 // AArch32-NEXT: call void @llvm.arm.hint(i32 3)
90 // AArch32-NEXT: ret void
92 // AArch64-LABEL: @test_wfi(
93 // AArch64-NEXT: entry:
94 // AArch64-NEXT: call void @llvm.aarch64.hint(i32 3)
95 // AArch64-NEXT: ret void
101 // AArch32-LABEL: @test_sev(
102 // AArch32-NEXT: entry:
103 // AArch32-NEXT: call void @llvm.arm.hint(i32 4)
104 // AArch32-NEXT: ret void
106 // AArch64-LABEL: @test_sev(
107 // AArch64-NEXT: entry:
108 // AArch64-NEXT: call void @llvm.aarch64.hint(i32 4)
109 // AArch64-NEXT: ret void
111 void test_sev(void) {
115 // AArch32-LABEL: @test_sevl(
116 // AArch32-NEXT: entry:
117 // AArch32-NEXT: call void @llvm.arm.hint(i32 5)
118 // AArch32-NEXT: ret void
120 // AArch64-LABEL: @test_sevl(
121 // AArch64-NEXT: entry:
122 // AArch64-NEXT: call void @llvm.aarch64.hint(i32 5)
123 // AArch64-NEXT: ret void
125 void test_sevl(void) {
129 #ifdef __ARM_32BIT_STATE
130 // AArch32-LABEL: @test_dbg(
131 // AArch32-NEXT: entry:
132 // AArch32-NEXT: call void @llvm.arm.dbg(i32 0)
133 // AArch32-NEXT: ret void
135 void test_dbg(void) {
141 // AArch32-LABEL: @test_swp(
142 // AArch32-NEXT: entry:
143 // AArch32-NEXT: br label [[DO_BODY_I:%.*]]
144 // AArch32: do.body.i:
145 // AArch32-NEXT: [[LDREX_I:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[P:%.*]])
146 // AArch32-NEXT: [[STREX_I:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[X:%.*]], ptr elementtype(i32) [[P]])
147 // AArch32-NEXT: [[TOBOOL_I:%.*]] = icmp ne i32 [[STREX_I]], 0
148 // AArch32-NEXT: br i1 [[TOBOOL_I]], label [[DO_BODY_I]], label [[__SWP_EXIT:%.*]], !llvm.loop [[LOOP3:![0-9]+]]
149 // AArch32: __swp.exit:
150 // AArch32-NEXT: ret void
152 // AArch64-LABEL: @test_swp(
153 // AArch64-NEXT: entry:
154 // AArch64-NEXT: br label [[DO_BODY_I:%.*]]
155 // AArch64: do.body.i:
156 // AArch64-NEXT: [[LDXR_I:%.*]] = call i64 @llvm.aarch64.ldxr.p0(ptr elementtype(i32) [[P:%.*]])
157 // AArch64-NEXT: [[TMP0:%.*]] = trunc i64 [[LDXR_I]] to i32
158 // AArch64-NEXT: [[TMP1:%.*]] = zext i32 [[X:%.*]] to i64
159 // AArch64-NEXT: [[STXR_I:%.*]] = call i32 @llvm.aarch64.stxr.p0(i64 [[TMP1]], ptr elementtype(i32) [[P]])
160 // AArch64-NEXT: [[TOBOOL_I:%.*]] = icmp ne i32 [[STXR_I]], 0
161 // AArch64-NEXT: br i1 [[TOBOOL_I]], label [[DO_BODY_I]], label [[__SWP_EXIT:%.*]], !llvm.loop [[LOOP2:![0-9]+]]
162 // AArch64: __swp.exit:
163 // AArch64-NEXT: ret void
165 void test_swp(uint32_t x
, volatile void *p
) {
169 /* 8.6 Memory prefetch intrinsics */
170 /* 8.6.1 Data prefetch */
171 // AArch32-LABEL: @test_pld(
172 // AArch32-NEXT: entry:
173 // AArch32-NEXT: call void @llvm.prefetch.p0(ptr null, i32 0, i32 3, i32 1)
174 // AArch32-NEXT: ret void
176 // AArch64-LABEL: @test_pld(
177 // AArch64-NEXT: entry:
178 // AArch64-NEXT: call void @llvm.aarch64.prefetch(ptr null, i32 0, i32 0, i32 0, i32 1)
179 // AArch64-NEXT: ret void
185 // AArch32-LABEL: @test_pldx(
186 // AArch32-NEXT: entry:
187 // AArch32-NEXT: call void @llvm.prefetch.p0(ptr null, i32 1, i32 3, i32 1)
188 // AArch32-NEXT: ret void
190 // AArch64-LABEL: @test_pldx(
191 // AArch64-NEXT: entry:
192 // AArch64-NEXT: call void @llvm.aarch64.prefetch(ptr null, i32 1, i32 2, i32 0, i32 1)
193 // AArch64-NEXT: ret void
199 /* 8.6.2 Instruction prefetch */
200 // AArch32-LABEL: @test_pli(
201 // AArch32-NEXT: entry:
202 // AArch32-NEXT: call void @llvm.prefetch.p0(ptr null, i32 0, i32 3, i32 0)
203 // AArch32-NEXT: ret void
205 // AArch64-LABEL: @test_pli(
206 // AArch64-NEXT: entry:
207 // AArch64-NEXT: call void @llvm.aarch64.prefetch(ptr null, i32 0, i32 0, i32 0, i32 0)
208 // AArch64-NEXT: ret void
214 // AArch32-LABEL: @test_plix(
215 // AArch32-NEXT: entry:
216 // AArch32-NEXT: call void @llvm.prefetch.p0(ptr null, i32 0, i32 3, i32 0)
217 // AArch32-NEXT: ret void
219 // AArch64-LABEL: @test_plix(
220 // AArch64-NEXT: entry:
221 // AArch64-NEXT: call void @llvm.aarch64.prefetch(ptr null, i32 0, i32 2, i32 0, i32 0)
222 // AArch64-NEXT: ret void
229 // AArch32-LABEL: @test_nop(
230 // AArch32-NEXT: entry:
231 // AArch32-NEXT: call void @llvm.arm.hint(i32 0)
232 // AArch32-NEXT: ret void
234 // AArch64-LABEL: @test_nop(
235 // AArch64-NEXT: entry:
236 // AArch64-NEXT: call void @llvm.aarch64.hint(i32 0)
237 // AArch64-NEXT: ret void
239 void test_nop(void) {
243 /* 9 DATA-PROCESSING INTRINSICS */
245 /* 9.2 Miscellaneous data-processing intrinsics */
246 // ARM-LABEL: @test_ror(
248 // ARM-NEXT: [[REM_I:%.*]] = urem i32 [[Y:%.*]], 32
249 // ARM-NEXT: [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0
250 // ARM-NEXT: br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]]
252 // ARM-NEXT: br label [[__ROR_EXIT:%.*]]
254 // ARM-NEXT: [[SHR_I:%.*]] = lshr i32 [[X:%.*]], [[REM_I]]
255 // ARM-NEXT: [[SUB_I:%.*]] = sub i32 32, [[REM_I]]
256 // ARM-NEXT: [[SHL_I:%.*]] = shl i32 [[X]], [[SUB_I]]
257 // ARM-NEXT: [[OR_I:%.*]] = or i32 [[SHR_I]], [[SHL_I]]
258 // ARM-NEXT: br label [[__ROR_EXIT]]
260 // ARM-NEXT: [[RETVAL_I_0:%.*]] = phi i32 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ]
261 // ARM-NEXT: ret i32 [[RETVAL_I_0]]
263 uint32_t test_ror(uint32_t x
, uint32_t y
) {
267 // AArch32-LABEL: @test_rorl(
268 // AArch32-NEXT: entry:
269 // AArch32-NEXT: [[REM_I_I:%.*]] = urem i32 [[Y:%.*]], 32
270 // AArch32-NEXT: [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0
271 // AArch32-NEXT: br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]]
272 // AArch32: if.then.i.i:
273 // AArch32-NEXT: br label [[__RORL_EXIT:%.*]]
274 // AArch32: if.end.i.i:
275 // AArch32-NEXT: [[SHR_I_I:%.*]] = lshr i32 [[X:%.*]], [[REM_I_I]]
276 // AArch32-NEXT: [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]]
277 // AArch32-NEXT: [[SHL_I_I:%.*]] = shl i32 [[X]], [[SUB_I_I]]
278 // AArch32-NEXT: [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]]
279 // AArch32-NEXT: br label [[__RORL_EXIT]]
280 // AArch32: __rorl.exit:
281 // AArch32-NEXT: [[RETVAL_I_I_0:%.*]] = phi i32 [ [[X]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ]
282 // AArch32-NEXT: ret i32 [[RETVAL_I_I_0]]
284 // AArch64-LABEL: @test_rorl(
285 // AArch64-NEXT: entry:
286 // AArch64-NEXT: [[REM_I:%.*]] = urem i32 [[Y:%.*]], 64
287 // AArch64-NEXT: [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0
288 // AArch64-NEXT: br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]]
289 // AArch64: if.then.i:
290 // AArch64-NEXT: br label [[__RORLL_EXIT:%.*]]
291 // AArch64: if.end.i:
292 // AArch64-NEXT: [[SH_PROM_I:%.*]] = zext i32 [[REM_I]] to i64
293 // AArch64-NEXT: [[SHR_I:%.*]] = lshr i64 [[X:%.*]], [[SH_PROM_I]]
294 // AArch64-NEXT: [[SUB_I:%.*]] = sub i32 64, [[REM_I]]
295 // AArch64-NEXT: [[SH_PROM1_I:%.*]] = zext i32 [[SUB_I]] to i64
296 // AArch64-NEXT: [[SHL_I:%.*]] = shl i64 [[X]], [[SH_PROM1_I]]
297 // AArch64-NEXT: [[OR_I:%.*]] = or i64 [[SHR_I]], [[SHL_I]]
298 // AArch64-NEXT: br label [[__RORLL_EXIT]]
299 // AArch64: __rorll.exit:
300 // AArch64-NEXT: [[RETVAL_I_0:%.*]] = phi i64 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ]
301 // AArch64-NEXT: ret i64 [[RETVAL_I_0]]
303 unsigned long test_rorl(unsigned long x
, uint32_t y
) {
307 // ARM-LABEL: @test_rorll(
309 // ARM-NEXT: [[REM_I:%.*]] = urem i32 [[Y:%.*]], 64
310 // ARM-NEXT: [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0
311 // ARM-NEXT: br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]]
313 // ARM-NEXT: br label [[__RORLL_EXIT:%.*]]
315 // ARM-NEXT: [[SH_PROM_I:%.*]] = zext i32 [[REM_I]] to i64
316 // ARM-NEXT: [[SHR_I:%.*]] = lshr i64 [[X:%.*]], [[SH_PROM_I]]
317 // ARM-NEXT: [[SUB_I:%.*]] = sub i32 64, [[REM_I]]
318 // ARM-NEXT: [[SH_PROM1_I:%.*]] = zext i32 [[SUB_I]] to i64
319 // ARM-NEXT: [[SHL_I:%.*]] = shl i64 [[X]], [[SH_PROM1_I]]
320 // ARM-NEXT: [[OR_I:%.*]] = or i64 [[SHR_I]], [[SHL_I]]
321 // ARM-NEXT: br label [[__RORLL_EXIT]]
322 // ARM: __rorll.exit:
323 // ARM-NEXT: [[RETVAL_I_0:%.*]] = phi i64 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ]
324 // ARM-NEXT: ret i64 [[RETVAL_I_0]]
326 uint64_t test_rorll(uint64_t x
, uint32_t y
) {
327 return __rorll(x
, y
);
330 // ARM-LABEL: @test_clz(
332 // ARM-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[T:%.*]], i1 false)
333 // ARM-NEXT: ret i32 [[TMP0]]
335 unsigned test_clz(uint32_t t
) {
339 // AArch32-LABEL: @test_clzl(
340 // AArch32-NEXT: entry:
341 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[T:%.*]], i1 false)
342 // AArch32-NEXT: ret i32 [[TMP0]]
344 // AArch64-LABEL: @test_clzl(
345 // AArch64-NEXT: entry:
346 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false)
347 // AArch64-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32
348 // AArch64-NEXT: ret i32 [[CAST_I]]
350 unsigned test_clzl(unsigned long t
) {
354 // ARM-LABEL: @test_clzll(
356 // ARM-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false)
357 // ARM-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32
358 // ARM-NEXT: ret i32 [[CAST_I]]
360 unsigned test_clzll(uint64_t t
) {
364 // AArch32-LABEL: @test_cls(
365 // AArch32-NEXT: entry:
366 // AArch32-NEXT: [[CLS_I:%.*]] = call i32 @llvm.arm.cls(i32 [[T:%.*]])
367 // AArch32-NEXT: ret i32 [[CLS_I]]
369 // AArch64-LABEL: @test_cls(
370 // AArch64-NEXT: entry:
371 // AArch64-NEXT: [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls(i32 [[T:%.*]])
372 // AArch64-NEXT: ret i32 [[CLS_I]]
374 unsigned test_cls(uint32_t t
) {
378 // AArch32-LABEL: @test_clsl(
379 // AArch32-NEXT: entry:
380 // AArch32-NEXT: [[CLS_I:%.*]] = call i32 @llvm.arm.cls(i32 [[T:%.*]])
381 // AArch32-NEXT: ret i32 [[CLS_I]]
383 // AArch64-LABEL: @test_clsl(
384 // AArch64-NEXT: entry:
385 // AArch64-NEXT: [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls64(i64 [[T:%.*]])
386 // AArch64-NEXT: ret i32 [[CLS_I]]
388 unsigned test_clsl(unsigned long t
) {
392 // AArch32-LABEL: @test_clsll(
393 // AArch32-NEXT: entry:
394 // AArch32-NEXT: [[CLS_I:%.*]] = call i32 @llvm.arm.cls64(i64 [[T:%.*]])
395 // AArch32-NEXT: ret i32 [[CLS_I]]
397 // AArch64-LABEL: @test_clsll(
398 // AArch64-NEXT: entry:
399 // AArch64-NEXT: [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls64(i64 [[T:%.*]])
400 // AArch64-NEXT: ret i32 [[CLS_I]]
402 unsigned test_clsll(uint64_t t
) {
406 // ARM-LABEL: @test_rev(
408 // ARM-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]])
409 // ARM-NEXT: ret i32 [[TMP0]]
411 uint32_t test_rev(uint32_t t
) {
415 // AArch32-LABEL: @test_revl(
416 // AArch32-NEXT: entry:
417 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]])
418 // AArch32-NEXT: ret i32 [[TMP0]]
420 // AArch64-LABEL: @test_revl(
421 // AArch64-NEXT: entry:
422 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]])
423 // AArch64-NEXT: ret i64 [[TMP0]]
425 long test_revl(long t
) {
429 // ARM-LABEL: @test_revll(
431 // ARM-NEXT: [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]])
432 // ARM-NEXT: ret i64 [[TMP0]]
434 uint64_t test_revll(uint64_t t
) {
438 // ARM-LABEL: @test_rev16(
440 // ARM-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]])
441 // ARM-NEXT: [[REM_I_I:%.*]] = urem i32 16, 32
442 // ARM-NEXT: [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0
443 // ARM-NEXT: br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]]
445 // ARM-NEXT: br label [[__REV16_EXIT:%.*]]
447 // ARM-NEXT: [[SHR_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I]]
448 // ARM-NEXT: [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]]
449 // ARM-NEXT: [[SHL_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I]]
450 // ARM-NEXT: [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]]
451 // ARM-NEXT: br label [[__REV16_EXIT]]
452 // ARM: __rev16.exit:
453 // ARM-NEXT: [[RETVAL_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ]
454 // ARM-NEXT: ret i32 [[RETVAL_I_I_0]]
456 uint32_t test_rev16(uint32_t t
) {
460 // AArch32-LABEL: @test_rev16l(
461 // AArch32-NEXT: entry:
462 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]])
463 // AArch32-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32
464 // AArch32-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0
465 // AArch32-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]]
466 // AArch32: if.then.i.i.i:
467 // AArch32-NEXT: br label [[__REV16L_EXIT:%.*]]
468 // AArch32: if.end.i.i.i:
469 // AArch32-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I_I]]
470 // AArch32-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]]
471 // AArch32-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I_I]]
472 // AArch32-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]]
473 // AArch32-NEXT: br label [[__REV16L_EXIT]]
474 // AArch32: __rev16l.exit:
475 // AArch32-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ]
476 // AArch32-NEXT: ret i32 [[RETVAL_I_I_I_0]]
478 // AArch64-LABEL: @test_rev16l(
479 // AArch64-NEXT: entry:
480 // AArch64-NEXT: [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32
481 // AArch64-NEXT: [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32
482 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]])
483 // AArch64-NEXT: [[REM_I_I10_I:%.*]] = urem i32 16, 32
484 // AArch64-NEXT: [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0
485 // AArch64-NEXT: br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I17_I:%.*]], label [[IF_END_I_I12_I:%.*]]
486 // AArch64: if.then.i.i17.i:
487 // AArch64-NEXT: br label [[__REV16_EXIT18_I:%.*]]
488 // AArch64: if.end.i.i12.i:
489 // AArch64-NEXT: [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]]
490 // AArch64-NEXT: [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]]
491 // AArch64-NEXT: [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]]
492 // AArch64-NEXT: [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]]
493 // AArch64-NEXT: br label [[__REV16_EXIT18_I]]
494 // AArch64: __rev16.exit18.i:
495 // AArch64-NEXT: [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I17_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I12_I]] ]
496 // AArch64-NEXT: [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64
497 // AArch64-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32
498 // AArch64-NEXT: [[CONV2_I:%.*]] = trunc i64 [[T]] to i32
499 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]])
500 // AArch64-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32
501 // AArch64-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0
502 // AArch64-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]]
503 // AArch64: if.then.i.i.i:
504 // AArch64-NEXT: br label [[__REV16LL_EXIT:%.*]]
505 // AArch64: if.end.i.i.i:
506 // AArch64-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]]
507 // AArch64-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]]
508 // AArch64-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]]
509 // AArch64-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]]
510 // AArch64-NEXT: br label [[__REV16LL_EXIT]]
511 // AArch64: __rev16ll.exit:
512 // AArch64-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ]
513 // AArch64-NEXT: [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64
514 // AArch64-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]]
515 // AArch64-NEXT: ret i64 [[OR_I]]
517 long test_rev16l(long t
) {
521 // ARM-LABEL: @test_rev16ll(
523 // ARM-NEXT: [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32
524 // ARM-NEXT: [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32
525 // ARM-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]])
526 // ARM-NEXT: [[REM_I_I10_I:%.*]] = urem i32 16, 32
527 // ARM-NEXT: [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0
528 // ARM-NEXT: br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I17_I:%.*]], label [[IF_END_I_I12_I:%.*]]
529 // ARM: if.then.i.i17.i:
530 // ARM-NEXT: br label [[__REV16_EXIT18_I:%.*]]
531 // ARM: if.end.i.i12.i:
532 // ARM-NEXT: [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]]
533 // ARM-NEXT: [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]]
534 // ARM-NEXT: [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]]
535 // ARM-NEXT: [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]]
536 // ARM-NEXT: br label [[__REV16_EXIT18_I]]
537 // ARM: __rev16.exit18.i:
538 // ARM-NEXT: [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I17_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I12_I]] ]
539 // ARM-NEXT: [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64
540 // ARM-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32
541 // ARM-NEXT: [[CONV2_I:%.*]] = trunc i64 [[T]] to i32
542 // ARM-NEXT: [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]])
543 // ARM-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32
544 // ARM-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0
545 // ARM-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]]
546 // ARM: if.then.i.i.i:
547 // ARM-NEXT: br label [[__REV16LL_EXIT:%.*]]
548 // ARM: if.end.i.i.i:
549 // ARM-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]]
550 // ARM-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]]
551 // ARM-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]]
552 // ARM-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]]
553 // ARM-NEXT: br label [[__REV16LL_EXIT]]
554 // ARM: __rev16ll.exit:
555 // ARM-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ]
556 // ARM-NEXT: [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64
557 // ARM-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]]
558 // ARM-NEXT: ret i64 [[OR_I]]
560 uint64_t test_rev16ll(uint64_t t
) {
564 // ARM-LABEL: @test_revsh(
566 // ARM-NEXT: [[TMP0:%.*]] = call i16 @llvm.bswap.i16(i16 [[T:%.*]])
567 // ARM-NEXT: ret i16 [[TMP0]]
569 int16_t test_revsh(int16_t t
) {
573 // ARM-LABEL: @test_rbit(
575 // ARM-NEXT: [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]])
576 // ARM-NEXT: ret i32 [[RBIT_I]]
578 uint32_t test_rbit(uint32_t t
) {
582 // AArch32-LABEL: @test_rbitl(
583 // AArch32-NEXT: entry:
584 // AArch32-NEXT: [[RBIT_I_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]])
585 // AArch32-NEXT: ret i32 [[RBIT_I_I]]
587 // AArch64-LABEL: @test_rbitl(
588 // AArch64-NEXT: entry:
589 // AArch64-NEXT: [[RBIT_I:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[T:%.*]])
590 // AArch64-NEXT: ret i64 [[RBIT_I]]
592 long test_rbitl(long t
) {
596 // AArch32-LABEL: @test_rbitll(
597 // AArch32-NEXT: entry:
598 // AArch32-NEXT: [[CONV_I:%.*]] = trunc i64 [[T:%.*]] to i32
599 // AArch32-NEXT: [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[CONV_I]])
600 // AArch32-NEXT: [[CONV1_I:%.*]] = zext i32 [[RBIT_I]] to i64
601 // AArch32-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32
602 // AArch32-NEXT: [[SHR_I:%.*]] = lshr i64 [[T]], 32
603 // AArch32-NEXT: [[CONV2_I:%.*]] = trunc i64 [[SHR_I]] to i32
604 // AArch32-NEXT: [[RBIT3_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[CONV2_I]])
605 // AArch32-NEXT: [[CONV4_I:%.*]] = zext i32 [[RBIT3_I]] to i64
606 // AArch32-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]]
607 // AArch32-NEXT: ret i64 [[OR_I]]
609 // AArch64-LABEL: @test_rbitll(
610 // AArch64-NEXT: entry:
611 // AArch64-NEXT: [[RBIT_I:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[T:%.*]])
612 // AArch64-NEXT: ret i64 [[RBIT_I]]
614 uint64_t test_rbitll(uint64_t t
) {
618 /* 9.4 Saturating intrinsics */
619 #ifdef __ARM_FEATURE_SAT
620 /* 9.4.1 Width-specified saturation intrinsics */
621 // AArch32-LABEL: @test_ssat(
622 // AArch32-NEXT: entry:
623 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssat(i32 [[T:%.*]], i32 1)
624 // AArch32-NEXT: ret i32 [[TMP0]]
626 int32_t test_ssat(int32_t t
) {
630 // AArch32-LABEL: @test_usat(
631 // AArch32-NEXT: entry:
632 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usat(i32 [[T:%.*]], i32 2)
633 // AArch32-NEXT: ret i32 [[TMP0]]
635 uint32_t test_usat(int32_t t
) {
640 /* 9.4.2 Saturating addition and subtraction intrinsics */
641 #ifdef __ARM_FEATURE_DSP
642 // AArch32-LABEL: @test_qadd(
643 // AArch32-NEXT: entry:
644 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[A:%.*]], i32 [[B:%.*]])
645 // AArch32-NEXT: ret i32 [[TMP0]]
647 int32_t test_qadd(int32_t a
, int32_t b
) {
651 // AArch32-LABEL: @test_qsub(
652 // AArch32-NEXT: entry:
653 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub(i32 [[A:%.*]], i32 [[B:%.*]])
654 // AArch32-NEXT: ret i32 [[TMP0]]
656 int32_t test_qsub(int32_t a
, int32_t b
) {
661 // AArch32-LABEL: @test_qdbl(
662 // AArch32-NEXT: entry:
663 // AArch32-NEXT: [[CALL:%.*]] = call i32 @f() #[[ATTR9:[0-9]+]]
664 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[CALL]], i32 [[CALL]])
665 // AArch32-NEXT: ret i32 [[TMP0]]
667 int32_t test_qdbl() {
673 * 9.3 16-bit multiplications
675 #if __ARM_FEATURE_DSP
676 // AArch32-LABEL: @test_smulbb(
677 // AArch32-NEXT: entry:
678 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulbb(i32 [[A:%.*]], i32 [[B:%.*]])
679 // AArch32-NEXT: ret i32 [[TMP0]]
681 int32_t test_smulbb(int32_t a
, int32_t b
) {
682 return __smulbb(a
, b
);
685 // AArch32-LABEL: @test_smulbt(
686 // AArch32-NEXT: entry:
687 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulbt(i32 [[A:%.*]], i32 [[B:%.*]])
688 // AArch32-NEXT: ret i32 [[TMP0]]
690 int32_t test_smulbt(int32_t a
, int32_t b
) {
691 return __smulbt(a
, b
);
694 // AArch32-LABEL: @test_smultb(
695 // AArch32-NEXT: entry:
696 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smultb(i32 [[A:%.*]], i32 [[B:%.*]])
697 // AArch32-NEXT: ret i32 [[TMP0]]
699 int32_t test_smultb(int32_t a
, int32_t b
) {
700 return __smultb(a
, b
);
703 // AArch32-LABEL: @test_smultt(
704 // AArch32-NEXT: entry:
705 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smultt(i32 [[A:%.*]], i32 [[B:%.*]])
706 // AArch32-NEXT: ret i32 [[TMP0]]
708 int32_t test_smultt(int32_t a
, int32_t b
) {
709 return __smultt(a
, b
);
712 // AArch32-LABEL: @test_smulwb(
713 // AArch32-NEXT: entry:
714 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulwb(i32 [[A:%.*]], i32 [[B:%.*]])
715 // AArch32-NEXT: ret i32 [[TMP0]]
717 int32_t test_smulwb(int32_t a
, int32_t b
) {
718 return __smulwb(a
, b
);
721 // AArch32-LABEL: @test_smulwt(
722 // AArch32-NEXT: entry:
723 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulwt(i32 [[A:%.*]], i32 [[B:%.*]])
724 // AArch32-NEXT: ret i32 [[TMP0]]
726 int32_t test_smulwt(int32_t a
, int32_t b
) {
727 return __smulwt(a
, b
);
731 /* 9.4.3 Accumultating multiplications */
732 #if __ARM_FEATURE_DSP
733 // AArch32-LABEL: @test_smlabb(
734 // AArch32-NEXT: entry:
735 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlabb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
736 // AArch32-NEXT: ret i32 [[TMP0]]
738 int32_t test_smlabb(int32_t a
, int32_t b
, int32_t c
) {
739 return __smlabb(a
, b
, c
);
742 // AArch32-LABEL: @test_smlabt(
743 // AArch32-NEXT: entry:
744 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlabt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
745 // AArch32-NEXT: ret i32 [[TMP0]]
747 int32_t test_smlabt(int32_t a
, int32_t b
, int32_t c
) {
748 return __smlabt(a
, b
, c
);
751 // AArch32-LABEL: @test_smlatb(
752 // AArch32-NEXT: entry:
753 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlatb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
754 // AArch32-NEXT: ret i32 [[TMP0]]
756 int32_t test_smlatb(int32_t a
, int32_t b
, int32_t c
) {
757 return __smlatb(a
, b
, c
);
760 // AArch32-LABEL: @test_smlatt(
761 // AArch32-NEXT: entry:
762 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlatt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
763 // AArch32-NEXT: ret i32 [[TMP0]]
765 int32_t test_smlatt(int32_t a
, int32_t b
, int32_t c
) {
766 return __smlatt(a
, b
, c
);
769 // AArch32-LABEL: @test_smlawb(
770 // AArch32-NEXT: entry:
771 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlawb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
772 // AArch32-NEXT: ret i32 [[TMP0]]
774 int32_t test_smlawb(int32_t a
, int32_t b
, int32_t c
) {
775 return __smlawb(a
, b
, c
);
778 // AArch32-LABEL: @test_smlawt(
779 // AArch32-NEXT: entry:
780 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlawt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
781 // AArch32-NEXT: ret i32 [[TMP0]]
783 int32_t test_smlawt(int32_t a
, int32_t b
, int32_t c
) {
784 return __smlawt(a
, b
, c
);
788 /* 9.5.4 Parallel 16-bit saturation */
789 #if __ARM_FEATURE_SIMD32
790 // AArch32-LABEL: @test_ssat16(
791 // AArch32-NEXT: entry:
792 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssat16(i32 [[A:%.*]], i32 15)
793 // AArch32-NEXT: ret i32 [[TMP0]]
795 int16x2_t
test_ssat16(int16x2_t a
) {
796 return __ssat16(a
, 15);
799 // AArch32-LABEL: @test_usat16(
800 // AArch32-NEXT: entry:
801 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usat16(i32 [[A:%.*]], i32 15)
802 // AArch32-NEXT: ret i32 [[TMP0]]
804 uint16x2_t
test_usat16(int16x2_t a
) {
805 return __usat16(a
, 15);
809 /* 9.5.5 Packing and unpacking */
810 #if __ARM_FEATURE_SIMD32
811 // AArch32-LABEL: @test_sxtab16(
812 // AArch32-NEXT: entry:
813 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sxtab16(i32 [[A:%.*]], i32 [[B:%.*]])
814 // AArch32-NEXT: ret i32 [[TMP0]]
816 int16x2_t
test_sxtab16(int16x2_t a
, int8x4_t b
) {
817 return __sxtab16(a
, b
);
820 // AArch32-LABEL: @test_sxtb16(
821 // AArch32-NEXT: entry:
822 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sxtb16(i32 [[A:%.*]])
823 // AArch32-NEXT: ret i32 [[TMP0]]
825 int16x2_t
test_sxtb16(int8x4_t a
) {
829 // AArch32-LABEL: @test_uxtab16(
830 // AArch32-NEXT: entry:
831 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uxtab16(i32 [[A:%.*]], i32 [[B:%.*]])
832 // AArch32-NEXT: ret i32 [[TMP0]]
834 int16x2_t
test_uxtab16(int16x2_t a
, int8x4_t b
) {
835 return __uxtab16(a
, b
);
838 // AArch32-LABEL: @test_uxtb16(
839 // AArch32-NEXT: entry:
840 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uxtb16(i32 [[A:%.*]])
841 // AArch32-NEXT: ret i32 [[TMP0]]
843 int16x2_t
test_uxtb16(int8x4_t a
) {
848 /* 9.5.6 Parallel selection */
849 #if __ARM_FEATURE_SIMD32
850 // AArch32-LABEL: @test_sel(
851 // AArch32-NEXT: entry:
852 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sel(i32 [[A:%.*]], i32 [[B:%.*]])
853 // AArch32-NEXT: ret i32 [[TMP0]]
855 uint8x4_t
test_sel(uint8x4_t a
, uint8x4_t b
) {
860 /* 9.5.7 Parallel 8-bit addition and subtraction */
861 #if __ARM_FEATURE_SIMD32
862 // AArch32-LABEL: @test_qadd8(
863 // AArch32-NEXT: entry:
864 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd8(i32 [[A:%.*]], i32 [[B:%.*]])
865 // AArch32-NEXT: ret i32 [[TMP0]]
867 int16x2_t
test_qadd8(int8x4_t a
, int8x4_t b
) {
868 return __qadd8(a
, b
);
871 // AArch32-LABEL: @test_qsub8(
872 // AArch32-NEXT: entry:
873 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub8(i32 [[A:%.*]], i32 [[B:%.*]])
874 // AArch32-NEXT: ret i32 [[TMP0]]
876 int8x4_t
test_qsub8(int8x4_t a
, int8x4_t b
) {
877 return __qsub8(a
, b
);
880 // AArch32-LABEL: @test_sadd8(
881 // AArch32-NEXT: entry:
882 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sadd8(i32 [[A:%.*]], i32 [[B:%.*]])
883 // AArch32-NEXT: ret i32 [[TMP0]]
885 int8x4_t
test_sadd8(int8x4_t a
, int8x4_t b
) {
886 return __sadd8(a
, b
);
889 // AArch32-LABEL: @test_shadd8(
890 // AArch32-NEXT: entry:
891 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shadd8(i32 [[A:%.*]], i32 [[B:%.*]])
892 // AArch32-NEXT: ret i32 [[TMP0]]
894 int8x4_t
test_shadd8(int8x4_t a
, int8x4_t b
) {
895 return __shadd8(a
, b
);
898 // AArch32-LABEL: @test_shsub8(
899 // AArch32-NEXT: entry:
900 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shsub8(i32 [[A:%.*]], i32 [[B:%.*]])
901 // AArch32-NEXT: ret i32 [[TMP0]]
903 int8x4_t
test_shsub8(int8x4_t a
, int8x4_t b
) {
904 return __shsub8(a
, b
);
907 // AArch32-LABEL: @test_ssub8(
908 // AArch32-NEXT: entry:
909 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssub8(i32 [[A:%.*]], i32 [[B:%.*]])
910 // AArch32-NEXT: ret i32 [[TMP0]]
912 int8x4_t
test_ssub8(int8x4_t a
, int8x4_t b
) {
913 return __ssub8(a
, b
);
916 // AArch32-LABEL: @test_uadd8(
917 // AArch32-NEXT: entry:
918 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uadd8(i32 [[A:%.*]], i32 [[B:%.*]])
919 // AArch32-NEXT: ret i32 [[TMP0]]
921 uint8x4_t
test_uadd8(uint8x4_t a
, uint8x4_t b
) {
922 return __uadd8(a
, b
);
925 // AArch32-LABEL: @test_uhadd8(
926 // AArch32-NEXT: entry:
927 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhadd8(i32 [[A:%.*]], i32 [[B:%.*]])
928 // AArch32-NEXT: ret i32 [[TMP0]]
930 uint8x4_t
test_uhadd8(uint8x4_t a
, uint8x4_t b
) {
931 return __uhadd8(a
, b
);
934 // AArch32-LABEL: @test_uhsub8(
935 // AArch32-NEXT: entry:
936 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhsub8(i32 [[A:%.*]], i32 [[B:%.*]])
937 // AArch32-NEXT: ret i32 [[TMP0]]
939 uint8x4_t
test_uhsub8(uint8x4_t a
, uint8x4_t b
) {
940 return __uhsub8(a
, b
);
943 // AArch32-LABEL: @test_uqadd8(
944 // AArch32-NEXT: entry:
945 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqadd8(i32 [[A:%.*]], i32 [[B:%.*]])
946 // AArch32-NEXT: ret i32 [[TMP0]]
948 uint8x4_t
test_uqadd8(uint8x4_t a
, uint8x4_t b
) {
949 return __uqadd8(a
, b
);
952 // AArch32-LABEL: @test_uqsub8(
953 // AArch32-NEXT: entry:
954 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqsub8(i32 [[A:%.*]], i32 [[B:%.*]])
955 // AArch32-NEXT: ret i32 [[TMP0]]
957 uint8x4_t
test_uqsub8(uint8x4_t a
, uint8x4_t b
) {
958 return __uqsub8(a
, b
);
961 // AArch32-LABEL: @test_usub8(
962 // AArch32-NEXT: entry:
963 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usub8(i32 [[A:%.*]], i32 [[B:%.*]])
964 // AArch32-NEXT: ret i32 [[TMP0]]
966 uint8x4_t
test_usub8(uint8x4_t a
, uint8x4_t b
) {
967 return __usub8(a
, b
);
971 /* 9.5.8 Sum of 8-bit absolute differences */
972 #if __ARM_FEATURE_SIMD32
973 // AArch32-LABEL: @test_usad8(
974 // AArch32-NEXT: entry:
975 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usad8(i32 [[A:%.*]], i32 [[B:%.*]])
976 // AArch32-NEXT: ret i32 [[TMP0]]
978 uint32_t test_usad8(uint8x4_t a
, uint8x4_t b
) {
979 return __usad8(a
, b
);
982 // AArch32-LABEL: @test_usada8(
983 // AArch32-NEXT: entry:
984 // AArch32-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32
985 // AArch32-NEXT: [[CONV1:%.*]] = zext i8 [[B:%.*]] to i32
986 // AArch32-NEXT: [[CONV2:%.*]] = zext i8 [[C:%.*]] to i32
987 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usada8(i32 [[CONV]], i32 [[CONV1]], i32 [[CONV2]])
988 // AArch32-NEXT: ret i32 [[TMP0]]
990 uint32_t test_usada8(uint8_t a
, uint8_t b
, uint8_t c
) {
991 return __usada8(a
, b
, c
);
995 /* 9.5.9 Parallel 16-bit addition and subtraction */
996 #if __ARM_FEATURE_SIMD32
997 // AArch32-LABEL: @test_qadd16(
998 // AArch32-NEXT: entry:
999 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd16(i32 [[A:%.*]], i32 [[B:%.*]])
1000 // AArch32-NEXT: ret i32 [[TMP0]]
1002 int16x2_t
test_qadd16(int16x2_t a
, int16x2_t b
) {
1003 return __qadd16(a
, b
);
1006 // AArch32-LABEL: @test_qasx(
1007 // AArch32-NEXT: entry:
1008 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qasx(i32 [[A:%.*]], i32 [[B:%.*]])
1009 // AArch32-NEXT: ret i32 [[TMP0]]
1011 int16x2_t
test_qasx(int16x2_t a
, int16x2_t b
) {
1012 return __qasx(a
, b
);
1015 // AArch32-LABEL: @test_qsax(
1016 // AArch32-NEXT: entry:
1017 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsax(i32 [[A:%.*]], i32 [[B:%.*]])
1018 // AArch32-NEXT: ret i32 [[TMP0]]
1020 int16x2_t
test_qsax(int16x2_t a
, int16x2_t b
) {
1021 return __qsax(a
, b
);
1024 // AArch32-LABEL: @test_qsub16(
1025 // AArch32-NEXT: entry:
1026 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub16(i32 [[A:%.*]], i32 [[B:%.*]])
1027 // AArch32-NEXT: ret i32 [[TMP0]]
1029 int16x2_t
test_qsub16(int16x2_t a
, int16x2_t b
) {
1030 return __qsub16(a
, b
);
1033 // AArch32-LABEL: @test_sadd16(
1034 // AArch32-NEXT: entry:
1035 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sadd16(i32 [[A:%.*]], i32 [[B:%.*]])
1036 // AArch32-NEXT: ret i32 [[TMP0]]
1038 int16x2_t
test_sadd16(int16x2_t a
, int16x2_t b
) {
1039 return __sadd16(a
, b
);
1042 // AArch32-LABEL: @test_sasx(
1043 // AArch32-NEXT: entry:
1044 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sasx(i32 [[A:%.*]], i32 [[B:%.*]])
1045 // AArch32-NEXT: ret i32 [[TMP0]]
1047 int16x2_t
test_sasx(int16x2_t a
, int16x2_t b
) {
1048 return __sasx(a
, b
);
1051 // AArch32-LABEL: @test_shadd16(
1052 // AArch32-NEXT: entry:
1053 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shadd16(i32 [[A:%.*]], i32 [[B:%.*]])
1054 // AArch32-NEXT: ret i32 [[TMP0]]
1056 int16x2_t
test_shadd16(int16x2_t a
, int16x2_t b
) {
1057 return __shadd16(a
, b
);
1060 // AArch32-LABEL: @test_shasx(
1061 // AArch32-NEXT: entry:
1062 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shasx(i32 [[A:%.*]], i32 [[B:%.*]])
1063 // AArch32-NEXT: ret i32 [[TMP0]]
1065 int16x2_t
test_shasx(int16x2_t a
, int16x2_t b
) {
1066 return __shasx(a
, b
);
1069 // AArch32-LABEL: @test_shsax(
1070 // AArch32-NEXT: entry:
1071 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shsax(i32 [[A:%.*]], i32 [[B:%.*]])
1072 // AArch32-NEXT: ret i32 [[TMP0]]
1074 int16x2_t
test_shsax(int16x2_t a
, int16x2_t b
) {
1075 return __shsax(a
, b
);
1078 // AArch32-LABEL: @test_shsub16(
1079 // AArch32-NEXT: entry:
1080 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shsub16(i32 [[A:%.*]], i32 [[B:%.*]])
1081 // AArch32-NEXT: ret i32 [[TMP0]]
1083 int16x2_t
test_shsub16(int16x2_t a
, int16x2_t b
) {
1084 return __shsub16(a
, b
);
1087 // AArch32-LABEL: @test_ssax(
1088 // AArch32-NEXT: entry:
1089 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssax(i32 [[A:%.*]], i32 [[B:%.*]])
1090 // AArch32-NEXT: ret i32 [[TMP0]]
1092 int16x2_t
test_ssax(int16x2_t a
, int16x2_t b
) {
1093 return __ssax(a
, b
);
1096 // AArch32-LABEL: @test_ssub16(
1097 // AArch32-NEXT: entry:
1098 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssub16(i32 [[A:%.*]], i32 [[B:%.*]])
1099 // AArch32-NEXT: ret i32 [[TMP0]]
1101 int16x2_t
test_ssub16(int16x2_t a
, int16x2_t b
) {
1102 return __ssub16(a
, b
);
1105 // AArch32-LABEL: @test_uadd16(
1106 // AArch32-NEXT: entry:
1107 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uadd16(i32 [[A:%.*]], i32 [[B:%.*]])
1108 // AArch32-NEXT: ret i32 [[TMP0]]
1110 uint16x2_t
test_uadd16(uint16x2_t a
, uint16x2_t b
) {
1111 return __uadd16(a
, b
);
1114 // AArch32-LABEL: @test_uasx(
1115 // AArch32-NEXT: entry:
1116 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uasx(i32 [[A:%.*]], i32 [[B:%.*]])
1117 // AArch32-NEXT: ret i32 [[TMP0]]
1119 uint16x2_t
test_uasx(uint16x2_t a
, uint16x2_t b
) {
1120 return __uasx(a
, b
);
1123 // AArch32-LABEL: @test_uhadd16(
1124 // AArch32-NEXT: entry:
1125 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhadd16(i32 [[A:%.*]], i32 [[B:%.*]])
1126 // AArch32-NEXT: ret i32 [[TMP0]]
1128 uint16x2_t
test_uhadd16(uint16x2_t a
, uint16x2_t b
) {
1129 return __uhadd16(a
, b
);
1132 // AArch32-LABEL: @test_uhasx(
1133 // AArch32-NEXT: entry:
1134 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhasx(i32 [[A:%.*]], i32 [[B:%.*]])
1135 // AArch32-NEXT: ret i32 [[TMP0]]
1137 uint16x2_t
test_uhasx(uint16x2_t a
, uint16x2_t b
) {
1138 return __uhasx(a
, b
);
1141 // AArch32-LABEL: @test_uhsax(
1142 // AArch32-NEXT: entry:
1143 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhsax(i32 [[A:%.*]], i32 [[B:%.*]])
1144 // AArch32-NEXT: ret i32 [[TMP0]]
1146 uint16x2_t
test_uhsax(uint16x2_t a
, uint16x2_t b
) {
1147 return __uhsax(a
, b
);
1150 // AArch32-LABEL: @test_uhsub16(
1151 // AArch32-NEXT: entry:
1152 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhsub16(i32 [[A:%.*]], i32 [[B:%.*]])
1153 // AArch32-NEXT: ret i32 [[TMP0]]
1155 uint16x2_t
test_uhsub16(uint16x2_t a
, uint16x2_t b
) {
1156 return __uhsub16(a
, b
);
1159 // AArch32-LABEL: @test_uqadd16(
1160 // AArch32-NEXT: entry:
1161 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqadd16(i32 [[A:%.*]], i32 [[B:%.*]])
1162 // AArch32-NEXT: ret i32 [[TMP0]]
1164 uint16x2_t
test_uqadd16(uint16x2_t a
, uint16x2_t b
) {
1165 return __uqadd16(a
, b
);
1168 // AArch32-LABEL: @test_uqasx(
1169 // AArch32-NEXT: entry:
1170 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqasx(i32 [[A:%.*]], i32 [[B:%.*]])
1171 // AArch32-NEXT: ret i32 [[TMP0]]
1173 uint16x2_t
test_uqasx(uint16x2_t a
, uint16x2_t b
) {
1174 return __uqasx(a
, b
);
1177 // AArch32-LABEL: @test_uqsax(
1178 // AArch32-NEXT: entry:
1179 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqsax(i32 [[A:%.*]], i32 [[B:%.*]])
1180 // AArch32-NEXT: ret i32 [[TMP0]]
1182 uint16x2_t
test_uqsax(uint16x2_t a
, uint16x2_t b
) {
1183 return __uqsax(a
, b
);
1186 // AArch32-LABEL: @test_uqsub16(
1187 // AArch32-NEXT: entry:
1188 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqsub16(i32 [[A:%.*]], i32 [[B:%.*]])
1189 // AArch32-NEXT: ret i32 [[TMP0]]
1191 uint16x2_t
test_uqsub16(uint16x2_t a
, uint16x2_t b
) {
1192 return __uqsub16(a
, b
);
1195 // AArch32-LABEL: @test_usax(
1196 // AArch32-NEXT: entry:
1197 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usax(i32 [[A:%.*]], i32 [[B:%.*]])
1198 // AArch32-NEXT: ret i32 [[TMP0]]
1200 uint16x2_t
test_usax(uint16x2_t a
, uint16x2_t b
) {
1201 return __usax(a
, b
);
1204 // AArch32-LABEL: @test_usub16(
1205 // AArch32-NEXT: entry:
1206 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usub16(i32 [[A:%.*]], i32 [[B:%.*]])
1207 // AArch32-NEXT: ret i32 [[TMP0]]
1209 uint16x2_t
test_usub16(uint16x2_t a
, uint16x2_t b
) {
1210 return __usub16(a
, b
);
1214 /* 9.5.10 Parallel 16-bit multiplications */
1215 #if __ARM_FEATURE_SIMD32
1216 // AArch32-LABEL: @test_smlad(
1217 // AArch32-NEXT: entry:
1218 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlad(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
1219 // AArch32-NEXT: ret i32 [[TMP0]]
1221 int32_t test_smlad(int16x2_t a
, int16x2_t b
, int32_t c
) {
1222 return __smlad(a
, b
, c
);
1225 // AArch32-LABEL: @test_smladx(
1226 // AArch32-NEXT: entry:
1227 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smladx(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
1228 // AArch32-NEXT: ret i32 [[TMP0]]
1230 int32_t test_smladx(int16x2_t a
, int16x2_t b
, int32_t c
) {
1231 return __smladx(a
, b
, c
);
1234 // AArch32-LABEL: @test_smlald(
1235 // AArch32-NEXT: entry:
1236 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlald(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]])
1237 // AArch32-NEXT: ret i64 [[TMP0]]
1239 int64_t test_smlald(int16x2_t a
, int16x2_t b
, int64_t c
) {
1240 return __smlald(a
, b
, c
);
1243 // AArch32-LABEL: @test_smlaldx(
1244 // AArch32-NEXT: entry:
1245 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlaldx(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]])
1246 // AArch32-NEXT: ret i64 [[TMP0]]
1248 int64_t test_smlaldx(int16x2_t a
, int16x2_t b
, int64_t c
) {
1249 return __smlaldx(a
, b
, c
);
1252 // AArch32-LABEL: @test_smlsd(
1253 // AArch32-NEXT: entry:
1254 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlsd(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
1255 // AArch32-NEXT: ret i32 [[TMP0]]
1257 int32_t test_smlsd(int16x2_t a
, int16x2_t b
, int32_t c
) {
1258 return __smlsd(a
, b
, c
);
1261 // AArch32-LABEL: @test_smlsdx(
1262 // AArch32-NEXT: entry:
1263 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlsdx(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
1264 // AArch32-NEXT: ret i32 [[TMP0]]
1266 int32_t test_smlsdx(int16x2_t a
, int16x2_t b
, int32_t c
) {
1267 return __smlsdx(a
, b
, c
);
1270 // AArch32-LABEL: @test_smlsld(
1271 // AArch32-NEXT: entry:
1272 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlsld(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]])
1273 // AArch32-NEXT: ret i64 [[TMP0]]
1275 int64_t test_smlsld(int16x2_t a
, int16x2_t b
, int64_t c
) {
1276 return __smlsld(a
, b
, c
);
1279 // AArch32-LABEL: @test_smlsldx(
1280 // AArch32-NEXT: entry:
1281 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlsldx(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]])
1282 // AArch32-NEXT: ret i64 [[TMP0]]
1284 int64_t test_smlsldx(int16x2_t a
, int16x2_t b
, int64_t c
) {
1285 return __smlsldx(a
, b
, c
);
1288 // AArch32-LABEL: @test_smuad(
1289 // AArch32-NEXT: entry:
1290 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smuad(i32 [[A:%.*]], i32 [[B:%.*]])
1291 // AArch32-NEXT: ret i32 [[TMP0]]
1293 int32_t test_smuad(int16x2_t a
, int16x2_t b
) {
1294 return __smuad(a
, b
);
1297 // AArch32-LABEL: @test_smuadx(
1298 // AArch32-NEXT: entry:
1299 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smuadx(i32 [[A:%.*]], i32 [[B:%.*]])
1300 // AArch32-NEXT: ret i32 [[TMP0]]
1302 int32_t test_smuadx(int16x2_t a
, int16x2_t b
) {
1303 return __smuadx(a
, b
);
1306 // AArch32-LABEL: @test_smusd(
1307 // AArch32-NEXT: entry:
1308 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smusd(i32 [[A:%.*]], i32 [[B:%.*]])
1309 // AArch32-NEXT: ret i32 [[TMP0]]
1311 int32_t test_smusd(int16x2_t a
, int16x2_t b
) {
1312 return __smusd(a
, b
);
1315 // AArch32-LABEL: @test_smusdx(
1316 // AArch32-NEXT: entry:
1317 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smusdx(i32 [[A:%.*]], i32 [[B:%.*]])
1318 // AArch32-NEXT: ret i32 [[TMP0]]
1320 int32_t test_smusdx(int16x2_t a
, int16x2_t b
) {
1321 return __smusdx(a
, b
);
1325 /* 9.7 CRC32 intrinsics */
1326 // AArch32-LABEL: @test_crc32b(
1327 // AArch32-NEXT: entry:
1328 // AArch32-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32
1329 // AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32b(i32 [[A:%.*]], i32 [[TMP0]])
1330 // AArch32-NEXT: ret i32 [[TMP1]]
1332 // AArch64-LABEL: @test_crc32b(
1333 // AArch64-NEXT: entry:
1334 // AArch64-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32
1335 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32b(i32 [[A:%.*]], i32 [[TMP0]])
1336 // AArch64-NEXT: ret i32 [[TMP1]]
1338 uint32_t test_crc32b(uint32_t a
, uint8_t b
) {
1339 return __crc32b(a
, b
);
1342 // AArch32-LABEL: @test_crc32h(
1343 // AArch32-NEXT: entry:
1344 // AArch32-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32
1345 // AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32h(i32 [[A:%.*]], i32 [[TMP0]])
1346 // AArch32-NEXT: ret i32 [[TMP1]]
1348 // AArch64-LABEL: @test_crc32h(
1349 // AArch64-NEXT: entry:
1350 // AArch64-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32
1351 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32h(i32 [[A:%.*]], i32 [[TMP0]])
1352 // AArch64-NEXT: ret i32 [[TMP1]]
1354 uint32_t test_crc32h(uint32_t a
, uint16_t b
) {
1355 return __crc32h(a
, b
);
1358 // AArch32-LABEL: @test_crc32w(
1359 // AArch32-NEXT: entry:
1360 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.crc32w(i32 [[A:%.*]], i32 [[B:%.*]])
1361 // AArch32-NEXT: ret i32 [[TMP0]]
1363 // AArch64-LABEL: @test_crc32w(
1364 // AArch64-NEXT: entry:
1365 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32w(i32 [[A:%.*]], i32 [[B:%.*]])
1366 // AArch64-NEXT: ret i32 [[TMP0]]
1368 uint32_t test_crc32w(uint32_t a
, uint32_t b
) {
1369 return __crc32w(a
, b
);
1372 // AArch32-LABEL: @test_crc32d(
1373 // AArch32-NEXT: entry:
1374 // AArch32-NEXT: [[TMP0:%.*]] = trunc i64 [[B:%.*]] to i32
1375 // AArch32-NEXT: [[TMP1:%.*]] = lshr i64 [[B]], 32
1376 // AArch32-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
1377 // AArch32-NEXT: [[TMP3:%.*]] = call i32 @llvm.arm.crc32w(i32 [[A:%.*]], i32 [[TMP0]])
1378 // AArch32-NEXT: [[TMP4:%.*]] = call i32 @llvm.arm.crc32w(i32 [[TMP3]], i32 [[TMP2]])
1379 // AArch32-NEXT: ret i32 [[TMP4]]
1381 // AArch64-LABEL: @test_crc32d(
1382 // AArch64-NEXT: entry:
1383 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32x(i32 [[A:%.*]], i64 [[B:%.*]])
1384 // AArch64-NEXT: ret i32 [[TMP0]]
1386 uint32_t test_crc32d(uint32_t a
, uint64_t b
) {
1387 return __crc32d(a
, b
);
1390 // AArch32-LABEL: @test_crc32cb(
1391 // AArch32-NEXT: entry:
1392 // AArch32-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32
1393 // AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32cb(i32 [[A:%.*]], i32 [[TMP0]])
1394 // AArch32-NEXT: ret i32 [[TMP1]]
1396 // AArch64-LABEL: @test_crc32cb(
1397 // AArch64-NEXT: entry:
1398 // AArch64-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32
1399 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32cb(i32 [[A:%.*]], i32 [[TMP0]])
1400 // AArch64-NEXT: ret i32 [[TMP1]]
1402 uint32_t test_crc32cb(uint32_t a
, uint8_t b
) {
1403 return __crc32cb(a
, b
);
1406 // AArch32-LABEL: @test_crc32ch(
1407 // AArch32-NEXT: entry:
1408 // AArch32-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32
1409 // AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32ch(i32 [[A:%.*]], i32 [[TMP0]])
1410 // AArch32-NEXT: ret i32 [[TMP1]]
1412 // AArch64-LABEL: @test_crc32ch(
1413 // AArch64-NEXT: entry:
1414 // AArch64-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32
1415 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32ch(i32 [[A:%.*]], i32 [[TMP0]])
1416 // AArch64-NEXT: ret i32 [[TMP1]]
1418 uint32_t test_crc32ch(uint32_t a
, uint16_t b
) {
1419 return __crc32ch(a
, b
);
1422 // AArch32-LABEL: @test_crc32cw(
1423 // AArch32-NEXT: entry:
1424 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]])
1425 // AArch32-NEXT: ret i32 [[TMP0]]
1427 // AArch64-LABEL: @test_crc32cw(
1428 // AArch64-NEXT: entry:
1429 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]])
1430 // AArch64-NEXT: ret i32 [[TMP0]]
1432 uint32_t test_crc32cw(uint32_t a
, uint32_t b
) {
1433 return __crc32cw(a
, b
);
1436 // AArch32-LABEL: @test_crc32cd(
1437 // AArch32-NEXT: entry:
1438 // AArch32-NEXT: [[TMP0:%.*]] = trunc i64 [[B:%.*]] to i32
1439 // AArch32-NEXT: [[TMP1:%.*]] = lshr i64 [[B]], 32
1440 // AArch32-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
1441 // AArch32-NEXT: [[TMP3:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[A:%.*]], i32 [[TMP0]])
1442 // AArch32-NEXT: [[TMP4:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[TMP3]], i32 [[TMP2]])
1443 // AArch32-NEXT: ret i32 [[TMP4]]
1445 // AArch64-LABEL: @test_crc32cd(
1446 // AArch64-NEXT: entry:
1447 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cx(i32 [[A:%.*]], i64 [[B:%.*]])
1448 // AArch64-NEXT: ret i32 [[TMP0]]
1450 uint32_t test_crc32cd(uint32_t a
, uint64_t b
) {
1451 return __crc32cd(a
, b
);
1454 /* 10.1 Special register intrinsics */
1455 // AArch32-LABEL: @test_rsr(
1456 // AArch32-NEXT: entry:
1457 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META5:![0-9]+]])
1458 // AArch32-NEXT: ret i32 [[TMP0]]
1460 // AArch64-LABEL: @test_rsr(
1461 // AArch64-NEXT: entry:
1462 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META4:![0-9]+]])
1463 // AArch64-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
1464 // AArch64-NEXT: ret i32 [[TMP1]]
1466 uint32_t test_rsr() {
1467 #ifdef __ARM_32BIT_STATE
1468 return __arm_rsr("cp1:2:c3:c4:5");
1470 return __arm_rsr("1:2:3:4:5");
1474 // AArch32-LABEL: @test_rsr64(
1475 // AArch32-NEXT: entry:
1476 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META6:![0-9]+]])
1477 // AArch32-NEXT: ret i64 [[TMP0]]
1479 // AArch64-LABEL: @test_rsr64(
1480 // AArch64-NEXT: entry:
1481 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META4]])
1482 // AArch64-NEXT: ret i64 [[TMP0]]
1484 uint64_t test_rsr64() {
1485 #ifdef __ARM_32BIT_STATE
1486 return __arm_rsr64("cp1:2:c3");
1488 return __arm_rsr64("1:2:3:4:5");
1492 #ifdef __ARM_FEATURE_SYSREG128
1493 // AArch6494D128-LABEL: @test_rsr128(
1494 // AArch6494D128-NEXT: entry:
1495 // AArch6494D128-NEXT: [[TMP0:%.*]] = call i128 @llvm.read_volatile_register.i128(metadata [[META4]])
1496 // AArch6494D128-NEXT: ret i128 [[TMP0]]
1498 __uint128_t
test_rsr128() {
1499 return __arm_rsr128("1:2:3:4:5");
1503 // AArch32-LABEL: @test_rsrp(
1504 // AArch32-NEXT: entry:
1505 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META7:![0-9]+]])
1506 // AArch32-NEXT: [[TMP1:%.*]] = inttoptr i32 [[TMP0]] to ptr
1507 // AArch32-NEXT: ret ptr [[TMP1]]
1509 // AArch64-LABEL: @test_rsrp(
1510 // AArch64-NEXT: entry:
1511 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META5:![0-9]+]])
1512 // AArch64-NEXT: [[TMP1:%.*]] = inttoptr i64 [[TMP0]] to ptr
1513 // AArch64-NEXT: ret ptr [[TMP1]]
1516 return __arm_rsrp("sysreg");
1519 // AArch32-LABEL: @test_wsr(
1520 // AArch32-NEXT: entry:
1521 // AArch32-NEXT: call void @llvm.write_register.i32(metadata [[META5]], i32 [[V:%.*]])
1522 // AArch32-NEXT: ret void
1524 // AArch64-LABEL: @test_wsr(
1525 // AArch64-NEXT: entry:
1526 // AArch64-NEXT: [[TMP0:%.*]] = zext i32 [[V:%.*]] to i64
1527 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META4]], i64 [[TMP0]])
1528 // AArch64-NEXT: ret void
1530 void test_wsr(uint32_t v
) {
1531 #ifdef __ARM_32BIT_STATE
1532 __arm_wsr("cp1:2:c3:c4:5", v
);
1534 __arm_wsr("1:2:3:4:5", v
);
1538 // AArch32-LABEL: @test_wsr64(
1539 // AArch32-NEXT: entry:
1540 // AArch32-NEXT: call void @llvm.write_register.i64(metadata [[META6]], i64 [[V:%.*]])
1541 // AArch32-NEXT: ret void
1543 // AArch64-LABEL: @test_wsr64(
1544 // AArch64-NEXT: entry:
1545 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META4]], i64 [[V:%.*]])
1546 // AArch64-NEXT: ret void
1548 void test_wsr64(uint64_t v
) {
1549 #ifdef __ARM_32BIT_STATE
1550 __arm_wsr64("cp1:2:c3", v
);
1552 __arm_wsr64("1:2:3:4:5", v
);
1556 #ifdef __ARM_FEATURE_SYSREG128
1557 // AArch6494D128-LABEL: @test_wsr128(
1558 // AArch6494D128-NEXT: entry:
1559 // AArch6494D128-NEXT: call void @llvm.write_register.i128(metadata [[META4]], i128 [[V:%.*]])
1560 // AArch6494D128-NEXT: ret void
1562 void test_wsr128(__uint128_t v
) {
1563 __arm_wsr128("1:2:3:4:5", v
);
1568 // AArch32-LABEL: @test_wsrp(
1569 // AArch32-NEXT: entry:
1570 // AArch32-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[V:%.*]] to i32
1571 // AArch32-NEXT: call void @llvm.write_register.i32(metadata [[META7]], i32 [[TMP0]])
1572 // AArch32-NEXT: ret void
1574 // AArch64-LABEL: @test_wsrp(
1575 // AArch64-NEXT: entry:
1576 // AArch64-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[V:%.*]] to i64
1577 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META5]], i64 [[TMP0]])
1578 // AArch64-NEXT: ret void
1580 void test_wsrp(void *v
) {
1581 __arm_wsrp("sysreg", v
);
1584 // AArch32-LABEL: @test_rsrf(
1585 // AArch32-NEXT: entry:
1586 // AArch32-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
1587 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META5]])
1588 // AArch32-NEXT: store i32 [[TMP0]], ptr [[REF_TMP]], align 4
1589 // AArch32-NEXT: [[TMP1:%.*]] = load float, ptr [[REF_TMP]], align 4
1590 // AArch32-NEXT: ret float [[TMP1]]
1592 // AArch64-LABEL: @test_rsrf(
1593 // AArch64-NEXT: entry:
1594 // AArch64-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
1595 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META4]])
1596 // AArch64-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
1597 // AArch64-NEXT: store i32 [[TMP1]], ptr [[REF_TMP]], align 4
1598 // AArch64-NEXT: [[TMP2:%.*]] = load float, ptr [[REF_TMP]], align 4
1599 // AArch64-NEXT: ret float [[TMP2]]
1602 #ifdef __ARM_32BIT_STATE
1603 return __arm_rsrf("cp1:2:c3:c4:5");
1605 return __arm_rsrf("1:2:3:4:5");
1609 // AArch32-LABEL: @test_rsrf64(
1610 // AArch32-NEXT: entry:
1611 // AArch32-NEXT: [[REF_TMP:%.*]] = alloca i64, align 8
1612 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META6]])
1613 // AArch32-NEXT: store i64 [[TMP0]], ptr [[REF_TMP]], align 8
1614 // AArch32-NEXT: [[TMP1:%.*]] = load double, ptr [[REF_TMP]], align 8
1615 // AArch32-NEXT: ret double [[TMP1]]
1617 // AArch64-LABEL: @test_rsrf64(
1618 // AArch64-NEXT: entry:
1619 // AArch64-NEXT: [[REF_TMP:%.*]] = alloca i64, align 8
1620 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META4]])
1621 // AArch64-NEXT: store i64 [[TMP0]], ptr [[REF_TMP]], align 8
1622 // AArch64-NEXT: [[TMP1:%.*]] = load double, ptr [[REF_TMP]], align 8
1623 // AArch64-NEXT: ret double [[TMP1]]
1625 double test_rsrf64() {
1626 #ifdef __ARM_32BIT_STATE
1627 return __arm_rsrf64("cp1:2:c3");
1629 return __arm_rsrf64("1:2:3:4:5");
1633 // AArch32-LABEL: @test_wsrf(
1634 // AArch32-NEXT: entry:
1635 // AArch32-NEXT: [[V_ADDR:%.*]] = alloca float, align 4
1636 // AArch32-NEXT: store float [[V:%.*]], ptr [[V_ADDR]], align 4
1637 // AArch32-NEXT: [[TMP0:%.*]] = load i32, ptr [[V_ADDR]], align 4
1638 // AArch32-NEXT: call void @llvm.write_register.i32(metadata [[META5]], i32 [[TMP0]])
1639 // AArch32-NEXT: ret void
1641 // AArch64-LABEL: @test_wsrf(
1642 // AArch64-NEXT: entry:
1643 // AArch64-NEXT: [[V_ADDR:%.*]] = alloca float, align 4
1644 // AArch64-NEXT: store float [[V:%.*]], ptr [[V_ADDR]], align 4
1645 // AArch64-NEXT: [[TMP0:%.*]] = load i32, ptr [[V_ADDR]], align 4
1646 // AArch64-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
1647 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META4]], i64 [[TMP1]])
1648 // AArch64-NEXT: ret void
1650 void test_wsrf(float v
) {
1651 #ifdef __ARM_32BIT_STATE
1652 __arm_wsrf("cp1:2:c3:c4:5", v
);
1654 __arm_wsrf("1:2:3:4:5", v
);
1658 // AArch32-LABEL: @test_wsrf64(
1659 // AArch32-NEXT: entry:
1660 // AArch32-NEXT: [[V_ADDR:%.*]] = alloca double, align 8
1661 // AArch32-NEXT: store double [[V:%.*]], ptr [[V_ADDR]], align 8
1662 // AArch32-NEXT: [[TMP0:%.*]] = load i64, ptr [[V_ADDR]], align 8
1663 // AArch32-NEXT: call void @llvm.write_register.i64(metadata [[META6]], i64 [[TMP0]])
1664 // AArch32-NEXT: ret void
1666 // AArch64-LABEL: @test_wsrf64(
1667 // AArch64-NEXT: entry:
1668 // AArch64-NEXT: [[V_ADDR:%.*]] = alloca double, align 8
1669 // AArch64-NEXT: store double [[V:%.*]], ptr [[V_ADDR]], align 8
1670 // AArch64-NEXT: [[TMP0:%.*]] = load i64, ptr [[V_ADDR]], align 8
1671 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META4]], i64 [[TMP0]])
1672 // AArch64-NEXT: ret void
1674 void test_wsrf64(double v
) {
1675 #ifdef __ARM_32BIT_STATE
1676 __arm_wsrf64("cp1:2:c3", v
);
1678 __arm_wsrf64("1:2:3:4:5", v
);
1682 #if defined(__ARM_64BIT_STATE) && defined(__ARM_FEATURE_JCVT)
1683 // AArch6483-LABEL: @test_jcvt(
1684 // AArch6483-NEXT: entry:
1685 // AArch6483-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.fjcvtzs(double [[V:%.*]])
1686 // AArch6483-NEXT: ret i32 [[TMP0]]
1688 int32_t test_jcvt(double v
) {
1693 #if defined(__ARM_FEATURE_DIRECTED_ROUNDING) && defined(__ARM_64BIT_STATE)
1695 // AArch64-LABEL: @test_rintn(
1696 // AArch64-NEXT: entry:
1697 // AArch64-NEXT: call double @llvm.roundeven.f64(double [[TMP0:%.*]])
1698 double test_rintn(double a
) {
1702 // AArch64-LABEL: @test_rintnf(
1703 // AArch64-NEXT: entry:
1704 // AArch64-NEXT: call float @llvm.roundeven.f32(float [[TMP0:%.*]])
1705 float test_rintnf(float b
) {
1710 #if defined(__ARM_64BIT_STATE) && defined(__ARM_FEATURE_RNG)
1712 // AArch6485-LABEL: @test_rndr(
1713 // AArch6485-NEXT: entry:
1714 // AArch6485-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndr()
1715 // AArch6485-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
1716 // AArch6485-NEXT: [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
1717 // AArch6485-NEXT: store i64 [[TMP1]], ptr [[__ADDR:%.*]], align 8
1718 // AArch6485-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
1719 // AArch6485-NEXT: ret i32 [[TMP3]]
1721 int test_rndr(uint64_t *__addr
) {
1722 return __rndr(__addr
);
1725 // AArch6485-LABEL: @test_rndrrs(
1726 // AArch6485-NEXT: entry:
1727 // AArch6485-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndrrs()
1728 // AArch6485-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
1729 // AArch6485-NEXT: [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
1730 // AArch6485-NEXT: store i64 [[TMP1]], ptr [[__ADDR:%.*]], align 8
1731 // AArch6485-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
1732 // AArch6485-NEXT: ret i32 [[TMP3]]
1734 int test_rndrrs(uint64_t *__addr
) {
1735 return __rndrrs(__addr
);