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-eabi -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-eabi -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-eabi -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-eabi -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 [[LOOP7:![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: [[TMP1:%.*]] = trunc i64 [[LDXR_I]] to i32
158 // AArch64-NEXT: [[TMP2:%.*]] = zext i32 [[X:%.*]] to i64
159 // AArch64-NEXT: [[STXR_I:%.*]] = call i32 @llvm.aarch64.stxr.p0(i64 [[TMP2]], 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 [[LOOP6:![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 uint32_t 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: [[CONV_I:%.*]] = sext i32 [[CAST_I]] to i64
349 // AArch64-NEXT: ret i64 [[CONV_I]]
351 long test_clzl(long t
) {
355 // ARM-LABEL: @test_clzll(
357 // ARM-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false)
358 // ARM-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32
359 // ARM-NEXT: [[CONV_I:%.*]] = sext i32 [[CAST_I]] to i64
360 // ARM-NEXT: ret i64 [[CONV_I]]
362 uint64_t test_clzll(uint64_t t
) {
366 // AArch32-LABEL: @test_cls(
367 // AArch32-NEXT: entry:
368 // AArch32-NEXT: [[CLS_I:%.*]] = call i32 @llvm.arm.cls(i32 [[T:%.*]])
369 // AArch32-NEXT: ret i32 [[CLS_I]]
371 // AArch64-LABEL: @test_cls(
372 // AArch64-NEXT: entry:
373 // AArch64-NEXT: [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls(i32 [[T:%.*]])
374 // AArch64-NEXT: ret i32 [[CLS_I]]
376 unsigned test_cls(uint32_t t
) {
380 // AArch32-LABEL: @test_clsl(
381 // AArch32-NEXT: entry:
382 // AArch32-NEXT: [[CLS_I:%.*]] = call i32 @llvm.arm.cls(i32 [[T:%.*]])
383 // AArch32-NEXT: ret i32 [[CLS_I]]
385 // AArch64-LABEL: @test_clsl(
386 // AArch64-NEXT: entry:
387 // AArch64-NEXT: [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls64(i64 [[T:%.*]])
388 // AArch64-NEXT: ret i32 [[CLS_I]]
390 unsigned test_clsl(unsigned long t
) {
394 // AArch32-LABEL: @test_clsll(
395 // AArch32-NEXT: entry:
396 // AArch32-NEXT: [[CLS_I:%.*]] = call i32 @llvm.arm.cls64(i64 [[T:%.*]])
397 // AArch32-NEXT: ret i32 [[CLS_I]]
399 // AArch64-LABEL: @test_clsll(
400 // AArch64-NEXT: entry:
401 // AArch64-NEXT: [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls64(i64 [[T:%.*]])
402 // AArch64-NEXT: ret i32 [[CLS_I]]
404 unsigned test_clsll(uint64_t t
) {
408 // ARM-LABEL: @test_rev(
410 // ARM-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]])
411 // ARM-NEXT: ret i32 [[TMP0]]
413 uint32_t test_rev(uint32_t t
) {
417 // AArch32-LABEL: @test_revl(
418 // AArch32-NEXT: entry:
419 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]])
420 // AArch32-NEXT: ret i32 [[TMP0]]
422 // AArch64-LABEL: @test_revl(
423 // AArch64-NEXT: entry:
424 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]])
425 // AArch64-NEXT: ret i64 [[TMP0]]
427 long test_revl(long t
) {
431 // ARM-LABEL: @test_revll(
433 // ARM-NEXT: [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]])
434 // ARM-NEXT: ret i64 [[TMP0]]
436 uint64_t test_revll(uint64_t t
) {
440 // ARM-LABEL: @test_rev16(
442 // ARM-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]])
443 // ARM-NEXT: [[REM_I_I:%.*]] = urem i32 16, 32
444 // ARM-NEXT: [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0
445 // ARM-NEXT: br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]]
447 // ARM-NEXT: br label [[__REV16_EXIT:%.*]]
449 // ARM-NEXT: [[SHR_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I]]
450 // ARM-NEXT: [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]]
451 // ARM-NEXT: [[SHL_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I]]
452 // ARM-NEXT: [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]]
453 // ARM-NEXT: br label [[__REV16_EXIT]]
454 // ARM: __rev16.exit:
455 // ARM-NEXT: [[RETVAL_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ]
456 // ARM-NEXT: ret i32 [[RETVAL_I_I_0]]
458 uint32_t test_rev16(uint32_t t
) {
462 // AArch32-LABEL: @test_rev16l(
463 // AArch32-NEXT: entry:
464 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]])
465 // AArch32-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32
466 // AArch32-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0
467 // AArch32-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]]
468 // AArch32: if.then.i.i.i:
469 // AArch32-NEXT: br label [[__REV16L_EXIT:%.*]]
470 // AArch32: if.end.i.i.i:
471 // AArch32-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I_I]]
472 // AArch32-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]]
473 // AArch32-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I_I]]
474 // AArch32-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]]
475 // AArch32-NEXT: br label [[__REV16L_EXIT]]
476 // AArch32: __rev16l.exit:
477 // AArch32-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ]
478 // AArch32-NEXT: ret i32 [[RETVAL_I_I_I_0]]
480 // AArch64-LABEL: @test_rev16l(
481 // AArch64-NEXT: entry:
482 // AArch64-NEXT: [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32
483 // AArch64-NEXT: [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32
484 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]])
485 // AArch64-NEXT: [[REM_I_I10_I:%.*]] = urem i32 16, 32
486 // AArch64-NEXT: [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0
487 // AArch64-NEXT: br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I12_I:%.*]], label [[IF_END_I_I17_I:%.*]]
488 // AArch64: if.then.i.i12.i:
489 // AArch64-NEXT: br label [[__REV16_EXIT18_I:%.*]]
490 // AArch64: if.end.i.i17.i:
491 // AArch64-NEXT: [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]]
492 // AArch64-NEXT: [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]]
493 // AArch64-NEXT: [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]]
494 // AArch64-NEXT: [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]]
495 // AArch64-NEXT: br label [[__REV16_EXIT18_I]]
496 // AArch64: __rev16.exit18.i:
497 // AArch64-NEXT: [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I12_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I17_I]] ]
498 // AArch64-NEXT: [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64
499 // AArch64-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32
500 // AArch64-NEXT: [[CONV2_I:%.*]] = trunc i64 [[T]] to i32
501 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]])
502 // AArch64-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32
503 // AArch64-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0
504 // AArch64-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]]
505 // AArch64: if.then.i.i.i:
506 // AArch64-NEXT: br label [[__REV16LL_EXIT:%.*]]
507 // AArch64: if.end.i.i.i:
508 // AArch64-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]]
509 // AArch64-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]]
510 // AArch64-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]]
511 // AArch64-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]]
512 // AArch64-NEXT: br label [[__REV16LL_EXIT]]
513 // AArch64: __rev16ll.exit:
514 // AArch64-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ]
515 // AArch64-NEXT: [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64
516 // AArch64-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]]
517 // AArch64-NEXT: ret i64 [[OR_I]]
519 long test_rev16l(long t
) {
523 // ARM-LABEL: @test_rev16ll(
525 // ARM-NEXT: [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32
526 // ARM-NEXT: [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32
527 // ARM-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]])
528 // ARM-NEXT: [[REM_I_I10_I:%.*]] = urem i32 16, 32
529 // ARM-NEXT: [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0
530 // ARM-NEXT: br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I12_I:%.*]], label [[IF_END_I_I17_I:%.*]]
531 // ARM: if.then.i.i12.i:
532 // ARM-NEXT: br label [[__REV16_EXIT18_I:%.*]]
533 // ARM: if.end.i.i17.i:
534 // ARM-NEXT: [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]]
535 // ARM-NEXT: [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]]
536 // ARM-NEXT: [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]]
537 // ARM-NEXT: [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]]
538 // ARM-NEXT: br label [[__REV16_EXIT18_I]]
539 // ARM: __rev16.exit18.i:
540 // ARM-NEXT: [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I12_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I17_I]] ]
541 // ARM-NEXT: [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64
542 // ARM-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32
543 // ARM-NEXT: [[CONV2_I:%.*]] = trunc i64 [[T]] to i32
544 // ARM-NEXT: [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]])
545 // ARM-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32
546 // ARM-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0
547 // ARM-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]]
548 // ARM: if.then.i.i.i:
549 // ARM-NEXT: br label [[__REV16LL_EXIT:%.*]]
550 // ARM: if.end.i.i.i:
551 // ARM-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]]
552 // ARM-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]]
553 // ARM-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]]
554 // ARM-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]]
555 // ARM-NEXT: br label [[__REV16LL_EXIT]]
556 // ARM: __rev16ll.exit:
557 // ARM-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ]
558 // ARM-NEXT: [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64
559 // ARM-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]]
560 // ARM-NEXT: ret i64 [[OR_I]]
562 uint64_t test_rev16ll(uint64_t t
) {
566 // ARM-LABEL: @test_revsh(
568 // ARM-NEXT: [[TMP0:%.*]] = call i16 @llvm.bswap.i16(i16 [[T:%.*]])
569 // ARM-NEXT: ret i16 [[TMP0]]
571 int16_t test_revsh(int16_t t
) {
575 // ARM-LABEL: @test_rbit(
577 // ARM-NEXT: [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]])
578 // ARM-NEXT: ret i32 [[RBIT_I]]
580 uint32_t test_rbit(uint32_t t
) {
584 // AArch32-LABEL: @test_rbitl(
585 // AArch32-NEXT: entry:
586 // AArch32-NEXT: [[RBIT_I_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]])
587 // AArch32-NEXT: ret i32 [[RBIT_I_I]]
589 // AArch64-LABEL: @test_rbitl(
590 // AArch64-NEXT: entry:
591 // AArch64-NEXT: [[RBIT_I:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[T:%.*]])
592 // AArch64-NEXT: ret i64 [[RBIT_I]]
594 long test_rbitl(long t
) {
598 // AArch32-LABEL: @test_rbitll(
599 // AArch32-NEXT: entry:
600 // AArch32-NEXT: [[CONV_I:%.*]] = trunc i64 [[T:%.*]] to i32
601 // AArch32-NEXT: [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[CONV_I]])
602 // AArch32-NEXT: [[CONV1_I:%.*]] = zext i32 [[RBIT_I]] to i64
603 // AArch32-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32
604 // AArch32-NEXT: [[SHR_I:%.*]] = lshr i64 [[T]], 32
605 // AArch32-NEXT: [[CONV2_I:%.*]] = trunc i64 [[SHR_I]] to i32
606 // AArch32-NEXT: [[RBIT3_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[CONV2_I]])
607 // AArch32-NEXT: [[CONV4_I:%.*]] = zext i32 [[RBIT3_I]] to i64
608 // AArch32-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]]
609 // AArch32-NEXT: ret i64 [[OR_I]]
611 // AArch64-LABEL: @test_rbitll(
612 // AArch64-NEXT: entry:
613 // AArch64-NEXT: [[RBIT_I:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[T:%.*]])
614 // AArch64-NEXT: ret i64 [[RBIT_I]]
616 uint64_t test_rbitll(uint64_t t
) {
620 /* 9.4 Saturating intrinsics */
621 #ifdef __ARM_FEATURE_SAT
622 /* 9.4.1 Width-specified saturation intrinsics */
623 // AArch32-LABEL: @test_ssat(
624 // AArch32-NEXT: entry:
625 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssat(i32 [[T:%.*]], i32 1)
626 // AArch32-NEXT: ret i32 [[TMP0]]
628 int32_t test_ssat(int32_t t
) {
632 // AArch32-LABEL: @test_usat(
633 // AArch32-NEXT: entry:
634 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usat(i32 [[T:%.*]], i32 2)
635 // AArch32-NEXT: ret i32 [[TMP0]]
637 uint32_t test_usat(int32_t t
) {
642 /* 9.4.2 Saturating addition and subtraction intrinsics */
643 #ifdef __ARM_FEATURE_DSP
644 // AArch32-LABEL: @test_qadd(
645 // AArch32-NEXT: entry:
646 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[A:%.*]], i32 [[B:%.*]])
647 // AArch32-NEXT: ret i32 [[TMP0]]
649 int32_t test_qadd(int32_t a
, int32_t b
) {
653 // AArch32-LABEL: @test_qsub(
654 // AArch32-NEXT: entry:
655 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub(i32 [[A:%.*]], i32 [[B:%.*]])
656 // AArch32-NEXT: ret i32 [[TMP0]]
658 int32_t test_qsub(int32_t a
, int32_t b
) {
663 // AArch32-LABEL: @test_qdbl(
664 // AArch32-NEXT: entry:
665 // AArch32-NEXT: [[CALL:%.*]] = call i32 @f() #[[ATTR7:[0-9]+]]
666 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[CALL]], i32 [[CALL]])
667 // AArch32-NEXT: ret i32 [[TMP0]]
669 int32_t test_qdbl() {
675 * 9.3 16-bit multiplications
677 #if __ARM_FEATURE_DSP
678 // AArch32-LABEL: @test_smulbb(
679 // AArch32-NEXT: entry:
680 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulbb(i32 [[A:%.*]], i32 [[B:%.*]])
681 // AArch32-NEXT: ret i32 [[TMP0]]
683 int32_t test_smulbb(int32_t a
, int32_t b
) {
684 return __smulbb(a
, b
);
687 // AArch32-LABEL: @test_smulbt(
688 // AArch32-NEXT: entry:
689 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulbt(i32 [[A:%.*]], i32 [[B:%.*]])
690 // AArch32-NEXT: ret i32 [[TMP0]]
692 int32_t test_smulbt(int32_t a
, int32_t b
) {
693 return __smulbt(a
, b
);
696 // AArch32-LABEL: @test_smultb(
697 // AArch32-NEXT: entry:
698 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smultb(i32 [[A:%.*]], i32 [[B:%.*]])
699 // AArch32-NEXT: ret i32 [[TMP0]]
701 int32_t test_smultb(int32_t a
, int32_t b
) {
702 return __smultb(a
, b
);
705 // AArch32-LABEL: @test_smultt(
706 // AArch32-NEXT: entry:
707 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smultt(i32 [[A:%.*]], i32 [[B:%.*]])
708 // AArch32-NEXT: ret i32 [[TMP0]]
710 int32_t test_smultt(int32_t a
, int32_t b
) {
711 return __smultt(a
, b
);
714 // AArch32-LABEL: @test_smulwb(
715 // AArch32-NEXT: entry:
716 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulwb(i32 [[A:%.*]], i32 [[B:%.*]])
717 // AArch32-NEXT: ret i32 [[TMP0]]
719 int32_t test_smulwb(int32_t a
, int32_t b
) {
720 return __smulwb(a
, b
);
723 // AArch32-LABEL: @test_smulwt(
724 // AArch32-NEXT: entry:
725 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulwt(i32 [[A:%.*]], i32 [[B:%.*]])
726 // AArch32-NEXT: ret i32 [[TMP0]]
728 int32_t test_smulwt(int32_t a
, int32_t b
) {
729 return __smulwt(a
, b
);
733 /* 9.4.3 Accumultating multiplications */
734 #if __ARM_FEATURE_DSP
735 // AArch32-LABEL: @test_smlabb(
736 // AArch32-NEXT: entry:
737 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlabb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
738 // AArch32-NEXT: ret i32 [[TMP0]]
740 int32_t test_smlabb(int32_t a
, int32_t b
, int32_t c
) {
741 return __smlabb(a
, b
, c
);
744 // AArch32-LABEL: @test_smlabt(
745 // AArch32-NEXT: entry:
746 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlabt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
747 // AArch32-NEXT: ret i32 [[TMP0]]
749 int32_t test_smlabt(int32_t a
, int32_t b
, int32_t c
) {
750 return __smlabt(a
, b
, c
);
753 // AArch32-LABEL: @test_smlatb(
754 // AArch32-NEXT: entry:
755 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlatb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
756 // AArch32-NEXT: ret i32 [[TMP0]]
758 int32_t test_smlatb(int32_t a
, int32_t b
, int32_t c
) {
759 return __smlatb(a
, b
, c
);
762 // AArch32-LABEL: @test_smlatt(
763 // AArch32-NEXT: entry:
764 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlatt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
765 // AArch32-NEXT: ret i32 [[TMP0]]
767 int32_t test_smlatt(int32_t a
, int32_t b
, int32_t c
) {
768 return __smlatt(a
, b
, c
);
771 // AArch32-LABEL: @test_smlawb(
772 // AArch32-NEXT: entry:
773 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlawb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
774 // AArch32-NEXT: ret i32 [[TMP0]]
776 int32_t test_smlawb(int32_t a
, int32_t b
, int32_t c
) {
777 return __smlawb(a
, b
, c
);
780 // AArch32-LABEL: @test_smlawt(
781 // AArch32-NEXT: entry:
782 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlawt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
783 // AArch32-NEXT: ret i32 [[TMP0]]
785 int32_t test_smlawt(int32_t a
, int32_t b
, int32_t c
) {
786 return __smlawt(a
, b
, c
);
790 /* 9.5.4 Parallel 16-bit saturation */
791 #if __ARM_FEATURE_SIMD32
792 // AArch32-LABEL: @test_ssat16(
793 // AArch32-NEXT: entry:
794 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssat16(i32 [[A:%.*]], i32 15)
795 // AArch32-NEXT: ret i32 [[TMP0]]
797 int16x2_t
test_ssat16(int16x2_t a
) {
798 return __ssat16(a
, 15);
801 // AArch32-LABEL: @test_usat16(
802 // AArch32-NEXT: entry:
803 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usat16(i32 [[A:%.*]], i32 15)
804 // AArch32-NEXT: ret i32 [[TMP0]]
806 uint16x2_t
test_usat16(int16x2_t a
) {
807 return __usat16(a
, 15);
811 /* 9.5.5 Packing and unpacking */
812 #if __ARM_FEATURE_SIMD32
813 // AArch32-LABEL: @test_sxtab16(
814 // AArch32-NEXT: entry:
815 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sxtab16(i32 [[A:%.*]], i32 [[B:%.*]])
816 // AArch32-NEXT: ret i32 [[TMP0]]
818 int16x2_t
test_sxtab16(int16x2_t a
, int8x4_t b
) {
819 return __sxtab16(a
, b
);
822 // AArch32-LABEL: @test_sxtb16(
823 // AArch32-NEXT: entry:
824 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sxtb16(i32 [[A:%.*]])
825 // AArch32-NEXT: ret i32 [[TMP0]]
827 int16x2_t
test_sxtb16(int8x4_t a
) {
831 // AArch32-LABEL: @test_uxtab16(
832 // AArch32-NEXT: entry:
833 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uxtab16(i32 [[A:%.*]], i32 [[B:%.*]])
834 // AArch32-NEXT: ret i32 [[TMP0]]
836 int16x2_t
test_uxtab16(int16x2_t a
, int8x4_t b
) {
837 return __uxtab16(a
, b
);
840 // AArch32-LABEL: @test_uxtb16(
841 // AArch32-NEXT: entry:
842 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uxtb16(i32 [[A:%.*]])
843 // AArch32-NEXT: ret i32 [[TMP0]]
845 int16x2_t
test_uxtb16(int8x4_t a
) {
850 /* 9.5.6 Parallel selection */
851 #if __ARM_FEATURE_SIMD32
852 // AArch32-LABEL: @test_sel(
853 // AArch32-NEXT: entry:
854 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sel(i32 [[A:%.*]], i32 [[B:%.*]])
855 // AArch32-NEXT: ret i32 [[TMP0]]
857 uint8x4_t
test_sel(uint8x4_t a
, uint8x4_t b
) {
862 /* 9.5.7 Parallel 8-bit addition and subtraction */
863 #if __ARM_FEATURE_SIMD32
864 // AArch32-LABEL: @test_qadd8(
865 // AArch32-NEXT: entry:
866 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd8(i32 [[A:%.*]], i32 [[B:%.*]])
867 // AArch32-NEXT: ret i32 [[TMP0]]
869 int16x2_t
test_qadd8(int8x4_t a
, int8x4_t b
) {
870 return __qadd8(a
, b
);
873 // AArch32-LABEL: @test_qsub8(
874 // AArch32-NEXT: entry:
875 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub8(i32 [[A:%.*]], i32 [[B:%.*]])
876 // AArch32-NEXT: ret i32 [[TMP0]]
878 int8x4_t
test_qsub8(int8x4_t a
, int8x4_t b
) {
879 return __qsub8(a
, b
);
882 // AArch32-LABEL: @test_sadd8(
883 // AArch32-NEXT: entry:
884 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sadd8(i32 [[A:%.*]], i32 [[B:%.*]])
885 // AArch32-NEXT: ret i32 [[TMP0]]
887 int8x4_t
test_sadd8(int8x4_t a
, int8x4_t b
) {
888 return __sadd8(a
, b
);
891 // AArch32-LABEL: @test_shadd8(
892 // AArch32-NEXT: entry:
893 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shadd8(i32 [[A:%.*]], i32 [[B:%.*]])
894 // AArch32-NEXT: ret i32 [[TMP0]]
896 int8x4_t
test_shadd8(int8x4_t a
, int8x4_t b
) {
897 return __shadd8(a
, b
);
900 // AArch32-LABEL: @test_shsub8(
901 // AArch32-NEXT: entry:
902 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shsub8(i32 [[A:%.*]], i32 [[B:%.*]])
903 // AArch32-NEXT: ret i32 [[TMP0]]
905 int8x4_t
test_shsub8(int8x4_t a
, int8x4_t b
) {
906 return __shsub8(a
, b
);
909 // AArch32-LABEL: @test_ssub8(
910 // AArch32-NEXT: entry:
911 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssub8(i32 [[A:%.*]], i32 [[B:%.*]])
912 // AArch32-NEXT: ret i32 [[TMP0]]
914 int8x4_t
test_ssub8(int8x4_t a
, int8x4_t b
) {
915 return __ssub8(a
, b
);
918 // AArch32-LABEL: @test_uadd8(
919 // AArch32-NEXT: entry:
920 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uadd8(i32 [[A:%.*]], i32 [[B:%.*]])
921 // AArch32-NEXT: ret i32 [[TMP0]]
923 uint8x4_t
test_uadd8(uint8x4_t a
, uint8x4_t b
) {
924 return __uadd8(a
, b
);
927 // AArch32-LABEL: @test_uhadd8(
928 // AArch32-NEXT: entry:
929 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhadd8(i32 [[A:%.*]], i32 [[B:%.*]])
930 // AArch32-NEXT: ret i32 [[TMP0]]
932 uint8x4_t
test_uhadd8(uint8x4_t a
, uint8x4_t b
) {
933 return __uhadd8(a
, b
);
936 // AArch32-LABEL: @test_uhsub8(
937 // AArch32-NEXT: entry:
938 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhsub8(i32 [[A:%.*]], i32 [[B:%.*]])
939 // AArch32-NEXT: ret i32 [[TMP0]]
941 uint8x4_t
test_uhsub8(uint8x4_t a
, uint8x4_t b
) {
942 return __uhsub8(a
, b
);
945 // AArch32-LABEL: @test_uqadd8(
946 // AArch32-NEXT: entry:
947 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqadd8(i32 [[A:%.*]], i32 [[B:%.*]])
948 // AArch32-NEXT: ret i32 [[TMP0]]
950 uint8x4_t
test_uqadd8(uint8x4_t a
, uint8x4_t b
) {
951 return __uqadd8(a
, b
);
954 // AArch32-LABEL: @test_uqsub8(
955 // AArch32-NEXT: entry:
956 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqsub8(i32 [[A:%.*]], i32 [[B:%.*]])
957 // AArch32-NEXT: ret i32 [[TMP0]]
959 uint8x4_t
test_uqsub8(uint8x4_t a
, uint8x4_t b
) {
960 return __uqsub8(a
, b
);
963 // AArch32-LABEL: @test_usub8(
964 // AArch32-NEXT: entry:
965 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usub8(i32 [[A:%.*]], i32 [[B:%.*]])
966 // AArch32-NEXT: ret i32 [[TMP0]]
968 uint8x4_t
test_usub8(uint8x4_t a
, uint8x4_t b
) {
969 return __usub8(a
, b
);
973 /* 9.5.8 Sum of 8-bit absolute differences */
974 #if __ARM_FEATURE_SIMD32
975 // AArch32-LABEL: @test_usad8(
976 // AArch32-NEXT: entry:
977 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usad8(i32 [[A:%.*]], i32 [[B:%.*]])
978 // AArch32-NEXT: ret i32 [[TMP0]]
980 uint32_t test_usad8(uint8x4_t a
, uint8x4_t b
) {
981 return __usad8(a
, b
);
984 // AArch32-LABEL: @test_usada8(
985 // AArch32-NEXT: entry:
986 // AArch32-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32
987 // AArch32-NEXT: [[CONV1:%.*]] = zext i8 [[B:%.*]] to i32
988 // AArch32-NEXT: [[CONV2:%.*]] = zext i8 [[C:%.*]] to i32
989 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usada8(i32 [[CONV]], i32 [[CONV1]], i32 [[CONV2]])
990 // AArch32-NEXT: ret i32 [[TMP0]]
992 uint32_t test_usada8(uint8_t a
, uint8_t b
, uint8_t c
) {
993 return __usada8(a
, b
, c
);
997 /* 9.5.9 Parallel 16-bit addition and subtraction */
998 #if __ARM_FEATURE_SIMD32
999 // AArch32-LABEL: @test_qadd16(
1000 // AArch32-NEXT: entry:
1001 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd16(i32 [[A:%.*]], i32 [[B:%.*]])
1002 // AArch32-NEXT: ret i32 [[TMP0]]
1004 int16x2_t
test_qadd16(int16x2_t a
, int16x2_t b
) {
1005 return __qadd16(a
, b
);
1008 // AArch32-LABEL: @test_qasx(
1009 // AArch32-NEXT: entry:
1010 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qasx(i32 [[A:%.*]], i32 [[B:%.*]])
1011 // AArch32-NEXT: ret i32 [[TMP0]]
1013 int16x2_t
test_qasx(int16x2_t a
, int16x2_t b
) {
1014 return __qasx(a
, b
);
1017 // AArch32-LABEL: @test_qsax(
1018 // AArch32-NEXT: entry:
1019 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsax(i32 [[A:%.*]], i32 [[B:%.*]])
1020 // AArch32-NEXT: ret i32 [[TMP0]]
1022 int16x2_t
test_qsax(int16x2_t a
, int16x2_t b
) {
1023 return __qsax(a
, b
);
1026 // AArch32-LABEL: @test_qsub16(
1027 // AArch32-NEXT: entry:
1028 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub16(i32 [[A:%.*]], i32 [[B:%.*]])
1029 // AArch32-NEXT: ret i32 [[TMP0]]
1031 int16x2_t
test_qsub16(int16x2_t a
, int16x2_t b
) {
1032 return __qsub16(a
, b
);
1035 // AArch32-LABEL: @test_sadd16(
1036 // AArch32-NEXT: entry:
1037 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sadd16(i32 [[A:%.*]], i32 [[B:%.*]])
1038 // AArch32-NEXT: ret i32 [[TMP0]]
1040 int16x2_t
test_sadd16(int16x2_t a
, int16x2_t b
) {
1041 return __sadd16(a
, b
);
1044 // AArch32-LABEL: @test_sasx(
1045 // AArch32-NEXT: entry:
1046 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sasx(i32 [[A:%.*]], i32 [[B:%.*]])
1047 // AArch32-NEXT: ret i32 [[TMP0]]
1049 int16x2_t
test_sasx(int16x2_t a
, int16x2_t b
) {
1050 return __sasx(a
, b
);
1053 // AArch32-LABEL: @test_shadd16(
1054 // AArch32-NEXT: entry:
1055 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shadd16(i32 [[A:%.*]], i32 [[B:%.*]])
1056 // AArch32-NEXT: ret i32 [[TMP0]]
1058 int16x2_t
test_shadd16(int16x2_t a
, int16x2_t b
) {
1059 return __shadd16(a
, b
);
1062 // AArch32-LABEL: @test_shasx(
1063 // AArch32-NEXT: entry:
1064 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shasx(i32 [[A:%.*]], i32 [[B:%.*]])
1065 // AArch32-NEXT: ret i32 [[TMP0]]
1067 int16x2_t
test_shasx(int16x2_t a
, int16x2_t b
) {
1068 return __shasx(a
, b
);
1071 // AArch32-LABEL: @test_shsax(
1072 // AArch32-NEXT: entry:
1073 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shsax(i32 [[A:%.*]], i32 [[B:%.*]])
1074 // AArch32-NEXT: ret i32 [[TMP0]]
1076 int16x2_t
test_shsax(int16x2_t a
, int16x2_t b
) {
1077 return __shsax(a
, b
);
1080 // AArch32-LABEL: @test_shsub16(
1081 // AArch32-NEXT: entry:
1082 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shsub16(i32 [[A:%.*]], i32 [[B:%.*]])
1083 // AArch32-NEXT: ret i32 [[TMP0]]
1085 int16x2_t
test_shsub16(int16x2_t a
, int16x2_t b
) {
1086 return __shsub16(a
, b
);
1089 // AArch32-LABEL: @test_ssax(
1090 // AArch32-NEXT: entry:
1091 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssax(i32 [[A:%.*]], i32 [[B:%.*]])
1092 // AArch32-NEXT: ret i32 [[TMP0]]
1094 int16x2_t
test_ssax(int16x2_t a
, int16x2_t b
) {
1095 return __ssax(a
, b
);
1098 // AArch32-LABEL: @test_ssub16(
1099 // AArch32-NEXT: entry:
1100 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssub16(i32 [[A:%.*]], i32 [[B:%.*]])
1101 // AArch32-NEXT: ret i32 [[TMP0]]
1103 int16x2_t
test_ssub16(int16x2_t a
, int16x2_t b
) {
1104 return __ssub16(a
, b
);
1107 // AArch32-LABEL: @test_uadd16(
1108 // AArch32-NEXT: entry:
1109 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uadd16(i32 [[A:%.*]], i32 [[B:%.*]])
1110 // AArch32-NEXT: ret i32 [[TMP0]]
1112 uint16x2_t
test_uadd16(uint16x2_t a
, uint16x2_t b
) {
1113 return __uadd16(a
, b
);
1116 // AArch32-LABEL: @test_uasx(
1117 // AArch32-NEXT: entry:
1118 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uasx(i32 [[A:%.*]], i32 [[B:%.*]])
1119 // AArch32-NEXT: ret i32 [[TMP0]]
1121 uint16x2_t
test_uasx(uint16x2_t a
, uint16x2_t b
) {
1122 return __uasx(a
, b
);
1125 // AArch32-LABEL: @test_uhadd16(
1126 // AArch32-NEXT: entry:
1127 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhadd16(i32 [[A:%.*]], i32 [[B:%.*]])
1128 // AArch32-NEXT: ret i32 [[TMP0]]
1130 uint16x2_t
test_uhadd16(uint16x2_t a
, uint16x2_t b
) {
1131 return __uhadd16(a
, b
);
1134 // AArch32-LABEL: @test_uhasx(
1135 // AArch32-NEXT: entry:
1136 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhasx(i32 [[A:%.*]], i32 [[B:%.*]])
1137 // AArch32-NEXT: ret i32 [[TMP0]]
1139 uint16x2_t
test_uhasx(uint16x2_t a
, uint16x2_t b
) {
1140 return __uhasx(a
, b
);
1143 // AArch32-LABEL: @test_uhsax(
1144 // AArch32-NEXT: entry:
1145 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhsax(i32 [[A:%.*]], i32 [[B:%.*]])
1146 // AArch32-NEXT: ret i32 [[TMP0]]
1148 uint16x2_t
test_uhsax(uint16x2_t a
, uint16x2_t b
) {
1149 return __uhsax(a
, b
);
1152 // AArch32-LABEL: @test_uhsub16(
1153 // AArch32-NEXT: entry:
1154 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhsub16(i32 [[A:%.*]], i32 [[B:%.*]])
1155 // AArch32-NEXT: ret i32 [[TMP0]]
1157 uint16x2_t
test_uhsub16(uint16x2_t a
, uint16x2_t b
) {
1158 return __uhsub16(a
, b
);
1161 // AArch32-LABEL: @test_uqadd16(
1162 // AArch32-NEXT: entry:
1163 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqadd16(i32 [[A:%.*]], i32 [[B:%.*]])
1164 // AArch32-NEXT: ret i32 [[TMP0]]
1166 uint16x2_t
test_uqadd16(uint16x2_t a
, uint16x2_t b
) {
1167 return __uqadd16(a
, b
);
1170 // AArch32-LABEL: @test_uqasx(
1171 // AArch32-NEXT: entry:
1172 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqasx(i32 [[A:%.*]], i32 [[B:%.*]])
1173 // AArch32-NEXT: ret i32 [[TMP0]]
1175 uint16x2_t
test_uqasx(uint16x2_t a
, uint16x2_t b
) {
1176 return __uqasx(a
, b
);
1179 // AArch32-LABEL: @test_uqsax(
1180 // AArch32-NEXT: entry:
1181 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqsax(i32 [[A:%.*]], i32 [[B:%.*]])
1182 // AArch32-NEXT: ret i32 [[TMP0]]
1184 uint16x2_t
test_uqsax(uint16x2_t a
, uint16x2_t b
) {
1185 return __uqsax(a
, b
);
1188 // AArch32-LABEL: @test_uqsub16(
1189 // AArch32-NEXT: entry:
1190 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqsub16(i32 [[A:%.*]], i32 [[B:%.*]])
1191 // AArch32-NEXT: ret i32 [[TMP0]]
1193 uint16x2_t
test_uqsub16(uint16x2_t a
, uint16x2_t b
) {
1194 return __uqsub16(a
, b
);
1197 // AArch32-LABEL: @test_usax(
1198 // AArch32-NEXT: entry:
1199 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usax(i32 [[A:%.*]], i32 [[B:%.*]])
1200 // AArch32-NEXT: ret i32 [[TMP0]]
1202 uint16x2_t
test_usax(uint16x2_t a
, uint16x2_t b
) {
1203 return __usax(a
, b
);
1206 // AArch32-LABEL: @test_usub16(
1207 // AArch32-NEXT: entry:
1208 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usub16(i32 [[A:%.*]], i32 [[B:%.*]])
1209 // AArch32-NEXT: ret i32 [[TMP0]]
1211 uint16x2_t
test_usub16(uint16x2_t a
, uint16x2_t b
) {
1212 return __usub16(a
, b
);
1216 /* 9.5.10 Parallel 16-bit multiplications */
1217 #if __ARM_FEATURE_SIMD32
1218 // AArch32-LABEL: @test_smlad(
1219 // AArch32-NEXT: entry:
1220 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlad(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
1221 // AArch32-NEXT: ret i32 [[TMP0]]
1223 int32_t test_smlad(int16x2_t a
, int16x2_t b
, int32_t c
) {
1224 return __smlad(a
, b
, c
);
1227 // AArch32-LABEL: @test_smladx(
1228 // AArch32-NEXT: entry:
1229 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smladx(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
1230 // AArch32-NEXT: ret i32 [[TMP0]]
1232 int32_t test_smladx(int16x2_t a
, int16x2_t b
, int32_t c
) {
1233 return __smladx(a
, b
, c
);
1236 // AArch32-LABEL: @test_smlald(
1237 // AArch32-NEXT: entry:
1238 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlald(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]])
1239 // AArch32-NEXT: ret i64 [[TMP0]]
1241 int64_t test_smlald(int16x2_t a
, int16x2_t b
, int64_t c
) {
1242 return __smlald(a
, b
, c
);
1245 // AArch32-LABEL: @test_smlaldx(
1246 // AArch32-NEXT: entry:
1247 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlaldx(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]])
1248 // AArch32-NEXT: ret i64 [[TMP0]]
1250 int64_t test_smlaldx(int16x2_t a
, int16x2_t b
, int64_t c
) {
1251 return __smlaldx(a
, b
, c
);
1254 // AArch32-LABEL: @test_smlsd(
1255 // AArch32-NEXT: entry:
1256 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlsd(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
1257 // AArch32-NEXT: ret i32 [[TMP0]]
1259 int32_t test_smlsd(int16x2_t a
, int16x2_t b
, int32_t c
) {
1260 return __smlsd(a
, b
, c
);
1263 // AArch32-LABEL: @test_smlsdx(
1264 // AArch32-NEXT: entry:
1265 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlsdx(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
1266 // AArch32-NEXT: ret i32 [[TMP0]]
1268 int32_t test_smlsdx(int16x2_t a
, int16x2_t b
, int32_t c
) {
1269 return __smlsdx(a
, b
, c
);
1272 // AArch32-LABEL: @test_smlsld(
1273 // AArch32-NEXT: entry:
1274 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlsld(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]])
1275 // AArch32-NEXT: ret i64 [[TMP0]]
1277 int64_t test_smlsld(int16x2_t a
, int16x2_t b
, int64_t c
) {
1278 return __smlsld(a
, b
, c
);
1281 // AArch32-LABEL: @test_smlsldx(
1282 // AArch32-NEXT: entry:
1283 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlsldx(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]])
1284 // AArch32-NEXT: ret i64 [[TMP0]]
1286 int64_t test_smlsldx(int16x2_t a
, int16x2_t b
, int64_t c
) {
1287 return __smlsldx(a
, b
, c
);
1290 // AArch32-LABEL: @test_smuad(
1291 // AArch32-NEXT: entry:
1292 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smuad(i32 [[A:%.*]], i32 [[B:%.*]])
1293 // AArch32-NEXT: ret i32 [[TMP0]]
1295 int32_t test_smuad(int16x2_t a
, int16x2_t b
) {
1296 return __smuad(a
, b
);
1299 // AArch32-LABEL: @test_smuadx(
1300 // AArch32-NEXT: entry:
1301 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smuadx(i32 [[A:%.*]], i32 [[B:%.*]])
1302 // AArch32-NEXT: ret i32 [[TMP0]]
1304 int32_t test_smuadx(int16x2_t a
, int16x2_t b
) {
1305 return __smuadx(a
, b
);
1308 // AArch32-LABEL: @test_smusd(
1309 // AArch32-NEXT: entry:
1310 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smusd(i32 [[A:%.*]], i32 [[B:%.*]])
1311 // AArch32-NEXT: ret i32 [[TMP0]]
1313 int32_t test_smusd(int16x2_t a
, int16x2_t b
) {
1314 return __smusd(a
, b
);
1317 // AArch32-LABEL: @test_smusdx(
1318 // AArch32-NEXT: entry:
1319 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smusdx(i32 [[A:%.*]], i32 [[B:%.*]])
1320 // AArch32-NEXT: ret i32 [[TMP0]]
1322 int32_t test_smusdx(int16x2_t a
, int16x2_t b
) {
1323 return __smusdx(a
, b
);
1327 /* 9.7 CRC32 intrinsics */
1328 // AArch32-LABEL: @test_crc32b(
1329 // AArch32-NEXT: entry:
1330 // AArch32-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32
1331 // AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32b(i32 [[A:%.*]], i32 [[TMP0]])
1332 // AArch32-NEXT: ret i32 [[TMP1]]
1334 // AArch64-LABEL: @test_crc32b(
1335 // AArch64-NEXT: entry:
1336 // AArch64-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32
1337 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32b(i32 [[A:%.*]], i32 [[TMP0]])
1338 // AArch64-NEXT: ret i32 [[TMP1]]
1340 uint32_t test_crc32b(uint32_t a
, uint8_t b
) {
1341 return __crc32b(a
, b
);
1344 // AArch32-LABEL: @test_crc32h(
1345 // AArch32-NEXT: entry:
1346 // AArch32-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32
1347 // AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32h(i32 [[A:%.*]], i32 [[TMP0]])
1348 // AArch32-NEXT: ret i32 [[TMP1]]
1350 // AArch64-LABEL: @test_crc32h(
1351 // AArch64-NEXT: entry:
1352 // AArch64-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32
1353 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32h(i32 [[A:%.*]], i32 [[TMP0]])
1354 // AArch64-NEXT: ret i32 [[TMP1]]
1356 uint32_t test_crc32h(uint32_t a
, uint16_t b
) {
1357 return __crc32h(a
, b
);
1360 // AArch32-LABEL: @test_crc32w(
1361 // AArch32-NEXT: entry:
1362 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.crc32w(i32 [[A:%.*]], i32 [[B:%.*]])
1363 // AArch32-NEXT: ret i32 [[TMP0]]
1365 // AArch64-LABEL: @test_crc32w(
1366 // AArch64-NEXT: entry:
1367 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32w(i32 [[A:%.*]], i32 [[B:%.*]])
1368 // AArch64-NEXT: ret i32 [[TMP0]]
1370 uint32_t test_crc32w(uint32_t a
, uint32_t b
) {
1371 return __crc32w(a
, b
);
1374 // AArch32-LABEL: @test_crc32d(
1375 // AArch32-NEXT: entry:
1376 // AArch32-NEXT: [[TMP0:%.*]] = trunc i64 [[B:%.*]] to i32
1377 // AArch32-NEXT: [[TMP1:%.*]] = lshr i64 [[B]], 32
1378 // AArch32-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
1379 // AArch32-NEXT: [[TMP3:%.*]] = call i32 @llvm.arm.crc32w(i32 [[A:%.*]], i32 [[TMP0]])
1380 // AArch32-NEXT: [[TMP4:%.*]] = call i32 @llvm.arm.crc32w(i32 [[TMP3]], i32 [[TMP2]])
1381 // AArch32-NEXT: ret i32 [[TMP4]]
1383 // AArch64-LABEL: @test_crc32d(
1384 // AArch64-NEXT: entry:
1385 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32x(i32 [[A:%.*]], i64 [[B:%.*]])
1386 // AArch64-NEXT: ret i32 [[TMP0]]
1388 uint32_t test_crc32d(uint32_t a
, uint64_t b
) {
1389 return __crc32d(a
, b
);
1392 // AArch32-LABEL: @test_crc32cb(
1393 // AArch32-NEXT: entry:
1394 // AArch32-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32
1395 // AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32cb(i32 [[A:%.*]], i32 [[TMP0]])
1396 // AArch32-NEXT: ret i32 [[TMP1]]
1398 // AArch64-LABEL: @test_crc32cb(
1399 // AArch64-NEXT: entry:
1400 // AArch64-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32
1401 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32cb(i32 [[A:%.*]], i32 [[TMP0]])
1402 // AArch64-NEXT: ret i32 [[TMP1]]
1404 uint32_t test_crc32cb(uint32_t a
, uint8_t b
) {
1405 return __crc32cb(a
, b
);
1408 // AArch32-LABEL: @test_crc32ch(
1409 // AArch32-NEXT: entry:
1410 // AArch32-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32
1411 // AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32ch(i32 [[A:%.*]], i32 [[TMP0]])
1412 // AArch32-NEXT: ret i32 [[TMP1]]
1414 // AArch64-LABEL: @test_crc32ch(
1415 // AArch64-NEXT: entry:
1416 // AArch64-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32
1417 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32ch(i32 [[A:%.*]], i32 [[TMP0]])
1418 // AArch64-NEXT: ret i32 [[TMP1]]
1420 uint32_t test_crc32ch(uint32_t a
, uint16_t b
) {
1421 return __crc32ch(a
, b
);
1424 // AArch32-LABEL: @test_crc32cw(
1425 // AArch32-NEXT: entry:
1426 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]])
1427 // AArch32-NEXT: ret i32 [[TMP0]]
1429 // AArch64-LABEL: @test_crc32cw(
1430 // AArch64-NEXT: entry:
1431 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]])
1432 // AArch64-NEXT: ret i32 [[TMP0]]
1434 uint32_t test_crc32cw(uint32_t a
, uint32_t b
) {
1435 return __crc32cw(a
, b
);
1438 // AArch32-LABEL: @test_crc32cd(
1439 // AArch32-NEXT: entry:
1440 // AArch32-NEXT: [[TMP0:%.*]] = trunc i64 [[B:%.*]] to i32
1441 // AArch32-NEXT: [[TMP1:%.*]] = lshr i64 [[B]], 32
1442 // AArch32-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
1443 // AArch32-NEXT: [[TMP3:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[A:%.*]], i32 [[TMP0]])
1444 // AArch32-NEXT: [[TMP4:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[TMP3]], i32 [[TMP2]])
1445 // AArch32-NEXT: ret i32 [[TMP4]]
1447 // AArch64-LABEL: @test_crc32cd(
1448 // AArch64-NEXT: entry:
1449 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cx(i32 [[A:%.*]], i64 [[B:%.*]])
1450 // AArch64-NEXT: ret i32 [[TMP0]]
1452 uint32_t test_crc32cd(uint32_t a
, uint64_t b
) {
1453 return __crc32cd(a
, b
);
1456 /* 10.1 Special register intrinsics */
1457 // AArch32-LABEL: @test_rsr(
1458 // AArch32-NEXT: entry:
1459 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META9:![0-9]+]])
1460 // AArch32-NEXT: ret i32 [[TMP0]]
1462 // AArch64-LABEL: @test_rsr(
1463 // AArch64-NEXT: entry:
1464 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META8:![0-9]+]])
1465 // AArch64-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
1466 // AArch64-NEXT: ret i32 [[TMP1]]
1468 uint32_t test_rsr() {
1469 #ifdef __ARM_32BIT_STATE
1470 return __arm_rsr("cp1:2:c3:c4:5");
1472 return __arm_rsr("1:2:3:4:5");
1476 // AArch32-LABEL: @test_rsr64(
1477 // AArch32-NEXT: entry:
1478 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META10:![0-9]+]])
1479 // AArch32-NEXT: ret i64 [[TMP0]]
1481 // AArch64-LABEL: @test_rsr64(
1482 // AArch64-NEXT: entry:
1483 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META8]])
1484 // AArch64-NEXT: ret i64 [[TMP0]]
1486 uint64_t test_rsr64() {
1487 #ifdef __ARM_32BIT_STATE
1488 return __arm_rsr64("cp1:2:c3");
1490 return __arm_rsr64("1:2:3:4:5");
1494 #ifdef __ARM_FEATURE_SYSREG128
1495 // AArch6494D128-LABEL: @test_rsr128(
1496 // AArch6494D128-NEXT: entry:
1497 // AArch6494D128-NEXT: [[TMP0:%.*]] = call i128 @llvm.read_volatile_register.i128(metadata [[META8]])
1498 // AArch6494D128-NEXT: ret i128 [[TMP0]]
1500 __uint128_t
test_rsr128() {
1501 return __arm_rsr128("1:2:3:4:5");
1505 // AArch32-LABEL: @test_rsrp(
1506 // AArch32-NEXT: entry:
1507 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META11:![0-9]+]])
1508 // AArch32-NEXT: [[TMP1:%.*]] = inttoptr i32 [[TMP0]] to ptr
1509 // AArch32-NEXT: ret ptr [[TMP1]]
1511 // AArch64-LABEL: @test_rsrp(
1512 // AArch64-NEXT: entry:
1513 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META9:![0-9]+]])
1514 // AArch64-NEXT: [[TMP1:%.*]] = inttoptr i64 [[TMP0]] to ptr
1515 // AArch64-NEXT: ret ptr [[TMP1]]
1518 return __arm_rsrp("sysreg");
1521 // AArch32-LABEL: @test_wsr(
1522 // AArch32-NEXT: entry:
1523 // AArch32-NEXT: call void @llvm.write_register.i32(metadata [[META9]], i32 [[V:%.*]])
1524 // AArch32-NEXT: ret void
1526 // AArch64-LABEL: @test_wsr(
1527 // AArch64-NEXT: entry:
1528 // AArch64-NEXT: [[TMP0:%.*]] = zext i32 [[V:%.*]] to i64
1529 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META8]], i64 [[TMP0]])
1530 // AArch64-NEXT: ret void
1532 void test_wsr(uint32_t v
) {
1533 #ifdef __ARM_32BIT_STATE
1534 __arm_wsr("cp1:2:c3:c4:5", v
);
1536 __arm_wsr("1:2:3:4:5", v
);
1540 // AArch32-LABEL: @test_wsr64(
1541 // AArch32-NEXT: entry:
1542 // AArch32-NEXT: call void @llvm.write_register.i64(metadata [[META10]], i64 [[V:%.*]])
1543 // AArch32-NEXT: ret void
1545 // AArch64-LABEL: @test_wsr64(
1546 // AArch64-NEXT: entry:
1547 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META8]], i64 [[V:%.*]])
1548 // AArch64-NEXT: ret void
1550 void test_wsr64(uint64_t v
) {
1551 #ifdef __ARM_32BIT_STATE
1552 __arm_wsr64("cp1:2:c3", v
);
1554 __arm_wsr64("1:2:3:4:5", v
);
1558 #ifdef __ARM_FEATURE_SYSREG128
1559 // AArch6494D128-LABEL: @test_wsr128(
1560 // AArch6494D128-NEXT: entry:
1561 // AArch6494D128-NEXT: call void @llvm.write_register.i128(metadata [[META8]], i128 [[V:%.*]])
1562 // AArch6494D128-NEXT: ret void
1564 void test_wsr128(__uint128_t v
) {
1565 __arm_wsr128("1:2:3:4:5", v
);
1570 // AArch32-LABEL: @test_wsrp(
1571 // AArch32-NEXT: entry:
1572 // AArch32-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[V:%.*]] to i32
1573 // AArch32-NEXT: call void @llvm.write_register.i32(metadata [[META11]], i32 [[TMP0]])
1574 // AArch32-NEXT: ret void
1576 // AArch64-LABEL: @test_wsrp(
1577 // AArch64-NEXT: entry:
1578 // AArch64-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[V:%.*]] to i64
1579 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META9]], i64 [[TMP0]])
1580 // AArch64-NEXT: ret void
1582 void test_wsrp(void *v
) {
1583 __arm_wsrp("sysreg", v
);
1586 // AArch32-LABEL: @test_rsrf(
1587 // AArch32-NEXT: entry:
1588 // AArch32-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
1589 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META9]])
1590 // AArch32-NEXT: store i32 [[TMP0]], ptr [[REF_TMP]], align 4
1591 // AArch32-NEXT: [[TMP2:%.*]] = load float, ptr [[REF_TMP]], align 4
1592 // AArch32-NEXT: ret float [[TMP2]]
1594 // AArch64-LABEL: @test_rsrf(
1595 // AArch64-NEXT: entry:
1596 // AArch64-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
1597 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META8]])
1598 // AArch64-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
1599 // AArch64-NEXT: store i32 [[TMP1]], ptr [[REF_TMP]], align 4
1600 // AArch64-NEXT: [[TMP3:%.*]] = load float, ptr [[REF_TMP]], align 4
1601 // AArch64-NEXT: ret float [[TMP3]]
1604 #ifdef __ARM_32BIT_STATE
1605 return __arm_rsrf("cp1:2:c3:c4:5");
1607 return __arm_rsrf("1:2:3:4:5");
1611 // AArch32-LABEL: @test_rsrf64(
1612 // AArch32-NEXT: entry:
1613 // AArch32-NEXT: [[REF_TMP:%.*]] = alloca i64, align 8
1614 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META10]])
1615 // AArch32-NEXT: store i64 [[TMP0]], ptr [[REF_TMP]], align 8
1616 // AArch32-NEXT: [[TMP2:%.*]] = load double, ptr [[REF_TMP]], align 8
1617 // AArch32-NEXT: ret double [[TMP2]]
1619 // AArch64-LABEL: @test_rsrf64(
1620 // AArch64-NEXT: entry:
1621 // AArch64-NEXT: [[REF_TMP:%.*]] = alloca i64, align 8
1622 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META8]])
1623 // AArch64-NEXT: store i64 [[TMP0]], ptr [[REF_TMP]], align 8
1624 // AArch64-NEXT: [[TMP2:%.*]] = load double, ptr [[REF_TMP]], align 8
1625 // AArch64-NEXT: ret double [[TMP2]]
1627 double test_rsrf64() {
1628 #ifdef __ARM_32BIT_STATE
1629 return __arm_rsrf64("cp1:2:c3");
1631 return __arm_rsrf64("1:2:3:4:5");
1635 // AArch32-LABEL: @test_wsrf(
1636 // AArch32-NEXT: entry:
1637 // AArch32-NEXT: [[V_ADDR:%.*]] = alloca float, align 4
1638 // AArch32-NEXT: store float [[V:%.*]], ptr [[V_ADDR]], align 4
1639 // AArch32-NEXT: [[TMP1:%.*]] = load i32, ptr [[V_ADDR]], align 4
1640 // AArch32-NEXT: call void @llvm.write_register.i32(metadata [[META9]], i32 [[TMP1]])
1641 // AArch32-NEXT: ret void
1643 // AArch64-LABEL: @test_wsrf(
1644 // AArch64-NEXT: entry:
1645 // AArch64-NEXT: [[V_ADDR:%.*]] = alloca float, align 4
1646 // AArch64-NEXT: store float [[V:%.*]], ptr [[V_ADDR]], align 4
1647 // AArch64-NEXT: [[TMP1:%.*]] = load i32, ptr [[V_ADDR]], align 4
1648 // AArch64-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64
1649 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META8]], i64 [[TMP2]])
1650 // AArch64-NEXT: ret void
1652 void test_wsrf(float v
) {
1653 #ifdef __ARM_32BIT_STATE
1654 __arm_wsrf("cp1:2:c3:c4:5", v
);
1656 __arm_wsrf("1:2:3:4:5", v
);
1660 // AArch32-LABEL: @test_wsrf64(
1661 // AArch32-NEXT: entry:
1662 // AArch32-NEXT: [[V_ADDR:%.*]] = alloca double, align 8
1663 // AArch32-NEXT: store double [[V:%.*]], ptr [[V_ADDR]], align 8
1664 // AArch32-NEXT: [[TMP1:%.*]] = load i64, ptr [[V_ADDR]], align 8
1665 // AArch32-NEXT: call void @llvm.write_register.i64(metadata [[META10]], i64 [[TMP1]])
1666 // AArch32-NEXT: ret void
1668 // AArch64-LABEL: @test_wsrf64(
1669 // AArch64-NEXT: entry:
1670 // AArch64-NEXT: [[V_ADDR:%.*]] = alloca double, align 8
1671 // AArch64-NEXT: store double [[V:%.*]], ptr [[V_ADDR]], align 8
1672 // AArch64-NEXT: [[TMP1:%.*]] = load i64, ptr [[V_ADDR]], align 8
1673 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META8]], i64 [[TMP1]])
1674 // AArch64-NEXT: ret void
1676 void test_wsrf64(double v
) {
1677 #ifdef __ARM_32BIT_STATE
1678 __arm_wsrf64("cp1:2:c3", v
);
1680 __arm_wsrf64("1:2:3:4:5", v
);
1684 #if defined(__ARM_64BIT_STATE) && defined(__ARM_FEATURE_JCVT)
1685 // AArch6483-LABEL: @test_jcvt(
1686 // AArch6483-NEXT: entry:
1687 // AArch6483-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.fjcvtzs(double [[V:%.*]])
1688 // AArch6483-NEXT: ret i32 [[TMP0]]
1690 int32_t test_jcvt(double v
) {
1696 #if defined(__ARM_64BIT_STATE) && defined(__ARM_FEATURE_RNG)
1698 // AArch6485-LABEL: @test_rndr(
1699 // AArch6485-NEXT: entry:
1700 // AArch6485-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndr()
1701 // AArch6485-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
1702 // AArch6485-NEXT: [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
1703 // AArch6485-NEXT: store i64 [[TMP1]], ptr [[__ADDR:%.*]], align 8
1704 // AArch6485-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
1705 // AArch6485-NEXT: ret i32 [[TMP3]]
1707 int test_rndr(uint64_t *__addr
) {
1708 return __rndr(__addr
);
1711 // AArch6485-LABEL: @test_rndrrs(
1712 // AArch6485-NEXT: entry:
1713 // AArch6485-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndrrs()
1714 // AArch6485-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
1715 // AArch6485-NEXT: [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
1716 // AArch6485-NEXT: store i64 [[TMP1]], ptr [[__ADDR:%.*]], align 8
1717 // AArch6485-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
1718 // AArch6485-NEXT: ret i32 [[TMP3]]
1720 int test_rndrrs(uint64_t *__addr
) {
1721 return __rndrrs(__addr
);