1 ; RUN: llc -O0 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
2 ; RUN: llc -O3 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefix=O3
4 ; This file checks that the translation from llvm IR to generic MachineInstr
6 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
7 target triple = "aarch64--"
10 ; CHECK-LABEL: name: addi64
11 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
12 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
13 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_ADD [[ARG1]], [[ARG2]]
14 ; CHECK-NEXT: $x0 = COPY [[RES]]
15 ; CHECK-NEXT: RET_ReallyLR implicit $x0
16 define i64 @addi64(i64 %arg1, i64 %arg2) {
17 %res = add i64 %arg1, %arg2
21 ; CHECK-LABEL: name: muli64
22 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
23 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
24 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_MUL [[ARG1]], [[ARG2]]
25 ; CHECK-NEXT: $x0 = COPY [[RES]]
26 ; CHECK-NEXT: RET_ReallyLR implicit $x0
27 define i64 @muli64(i64 %arg1, i64 %arg2) {
28 %res = mul i64 %arg1, %arg2
33 ; CHECK-LABEL: name: allocai64
35 ; CHECK-NEXT: - { id: 0, name: ptr1, type: default, offset: 0, size: 8, alignment: 8,
36 ; CHECK-NEXT: stack-id: default, callee-saved-register: '', callee-saved-restored: true,
37 ; CHECK-NEXT: debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
38 ; CHECK-NEXT: - { id: 1, name: ptr2, type: default, offset: 0, size: 8, alignment: 1,
39 ; CHECK-NEXT: stack-id: default, callee-saved-register: '', callee-saved-restored: true,
40 ; CHECK-NEXT: debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
41 ; CHECK-NEXT: - { id: 2, name: ptr3, type: default, offset: 0, size: 128, alignment: 8,
42 ; CHECK-NEXT: stack-id: default, callee-saved-register: '', callee-saved-restored: true,
43 ; CHECK-NEXT: debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
44 ; CHECK-NEXT: - { id: 3, name: ptr4, type: default, offset: 0, size: 1, alignment: 8,
45 ; CHECK: %{{[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.0.ptr1
46 ; CHECK: %{{[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.1.ptr2
47 ; CHECK: %{{[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.2.ptr3
48 ; CHECK: %{{[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.3.ptr4
49 define void @allocai64() {
51 %ptr2 = alloca i64, align 1
52 %ptr3 = alloca i64, i32 16
53 %ptr4 = alloca [0 x i64]
58 ; CHECK-LABEL: name: uncondbr
61 ; ABI/constant lowering and IR-level entry basic block.
62 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
64 ; Make sure we have one successor and only one.
65 ; CHECK-NEXT: successors: %[[BB2:bb.[0-9]+]](0x80000000)
67 ; Check that we emit the correct branch.
68 ; CHECK: G_BR %[[BB2]]
70 ; Check that end contains the return instruction.
71 ; CHECK: [[END:bb.[0-9]+]].{{[a-zA-Z0-9.]+}}:
72 ; CHECK-NEXT: RET_ReallyLR
74 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
75 ; CHECK-NEXT: successors: %[[END]](0x80000000)
76 ; CHECK: G_BR %[[END]]
77 define void @uncondbr() {
86 ; CHECK-LABEL: name: uncondbr_fallthrough
88 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
89 ; CHECK-NEXT: successors: %[[END:bb.[0-9]+]](0x80000000)
90 ; We don't emit a branch here, as we can fallthrough to the successor.
92 ; CHECK: [[END]].{{[a-zA-Z0-9.]+}}:
93 ; CHECK-NEXT: RET_ReallyLR
94 define void @uncondbr_fallthrough() {
101 ; Tests for conditional br.
102 ; CHECK-LABEL: name: condbr
105 ; ABI/constant lowering and IR-level entry basic block.
106 ; CHECK: bb.{{[0-9]+}} (%ir-block.{{[0-9]+}}):
107 ; Make sure we have two successors
108 ; CHECK-NEXT: successors: %[[TRUE:bb.[0-9]+]](0x40000000),
109 ; CHECK: %[[FALSE:bb.[0-9]+]](0x40000000)
111 ; CHECK: [[ADDR:%.*]]:_(p0) = COPY $x0
113 ; Check that we emit the correct branch.
114 ; CHECK: [[TST:%.*]]:_(s1) = G_LOAD [[ADDR]](p0)
115 ; CHECK: G_BRCOND [[TST]](s1), %[[TRUE]]
116 ; CHECK: G_BR %[[FALSE]]
118 ; Check that each successor contains the return instruction.
119 ; CHECK: [[TRUE]].{{[a-zA-Z0-9.]+}}:
120 ; CHECK-NEXT: RET_ReallyLR
121 ; CHECK: [[FALSE]].{{[a-zA-Z0-9.]+}}:
122 ; CHECK-NEXT: RET_ReallyLR
123 define void @condbr(i1* %tstaddr) {
124 %tst = load i1, i1* %tstaddr
125 br i1 %tst, label %true, label %false
132 ; Tests for indirect br.
133 ; CHECK-LABEL: name: indirectbr
136 ; ABI/constant lowering and IR-level entry basic block.
137 ; CHECK: bb.{{[0-9]+.[a-zA-Z0-9.]+}}:
138 ; Make sure we have one successor
139 ; CHECK-NEXT: successors: %[[BB_L1:bb.[0-9]+]](0x80000000)
142 ; Check basic block L1 has 2 successors: BBL1 and BBL2
143 ; CHECK: [[BB_L1]].{{[a-zA-Z0-9.]+}} (address-taken):
144 ; CHECK-NEXT: successors: %[[BB_L1]](0x40000000),
145 ; CHECK: %[[BB_L2:bb.[0-9]+]](0x40000000)
146 ; CHECK: G_BRINDIRECT %{{[0-9]+}}(p0)
148 ; Check basic block L2 is the return basic block
149 ; CHECK: [[BB_L2]].{{[a-zA-Z0-9.]+}} (address-taken):
150 ; CHECK-NEXT: RET_ReallyLR
152 @indirectbr.L = internal unnamed_addr constant [3 x i8*] [i8* blockaddress(@indirectbr, %L1), i8* blockaddress(@indirectbr, %L2), i8* null], align 8
154 define void @indirectbr() {
157 L1: ; preds = %entry, %L1
158 %i = phi i32 [ 0, %entry ], [ %inc, %L1 ]
160 %idxprom = zext i32 %i to i64
161 %arrayidx = getelementptr inbounds [3 x i8*], [3 x i8*]* @indirectbr.L, i64 0, i64 %idxprom
162 %brtarget = load i8*, i8** %arrayidx, align 8
163 indirectbr i8* %brtarget, [label %L1, label %L2]
169 ; CHECK-LABEL: name: ori64
170 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
171 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
172 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_OR [[ARG1]], [[ARG2]]
173 ; CHECK-NEXT: $x0 = COPY [[RES]]
174 ; CHECK-NEXT: RET_ReallyLR implicit $x0
175 define i64 @ori64(i64 %arg1, i64 %arg2) {
176 %res = or i64 %arg1, %arg2
180 ; CHECK-LABEL: name: ori32
181 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
182 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
183 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_OR [[ARG1]], [[ARG2]]
184 ; CHECK-NEXT: $w0 = COPY [[RES]]
185 ; CHECK-NEXT: RET_ReallyLR implicit $w0
186 define i32 @ori32(i32 %arg1, i32 %arg2) {
187 %res = or i32 %arg1, %arg2
192 ; CHECK-LABEL: name: xori64
193 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
194 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
195 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_XOR [[ARG1]], [[ARG2]]
196 ; CHECK-NEXT: $x0 = COPY [[RES]]
197 ; CHECK-NEXT: RET_ReallyLR implicit $x0
198 define i64 @xori64(i64 %arg1, i64 %arg2) {
199 %res = xor i64 %arg1, %arg2
203 ; CHECK-LABEL: name: xori32
204 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
205 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
206 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_XOR [[ARG1]], [[ARG2]]
207 ; CHECK-NEXT: $w0 = COPY [[RES]]
208 ; CHECK-NEXT: RET_ReallyLR implicit $w0
209 define i32 @xori32(i32 %arg1, i32 %arg2) {
210 %res = xor i32 %arg1, %arg2
215 ; CHECK-LABEL: name: andi64
216 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
217 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
218 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_AND [[ARG1]], [[ARG2]]
219 ; CHECK-NEXT: $x0 = COPY [[RES]]
220 ; CHECK-NEXT: RET_ReallyLR implicit $x0
221 define i64 @andi64(i64 %arg1, i64 %arg2) {
222 %res = and i64 %arg1, %arg2
226 ; CHECK-LABEL: name: andi32
227 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
228 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
229 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_AND [[ARG1]], [[ARG2]]
230 ; CHECK-NEXT: $w0 = COPY [[RES]]
231 ; CHECK-NEXT: RET_ReallyLR implicit $w0
232 define i32 @andi32(i32 %arg1, i32 %arg2) {
233 %res = and i32 %arg1, %arg2
238 ; CHECK-LABEL: name: subi64
239 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
240 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
241 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_SUB [[ARG1]], [[ARG2]]
242 ; CHECK-NEXT: $x0 = COPY [[RES]]
243 ; CHECK-NEXT: RET_ReallyLR implicit $x0
244 define i64 @subi64(i64 %arg1, i64 %arg2) {
245 %res = sub i64 %arg1, %arg2
249 ; CHECK-LABEL: name: subi32
250 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
251 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
252 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SUB [[ARG1]], [[ARG2]]
253 ; CHECK-NEXT: $w0 = COPY [[RES]]
254 ; CHECK-NEXT: RET_ReallyLR implicit $w0
255 define i32 @subi32(i32 %arg1, i32 %arg2) {
256 %res = sub i32 %arg1, %arg2
260 ; CHECK-LABEL: name: ptrtoint
261 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
262 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_PTRTOINT [[ARG1]]
263 ; CHECK: $x0 = COPY [[RES]]
264 ; CHECK: RET_ReallyLR implicit $x0
265 define i64 @ptrtoint(i64* %a) {
266 %val = ptrtoint i64* %a to i64
270 ; CHECK-LABEL: name: inttoptr
271 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
272 ; CHECK: [[RES:%[0-9]+]]:_(p0) = G_INTTOPTR [[ARG1]]
273 ; CHECK: $x0 = COPY [[RES]]
274 ; CHECK: RET_ReallyLR implicit $x0
275 define i64* @inttoptr(i64 %a) {
276 %val = inttoptr i64 %a to i64*
280 ; CHECK-LABEL: name: trivial_bitcast
281 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
282 ; CHECK: $x0 = COPY [[ARG1]]
283 ; CHECK: RET_ReallyLR implicit $x0
284 define i64* @trivial_bitcast(i8* %a) {
285 %val = bitcast i8* %a to i64*
289 ; CHECK-LABEL: name: trivial_bitcast_with_copy
290 ; CHECK: [[A:%[0-9]+]]:_(p0) = COPY $x0
291 ; CHECK: G_BR %[[CAST:bb\.[0-9]+]]
293 ; CHECK: [[END:bb\.[0-9]+]].{{[a-zA-Z0-9.]+}}:
294 ; CHECK: $x0 = COPY [[A]]
296 ; CHECK: [[CAST]].{{[a-zA-Z0-9.]+}}:
297 ; CHECK: G_BR %[[END]]
298 define i64* @trivial_bitcast_with_copy(i8* %a) {
305 %val = bitcast i8* %a to i64*
309 ; CHECK-LABEL: name: bitcast
310 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
311 ; CHECK: [[RES1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[ARG1]]
312 ; CHECK: [[RES2:%[0-9]+]]:_(s64) = G_BITCAST [[RES1]]
313 ; CHECK: $x0 = COPY [[RES2]]
314 ; CHECK: RET_ReallyLR implicit $x0
315 define i64 @bitcast(i64 %a) {
316 %res1 = bitcast i64 %a to <2 x i32>
317 %res2 = bitcast <2 x i32> %res1 to i64
321 ; CHECK-LABEL: name: addrspacecast
322 ; CHECK: [[ARG1:%[0-9]+]]:_(p1) = COPY $x0
323 ; CHECK: [[RES1:%[0-9]+]]:_(p2) = G_ADDRSPACE_CAST [[ARG1]]
324 ; CHECK: [[RES2:%[0-9]+]]:_(p0) = G_ADDRSPACE_CAST [[RES1]]
325 ; CHECK: $x0 = COPY [[RES2]]
326 ; CHECK: RET_ReallyLR implicit $x0
327 define i64* @addrspacecast(i32 addrspace(1)* %a) {
328 %res1 = addrspacecast i32 addrspace(1)* %a to i64 addrspace(2)*
329 %res2 = addrspacecast i64 addrspace(2)* %res1 to i64*
333 ; CHECK-LABEL: name: trunc
334 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
335 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_LOAD
336 ; CHECK: [[RES1:%[0-9]+]]:_(s8) = G_TRUNC [[ARG1]]
337 ; CHECK: [[RES2:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[VEC]]
338 define void @trunc(i64 %a) {
339 %vecptr = alloca <4 x i32>
340 %vec = load <4 x i32>, <4 x i32>* %vecptr
341 %res1 = trunc i64 %a to i8
342 %res2 = trunc <4 x i32> %vec to <4 x i16>
346 ; CHECK-LABEL: name: load
347 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
348 ; CHECK: [[ADDR42:%[0-9]+]]:_(p42) = COPY $x1
349 ; CHECK: [[VAL1:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (load 8 from %ir.addr, align 16)
350 ; CHECK: [[VAL2:%[0-9]+]]:_(s64) = G_LOAD [[ADDR42]](p42) :: (load 8 from %ir.addr42, addrspace 42)
351 ; CHECK: [[SUM2:%.*]]:_(s64) = G_ADD [[VAL1]], [[VAL2]]
352 ; CHECK: [[VAL3:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (volatile load 8 from %ir.addr)
353 ; CHECK: [[SUM3:%[0-9]+]]:_(s64) = G_ADD [[SUM2]], [[VAL3]]
354 ; CHECK: [[VAL4:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (load 8 from %ir.addr, !range !0)
355 ; CHECK: [[SUM4:%[0-9]+]]:_(s64) = G_ADD [[SUM3]], [[VAL4]]
356 ; CHECK: $x0 = COPY [[SUM4]]
357 ; CHECK: RET_ReallyLR implicit $x0
358 define i64 @load(i64* %addr, i64 addrspace(42)* %addr42) {
359 %val1 = load i64, i64* %addr, align 16
361 %val2 = load i64, i64 addrspace(42)* %addr42
362 %sum2 = add i64 %val1, %val2
364 %val3 = load volatile i64, i64* %addr
365 %sum3 = add i64 %sum2, %val3
367 %val4 = load i64, i64* %addr, !range !0
368 %sum4 = add i64 %sum3, %val4
372 ; CHECK-LABEL: name: store
373 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
374 ; CHECK: [[ADDR42:%[0-9]+]]:_(p42) = COPY $x1
375 ; CHECK: [[VAL1:%[0-9]+]]:_(s64) = COPY $x2
376 ; CHECK: [[VAL2:%[0-9]+]]:_(s64) = COPY $x3
377 ; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (store 8 into %ir.addr, align 16)
378 ; CHECK: G_STORE [[VAL2]](s64), [[ADDR42]](p42) :: (store 8 into %ir.addr42, addrspace 42)
379 ; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (volatile store 8 into %ir.addr)
380 ; CHECK: RET_ReallyLR
381 define void @store(i64* %addr, i64 addrspace(42)* %addr42, i64 %val1, i64 %val2) {
382 store i64 %val1, i64* %addr, align 16
383 store i64 %val2, i64 addrspace(42)* %addr42
384 store volatile i64 %val1, i64* %addr
385 %sum = add i64 %val1, %val2
389 ; CHECK-LABEL: name: intrinsics
390 ; CHECK: [[CUR:%[0-9]+]]:_(s32) = COPY $w0
391 ; CHECK: [[BITS:%[0-9]+]]:_(s32) = COPY $w1
392 ; CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTRINSIC intrinsic(@llvm.returnaddress), 0
393 ; CHECK: [[PTR_VEC:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.ptr.vec
394 ; CHECK: [[VEC:%[0-9]+]]:_(<8 x s8>) = G_LOAD [[PTR_VEC]]
395 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), [[VEC]](<8 x s8>), [[VEC]](<8 x s8>), [[PTR]](p0)
396 ; CHECK: RET_ReallyLR
397 declare i8* @llvm.returnaddress(i32)
398 declare void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8>, <8 x i8>, i8*)
399 declare { <8 x i8>, <8 x i8> } @llvm.aarch64.neon.ld2.v8i8.p0v8i8(<8 x i8>*)
400 define void @intrinsics(i32 %cur, i32 %bits) {
401 %ptr = call i8* @llvm.returnaddress(i32 0)
402 %ptr.vec = alloca <8 x i8>
403 %vec = load <8 x i8>, <8 x i8>* %ptr.vec
404 call void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8> %vec, <8 x i8> %vec, i8* %ptr)
408 ; CHECK-LABEL: name: test_phi
409 ; CHECK: G_BRCOND {{%.*}}, %[[TRUE:bb\.[0-9]+]]
410 ; CHECK: G_BR %[[FALSE:bb\.[0-9]+]]
412 ; CHECK: [[TRUE]].{{[a-zA-Z0-9.]+}}:
413 ; CHECK: [[RES1:%[0-9]+]]:_(s32) = G_LOAD
415 ; CHECK: [[FALSE]].{{[a-zA-Z0-9.]+}}:
416 ; CHECK: [[RES2:%[0-9]+]]:_(s32) = G_LOAD
418 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_PHI [[RES1]](s32), %[[TRUE]], [[RES2]](s32), %[[FALSE]]
419 ; CHECK: $w0 = COPY [[RES]]
420 define i32 @test_phi(i32* %addr1, i32* %addr2, i1 %tst) {
421 br i1 %tst, label %true, label %false
424 %res1 = load i32, i32* %addr1
428 %res2 = load i32, i32* %addr2
432 %res = phi i32 [%res1, %true], [%res2, %false]
436 ; CHECK-LABEL: name: unreachable
440 define void @unreachable(i32 %a) {
441 %sum = add i32 %a, %a
445 ; It's important that constants are after argument passing, but before the
446 ; rest of the entry block.
447 ; CHECK-LABEL: name: constant_int
448 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
449 ; CHECK: [[ONE:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
451 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
452 ; CHECK: [[SUM1:%[0-9]+]]:_(s32) = G_ADD [[IN]], [[ONE]]
453 ; CHECK: [[SUM2:%[0-9]+]]:_(s32) = G_ADD [[IN]], [[ONE]]
454 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_ADD [[SUM1]], [[SUM2]]
455 ; CHECK: $w0 = COPY [[RES]]
457 define i32 @constant_int(i32 %in) {
461 %sum1 = add i32 %in, 1
462 %sum2 = add i32 %in, 1
463 %res = add i32 %sum1, %sum2
467 ; CHECK-LABEL: name: constant_int_start
468 ; CHECK: [[TWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
469 ; CHECK: [[ANSWER:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
470 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CONSTANT i32 44
471 define i32 @constant_int_start() {
476 ; CHECK-LABEL: name: test_undef
477 ; CHECK: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
478 ; CHECK: $w0 = COPY [[UNDEF]]
479 define i32 @test_undef() {
483 ; CHECK-LABEL: name: test_constant_inttoptr
484 ; CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
485 ; CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[ONE]]
486 ; CHECK: $x0 = COPY [[PTR]]
487 define i8* @test_constant_inttoptr() {
488 ret i8* inttoptr(i64 1 to i8*)
491 ; This failed purely because the Constant -> VReg map was kept across
492 ; functions, so reuse the "i64 1" from above.
493 ; CHECK-LABEL: name: test_reused_constant
494 ; CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
495 ; CHECK: $x0 = COPY [[ONE]]
496 define i64 @test_reused_constant() {
500 ; CHECK-LABEL: name: test_sext
501 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
502 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_SEXT [[IN]]
503 ; CHECK: $x0 = COPY [[RES]]
504 define i64 @test_sext(i32 %in) {
505 %res = sext i32 %in to i64
509 ; CHECK-LABEL: name: test_zext
510 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
511 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_ZEXT [[IN]]
512 ; CHECK: $x0 = COPY [[RES]]
513 define i64 @test_zext(i32 %in) {
514 %res = zext i32 %in to i64
518 ; CHECK-LABEL: name: test_shl
519 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
520 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
521 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SHL [[ARG1]], [[ARG2]]
522 ; CHECK-NEXT: $w0 = COPY [[RES]]
523 ; CHECK-NEXT: RET_ReallyLR implicit $w0
524 define i32 @test_shl(i32 %arg1, i32 %arg2) {
525 %res = shl i32 %arg1, %arg2
530 ; CHECK-LABEL: name: test_lshr
531 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
532 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
533 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_LSHR [[ARG1]], [[ARG2]]
534 ; CHECK-NEXT: $w0 = COPY [[RES]]
535 ; CHECK-NEXT: RET_ReallyLR implicit $w0
536 define i32 @test_lshr(i32 %arg1, i32 %arg2) {
537 %res = lshr i32 %arg1, %arg2
541 ; CHECK-LABEL: name: test_ashr
542 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
543 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
544 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_ASHR [[ARG1]], [[ARG2]]
545 ; CHECK-NEXT: $w0 = COPY [[RES]]
546 ; CHECK-NEXT: RET_ReallyLR implicit $w0
547 define i32 @test_ashr(i32 %arg1, i32 %arg2) {
548 %res = ashr i32 %arg1, %arg2
552 ; CHECK-LABEL: name: test_sdiv
553 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
554 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
555 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SDIV [[ARG1]], [[ARG2]]
556 ; CHECK-NEXT: $w0 = COPY [[RES]]
557 ; CHECK-NEXT: RET_ReallyLR implicit $w0
558 define i32 @test_sdiv(i32 %arg1, i32 %arg2) {
559 %res = sdiv i32 %arg1, %arg2
563 ; CHECK-LABEL: name: test_udiv
564 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
565 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
566 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_UDIV [[ARG1]], [[ARG2]]
567 ; CHECK-NEXT: $w0 = COPY [[RES]]
568 ; CHECK-NEXT: RET_ReallyLR implicit $w0
569 define i32 @test_udiv(i32 %arg1, i32 %arg2) {
570 %res = udiv i32 %arg1, %arg2
574 ; CHECK-LABEL: name: test_srem
575 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
576 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
577 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SREM [[ARG1]], [[ARG2]]
578 ; CHECK-NEXT: $w0 = COPY [[RES]]
579 ; CHECK-NEXT: RET_ReallyLR implicit $w0
580 define i32 @test_srem(i32 %arg1, i32 %arg2) {
581 %res = srem i32 %arg1, %arg2
585 ; CHECK-LABEL: name: test_urem
586 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
587 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
588 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_UREM [[ARG1]], [[ARG2]]
589 ; CHECK-NEXT: $w0 = COPY [[RES]]
590 ; CHECK-NEXT: RET_ReallyLR implicit $w0
591 define i32 @test_urem(i32 %arg1, i32 %arg2) {
592 %res = urem i32 %arg1, %arg2
596 ; CHECK-LABEL: name: test_constant_null
597 ; CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
598 ; CHECK: [[NULL:%[0-9]+]]:_(p0) = G_INTTOPTR [[ZERO]]
599 ; CHECK: $x0 = COPY [[NULL]]
600 define i8* @test_constant_null() {
604 ; CHECK-LABEL: name: test_struct_memops
605 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
606 ; CHECK: [[VAL1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
607 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
608 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST1]](s64)
609 ; CHECK: [[VAL2:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load 4 from %ir.addr + 4)
610 ; CHECK: G_STORE [[VAL1]](s8), [[ADDR]](p0) :: (store 1 into %ir.addr, align 4)
611 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST1]](s64)
612 ; CHECK: G_STORE [[VAL2]](s32), [[GEP2]](p0) :: (store 4 into %ir.addr + 4)
613 define void @test_struct_memops({ i8, i32 }* %addr) {
614 %val = load { i8, i32 }, { i8, i32 }* %addr
615 store { i8, i32 } %val, { i8, i32 }* %addr
619 ; CHECK-LABEL: name: test_i1_memops
620 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
621 ; CHECK: [[VAL:%[0-9]+]]:_(s1) = G_LOAD [[ADDR]](p0) :: (load 1 from %ir.addr)
622 ; CHECK: G_STORE [[VAL]](s1), [[ADDR]](p0) :: (store 1 into %ir.addr)
623 define void @test_i1_memops(i1* %addr) {
624 %val = load i1, i1* %addr
625 store i1 %val, i1* %addr
629 ; CHECK-LABEL: name: int_comparison
630 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
631 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
632 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
633 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[LHS]](s32), [[RHS]]
634 ; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0)
635 define void @int_comparison(i32 %a, i32 %b, i1* %addr) {
636 %res = icmp ne i32 %a, %b
637 store i1 %res, i1* %addr
641 ; CHECK-LABEL: name: ptr_comparison
642 ; CHECK: [[LHS:%[0-9]+]]:_(p0) = COPY $x0
643 ; CHECK: [[RHS:%[0-9]+]]:_(p0) = COPY $x1
644 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
645 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[LHS]](p0), [[RHS]]
646 ; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0)
647 define void @ptr_comparison(i8* %a, i8* %b, i1* %addr) {
648 %res = icmp eq i8* %a, %b
649 store i1 %res, i1* %addr
653 ; CHECK-LABEL: name: test_fadd
654 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
655 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
656 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FADD [[ARG1]], [[ARG2]]
657 ; CHECK-NEXT: $s0 = COPY [[RES]]
658 ; CHECK-NEXT: RET_ReallyLR implicit $s0
659 define float @test_fadd(float %arg1, float %arg2) {
660 %res = fadd float %arg1, %arg2
664 ; CHECK-LABEL: name: test_fsub
665 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
666 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
667 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FSUB [[ARG1]], [[ARG2]]
668 ; CHECK-NEXT: $s0 = COPY [[RES]]
669 ; CHECK-NEXT: RET_ReallyLR implicit $s0
670 define float @test_fsub(float %arg1, float %arg2) {
671 %res = fsub float %arg1, %arg2
675 ; CHECK-LABEL: name: test_fmul
676 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
677 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
678 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FMUL [[ARG1]], [[ARG2]]
679 ; CHECK-NEXT: $s0 = COPY [[RES]]
680 ; CHECK-NEXT: RET_ReallyLR implicit $s0
681 define float @test_fmul(float %arg1, float %arg2) {
682 %res = fmul float %arg1, %arg2
686 ; CHECK-LABEL: name: test_fdiv
687 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
688 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
689 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FDIV [[ARG1]], [[ARG2]]
690 ; CHECK-NEXT: $s0 = COPY [[RES]]
691 ; CHECK-NEXT: RET_ReallyLR implicit $s0
692 define float @test_fdiv(float %arg1, float %arg2) {
693 %res = fdiv float %arg1, %arg2
697 ; CHECK-LABEL: name: test_frem
698 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
699 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
700 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FREM [[ARG1]], [[ARG2]]
701 ; CHECK-NEXT: $s0 = COPY [[RES]]
702 ; CHECK-NEXT: RET_ReallyLR implicit $s0
703 define float @test_frem(float %arg1, float %arg2) {
704 %res = frem float %arg1, %arg2
708 ; CHECK-LABEL: name: test_fneg
709 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
710 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FNEG [[ARG1]]
711 ; CHECK-NEXT: $s0 = COPY [[RES]]
712 ; CHECK-NEXT: RET_ReallyLR implicit $s0
713 define float @test_fneg(float %arg1) {
714 %res = fneg float %arg1
718 ; CHECK-LABEL: name: test_fneg_fmf
719 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
720 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG1]]
721 ; CHECK-NEXT: $s0 = COPY [[RES]]
722 ; CHECK-NEXT: RET_ReallyLR implicit $s0
723 define float @test_fneg_fmf(float %arg1) {
724 %res = fneg fast float %arg1
728 ; CHECK-LABEL: name: test_sadd_overflow
729 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
730 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
731 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
732 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SADDO [[LHS]], [[RHS]]
733 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
734 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
735 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
736 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
737 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
738 define void @test_sadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
739 %res = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %lhs, i32 %rhs)
740 store { i32, i1 } %res, { i32, i1 }* %addr
744 ; CHECK-LABEL: name: test_uadd_overflow
745 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
746 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
747 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
748 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_UADDO [[LHS]], [[RHS]]
749 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
750 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
751 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
752 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
753 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
754 define void @test_uadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
755 %res = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %lhs, i32 %rhs)
756 store { i32, i1 } %res, { i32, i1 }* %addr
760 ; CHECK-LABEL: name: test_ssub_overflow
761 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
762 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
763 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
764 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SSUBO [[LHS]], [[RHS]]
765 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.subr)
766 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
767 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
768 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.subr + 4, align 4)
769 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
770 define void @test_ssub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) {
771 %res = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %lhs, i32 %rhs)
772 store { i32, i1 } %res, { i32, i1 }* %subr
776 ; CHECK-LABEL: name: test_usub_overflow
777 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
778 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
779 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
780 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_USUBO [[LHS]], [[RHS]]
781 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.subr)
782 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
783 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
784 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.subr + 4, align 4)
785 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
786 define void @test_usub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) {
787 %res = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %lhs, i32 %rhs)
788 store { i32, i1 } %res, { i32, i1 }* %subr
792 ; CHECK-LABEL: name: test_smul_overflow
793 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
794 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
795 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
796 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SMULO [[LHS]], [[RHS]]
797 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
798 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
799 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
800 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
801 declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)
802 define void @test_smul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
803 %res = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %lhs, i32 %rhs)
804 store { i32, i1 } %res, { i32, i1 }* %addr
808 ; CHECK-LABEL: name: test_umul_overflow
809 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
810 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
811 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
812 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_UMULO [[LHS]], [[RHS]]
813 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
814 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
815 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
816 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
817 declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
818 define void @test_umul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
819 %res = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %lhs, i32 %rhs)
820 store { i32, i1 } %res, { i32, i1 }* %addr
824 ; CHECK-LABEL: name: test_extractvalue
825 ; CHECK: %0:_(p0) = COPY $x0
826 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
827 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
828 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
829 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4)
830 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
831 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
832 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8)
833 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
834 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
835 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12)
836 ; CHECK: $w0 = COPY [[LD3]](s32)
837 %struct.nested = type {i8, { i8, i32 }, i32}
838 define i32 @test_extractvalue(%struct.nested* %addr) {
839 %struct = load %struct.nested, %struct.nested* %addr
840 %res = extractvalue %struct.nested %struct, 1, 1
844 ; CHECK-LABEL: name: test_extractvalue_agg
845 ; CHECK: %0:_(p0) = COPY $x0
846 ; CHECK: %1:_(p0) = COPY $x1
847 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
848 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
849 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
850 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4)
851 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
852 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
853 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8)
854 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
855 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
856 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12)
857 ; CHECK: G_STORE [[LD2]](s8), %1(p0) :: (store 1 into %ir.addr2, align 4)
858 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP %1, [[CST1]](s64)
859 ; CHECK: G_STORE [[LD3]](s32), [[GEP4]](p0) :: (store 4 into %ir.addr2 + 4)
860 define void @test_extractvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
861 %struct = load %struct.nested, %struct.nested* %addr
862 %res = extractvalue %struct.nested %struct, 1
863 store {i8, i32} %res, {i8, i32}* %addr2
867 ; CHECK-LABEL: name: test_trivial_extract_ptr
868 ; CHECK: [[STRUCT:%[0-9]+]]:_(p0) = COPY $x0
869 ; CHECK: [[VAL32:%[0-9]+]]:_(s32) = COPY $w1
870 ; CHECK: [[VAL:%[0-9]+]]:_(s8) = G_TRUNC [[VAL32]]
871 ; CHECK: G_STORE [[VAL]](s8), [[STRUCT]](p0)
872 define void @test_trivial_extract_ptr([1 x i8*] %s, i8 %val) {
873 %addr = extractvalue [1 x i8*] %s, 0
874 store i8 %val, i8* %addr
878 ; CHECK-LABEL: name: test_insertvalue
879 ; CHECK: %0:_(p0) = COPY $x0
880 ; CHECK: %1:_(s32) = COPY $w1
881 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
882 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
883 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
884 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4)
885 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
886 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
887 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8)
888 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
889 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
890 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12)
891 ; CHECK: G_STORE [[LD1]](s8), %0(p0) :: (store 1 into %ir.addr, align 4)
892 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
893 ; CHECK: G_STORE [[LD2]](s8), [[GEP4]](p0) :: (store 1 into %ir.addr + 4, align 4)
894 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
895 ; CHECK: G_STORE %1(s32), [[GEP5]](p0) :: (store 4 into %ir.addr + 8)
896 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
897 ; CHECK: G_STORE [[LD4]](s32), [[GEP6]](p0) :: (store 4 into %ir.addr + 12)
898 define void @test_insertvalue(%struct.nested* %addr, i32 %val) {
899 %struct = load %struct.nested, %struct.nested* %addr
900 %newstruct = insertvalue %struct.nested %struct, i32 %val, 1, 1
901 store %struct.nested %newstruct, %struct.nested* %addr
905 define [1 x i64] @test_trivial_insert([1 x i64] %s, i64 %val) {
906 ; CHECK-LABEL: name: test_trivial_insert
907 ; CHECK: [[STRUCT:%[0-9]+]]:_(s64) = COPY $x0
908 ; CHECK: [[VAL:%[0-9]+]]:_(s64) = COPY $x1
909 ; CHECK: $x0 = COPY [[VAL]]
910 %res = insertvalue [1 x i64] %s, i64 %val, 0
914 define [1 x i8*] @test_trivial_insert_ptr([1 x i8*] %s, i8* %val) {
915 ; CHECK-LABEL: name: test_trivial_insert_ptr
916 ; CHECK: [[STRUCT:%[0-9]+]]:_(p0) = COPY $x0
917 ; CHECK: [[VAL:%[0-9]+]]:_(p0) = COPY $x1
918 ; CHECK: $x0 = COPY [[VAL]]
919 %res = insertvalue [1 x i8*] %s, i8* %val, 0
923 ; CHECK-LABEL: name: test_insertvalue_agg
924 ; CHECK: %0:_(p0) = COPY $x0
925 ; CHECK: %1:_(p0) = COPY $x1
926 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %1(p0) :: (load 1 from %ir.addr2, align 4)
927 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
928 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %1, [[CST1]](s64)
929 ; CHECK: [[LD2:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load 4 from %ir.addr2 + 4)
930 ; CHECK: [[LD3:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
931 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
932 ; CHECK: [[LD4:%[0-9]+]]:_(s8) = G_LOAD [[GEP2]](p0) :: (load 1 from %ir.addr + 4, align 4)
933 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
934 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
935 ; CHECK: [[LD5:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 8)
936 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
937 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP %0, [[CST4]](s64)
938 ; CHECK: [[LD6:%[0-9]+]]:_(s32) = G_LOAD [[GEP4]](p0) :: (load 4 from %ir.addr + 12)
939 ; CHECK: G_STORE [[LD3]](s8), %0(p0) :: (store 1 into %ir.addr, align 4)
940 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
941 ; CHECK: G_STORE [[LD1]](s8), [[GEP5]](p0) :: (store 1 into %ir.addr + 4, align 4)
942 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
943 ; CHECK: G_STORE [[LD2]](s32), [[GEP6]](p0) :: (store 4 into %ir.addr + 8)
944 ; CHECK: [[GEP7:%[0-9]+]]:_(p0) = G_GEP %0, [[CST4]](s64)
945 ; CHECK: G_STORE [[LD6]](s32), [[GEP7]](p0) :: (store 4 into %ir.addr + 12)
946 define void @test_insertvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
947 %smallstruct = load {i8, i32}, {i8, i32}* %addr2
948 %struct = load %struct.nested, %struct.nested* %addr
949 %res = insertvalue %struct.nested %struct, {i8, i32} %smallstruct, 1
950 store %struct.nested %res, %struct.nested* %addr
954 ; CHECK-LABEL: name: test_select
955 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
956 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]]
957 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w1
958 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w2
959 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
960 ; CHECK: $w0 = COPY [[RES]]
961 define i32 @test_select(i1 %tst, i32 %lhs, i32 %rhs) {
962 %res = select i1 %tst, i32 %lhs, i32 %rhs
966 ; CHECK-LABEL: name: test_select_ptr
967 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
968 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]]
969 ; CHECK: [[LHS:%[0-9]+]]:_(p0) = COPY $x1
970 ; CHECK: [[RHS:%[0-9]+]]:_(p0) = COPY $x2
971 ; CHECK: [[RES:%[0-9]+]]:_(p0) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
972 ; CHECK: $x0 = COPY [[RES]]
973 define i8* @test_select_ptr(i1 %tst, i8* %lhs, i8* %rhs) {
974 %res = select i1 %tst, i8* %lhs, i8* %rhs
978 ; CHECK-LABEL: name: test_select_vec
979 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
980 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]]
981 ; CHECK: [[LHS:%[0-9]+]]:_(<4 x s32>) = COPY $q0
982 ; CHECK: [[RHS:%[0-9]+]]:_(<4 x s32>) = COPY $q1
983 ; CHECK: [[RES:%[0-9]+]]:_(<4 x s32>) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
984 ; CHECK: $q0 = COPY [[RES]]
985 define <4 x i32> @test_select_vec(i1 %tst, <4 x i32> %lhs, <4 x i32> %rhs) {
986 %res = select i1 %tst, <4 x i32> %lhs, <4 x i32> %rhs
990 ; CHECK-LABEL: name: test_vselect_vec
991 ; CHECK: [[TST32:%[0-9]+]]:_(<4 x s32>) = COPY $q0
992 ; CHECK: [[LHS:%[0-9]+]]:_(<4 x s32>) = COPY $q1
993 ; CHECK: [[RHS:%[0-9]+]]:_(<4 x s32>) = COPY $q2
994 ; CHECK: [[TST:%[0-9]+]]:_(<4 x s1>) = G_TRUNC [[TST32]](<4 x s32>)
995 ; CHECK: [[RES:%[0-9]+]]:_(<4 x s32>) = G_SELECT [[TST]](<4 x s1>), [[LHS]], [[RHS]]
996 ; CHECK: $q0 = COPY [[RES]]
997 define <4 x i32> @test_vselect_vec(<4 x i32> %tst32, <4 x i32> %lhs, <4 x i32> %rhs) {
998 %tst = trunc <4 x i32> %tst32 to <4 x i1>
999 %res = select <4 x i1> %tst, <4 x i32> %lhs, <4 x i32> %rhs
1003 ; CHECK-LABEL: name: test_fptosi
1004 ; CHECK: [[FPADDR:%[0-9]+]]:_(p0) = COPY $x0
1005 ; CHECK: [[FP:%[0-9]+]]:_(s32) = G_LOAD [[FPADDR]](p0)
1006 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPTOSI [[FP]](s32)
1007 ; CHECK: $x0 = COPY [[RES]]
1008 define i64 @test_fptosi(float* %fp.addr) {
1009 %fp = load float, float* %fp.addr
1010 %res = fptosi float %fp to i64
1014 ; CHECK-LABEL: name: test_fptoui
1015 ; CHECK: [[FPADDR:%[0-9]+]]:_(p0) = COPY $x0
1016 ; CHECK: [[FP:%[0-9]+]]:_(s32) = G_LOAD [[FPADDR]](p0)
1017 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPTOUI [[FP]](s32)
1018 ; CHECK: $x0 = COPY [[RES]]
1019 define i64 @test_fptoui(float* %fp.addr) {
1020 %fp = load float, float* %fp.addr
1021 %res = fptoui float %fp to i64
1025 ; CHECK-LABEL: name: test_sitofp
1026 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1027 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w1
1028 ; CHECK: [[FP:%[0-9]+]]:_(s64) = G_SITOFP [[IN]](s32)
1029 ; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0)
1030 define void @test_sitofp(double* %addr, i32 %in) {
1031 %fp = sitofp i32 %in to double
1032 store double %fp, double* %addr
1036 ; CHECK-LABEL: name: test_uitofp
1037 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1038 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w1
1039 ; CHECK: [[FP:%[0-9]+]]:_(s64) = G_UITOFP [[IN]](s32)
1040 ; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0)
1041 define void @test_uitofp(double* %addr, i32 %in) {
1042 %fp = uitofp i32 %in to double
1043 store double %fp, double* %addr
1047 ; CHECK-LABEL: name: test_fpext
1048 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $s0
1049 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPEXT [[IN]](s32)
1050 ; CHECK: $d0 = COPY [[RES]]
1051 define double @test_fpext(float %in) {
1052 %res = fpext float %in to double
1056 ; CHECK-LABEL: name: test_fptrunc
1057 ; CHECK: [[IN:%[0-9]+]]:_(s64) = COPY $d0
1058 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FPTRUNC [[IN]](s64)
1059 ; CHECK: $s0 = COPY [[RES]]
1060 define float @test_fptrunc(double %in) {
1061 %res = fptrunc double %in to float
1065 ; CHECK-LABEL: name: test_constant_float
1066 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1067 ; CHECK: [[TMP:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.500000e+00
1068 ; CHECK: G_STORE [[TMP]](s32), [[ADDR]](p0)
1069 define void @test_constant_float(float* %addr) {
1070 store float 1.5, float* %addr
1074 ; CHECK-LABEL: name: float_comparison
1075 ; CHECK: [[LHSADDR:%[0-9]+]]:_(p0) = COPY $x0
1076 ; CHECK: [[RHSADDR:%[0-9]+]]:_(p0) = COPY $x1
1077 ; CHECK: [[BOOLADDR:%[0-9]+]]:_(p0) = COPY $x2
1078 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = G_LOAD [[LHSADDR]](p0)
1079 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = G_LOAD [[RHSADDR]](p0)
1080 ; CHECK: [[TST:%[0-9]+]]:_(s1) = nnan ninf nsz arcp contract afn reassoc G_FCMP floatpred(oge), [[LHS]](s32), [[RHS]]
1081 ; CHECK: G_STORE [[TST]](s1), [[BOOLADDR]](p0)
1082 define void @float_comparison(float* %a.addr, float* %b.addr, i1* %bool.addr) {
1083 %a = load float, float* %a.addr
1084 %b = load float, float* %b.addr
1085 %res = fcmp nnan ninf nsz arcp contract afn reassoc oge float %a, %b
1086 store i1 %res, i1* %bool.addr
1090 ; CHECK-LABEL: name: trivial_float_comparison
1091 ; CHECK: [[ENTRY_R1:%[0-9]+]]:_(s1) = G_CONSTANT i1 false
1092 ; CHECK: [[ENTRY_R2:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
1093 ; CHECK: [[R1:%[0-9]+]]:_(s1) = COPY [[ENTRY_R1]](s1)
1094 ; CHECK: [[R2:%[0-9]+]]:_(s1) = COPY [[ENTRY_R2]](s1)
1095 ; CHECK: G_ADD [[R1]], [[R2]]
1096 define i1 @trivial_float_comparison(double %a, double %b) {
1097 %r1 = fcmp false double %a, %b
1098 %r2 = fcmp true double %a, %b
1099 %sum = add i1 %r1, %r2
1105 define i32* @test_global() {
1106 ; CHECK-LABEL: name: test_global
1107 ; CHECK: [[TMP:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @var{{$}}
1108 ; CHECK: $x0 = COPY [[TMP]](p0)
1113 @var1 = addrspace(42) global i32 0
1114 define i32 addrspace(42)* @test_global_addrspace() {
1115 ; CHECK-LABEL: name: test_global
1116 ; CHECK: [[TMP:%[0-9]+]]:_(p42) = G_GLOBAL_VALUE @var1{{$}}
1117 ; CHECK: $x0 = COPY [[TMP]](p42)
1119 ret i32 addrspace(42)* @var1
1123 define void()* @test_global_func() {
1124 ; CHECK-LABEL: name: test_global_func
1125 ; CHECK: [[TMP:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @allocai64{{$}}
1126 ; CHECK: $x0 = COPY [[TMP]](p0)
1128 ret void()* @allocai64
1131 declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
1132 define void @test_memcpy(i8* %dst, i8* %src, i64 %size) {
1133 ; CHECK-LABEL: name: test_memcpy
1134 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1135 ; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1
1136 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1137 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[DST]](p0), [[SRC]](p0), [[SIZE]](s64), 0 :: (store 1 into %ir.dst), (load 1 from %ir.src)
1138 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 0)
1142 define void @test_memcpy_tail(i8* %dst, i8* %src, i64 %size) {
1143 ; CHECK-LABEL: name: test_memcpy_tail
1144 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1145 ; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1
1146 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1147 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[DST]](p0), [[SRC]](p0), [[SIZE]](s64), 1 :: (store 1 into %ir.dst), (load 1 from %ir.src)
1148 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 0)
1152 declare void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)*, i8 addrspace(1)*, i64, i1)
1153 define void @test_memcpy_nonzero_as(i8 addrspace(1)* %dst, i8 addrspace(1) * %src, i64 %size) {
1154 ; CHECK-LABEL: name: test_memcpy_nonzero_as
1155 ; CHECK: [[DST:%[0-9]+]]:_(p1) = COPY $x0
1156 ; CHECK: [[SRC:%[0-9]+]]:_(p1) = COPY $x1
1157 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1158 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[DST]](p1), [[SRC]](p1), [[SIZE]](s64), 0 :: (store 1 into %ir.dst, addrspace 1), (load 1 from %ir.src, addrspace 1)
1159 call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* %dst, i8 addrspace(1)* %src, i64 %size, i1 0)
1163 declare void @llvm.memmove.p0i8.p0i8.i64(i8*, i8*, i64, i1)
1164 define void @test_memmove(i8* %dst, i8* %src, i64 %size) {
1165 ; CHECK-LABEL: name: test_memmove
1166 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1167 ; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1
1168 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1169 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memmove), [[DST]](p0), [[SRC]](p0), [[SIZE]](s64), 0 :: (store 1 into %ir.dst), (load 1 from %ir.src)
1170 call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 0)
1174 declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i1)
1175 define void @test_memset(i8* %dst, i8 %val, i64 %size) {
1176 ; CHECK-LABEL: name: test_memset
1177 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1178 ; CHECK: [[SRC_C:%[0-9]+]]:_(s32) = COPY $w1
1179 ; CHECK: [[SRC:%[0-9]+]]:_(s8) = G_TRUNC [[SRC_C]]
1180 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1181 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memset), [[DST]](p0), [[SRC]](s8), [[SIZE]](s64), 0 :: (store 1 into %ir.dst)
1182 call void @llvm.memset.p0i8.i64(i8* %dst, i8 %val, i64 %size, i1 0)
1186 define void @test_large_const(i128* %addr) {
1187 ; CHECK-LABEL: name: test_large_const
1188 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1189 ; CHECK: [[VAL:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
1190 ; CHECK: G_STORE [[VAL]](s128), [[ADDR]](p0)
1191 store i128 42, i128* %addr
1195 ; When there was no formal argument handling (so the first BB was empty) we used
1196 ; to insert the constants at the end of the block, even if they were encountered
1197 ; after the block's terminators had been emitted. Also make sure the order is
1199 define i8* @test_const_placement() {
1200 ; CHECK-LABEL: name: test_const_placement
1201 ; CHECK: bb.{{[0-9]+}} (%ir-block.{{[0-9]+}}):
1202 ; CHECK: [[VAL_INT:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
1203 ; CHECK: [[VAL:%[0-9]+]]:_(p0) = G_INTTOPTR [[VAL_INT]](s32)
1204 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
1208 ret i8* inttoptr(i32 42 to i8*)
1211 declare void @llvm.va_end(i8*)
1212 define void @test_va_end(i8* %list) {
1213 ; CHECK-LABEL: name: test_va_end
1215 ; CHECK-NOT: INTRINSIC
1216 ; CHECK: RET_ReallyLR
1217 call void @llvm.va_end(i8* %list)
1221 define void @test_va_arg(i8* %list) {
1222 ; CHECK-LABEL: test_va_arg
1223 ; CHECK: [[LIST:%[0-9]+]]:_(p0) = COPY $x0
1224 ; CHECK: G_VAARG [[LIST]](p0), 8
1225 ; CHECK: G_VAARG [[LIST]](p0), 1
1226 ; CHECK: G_VAARG [[LIST]](p0), 16
1228 %v0 = va_arg i8* %list, i64
1229 %v1 = va_arg i8* %list, i8
1230 %v2 = va_arg i8* %list, i128
1234 declare float @llvm.pow.f32(float, float)
1235 define float @test_pow_intrin(float %l, float %r) {
1236 ; CHECK-LABEL: name: test_pow_intrin
1237 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $s0
1238 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $s1
1239 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FPOW [[LHS]], [[RHS]]
1240 ; CHECK: $s0 = COPY [[RES]]
1241 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.pow.f32(float %l, float %r)
1245 declare float @llvm.fma.f32(float, float, float)
1246 define float @test_fma_intrin(float %a, float %b, float %c) {
1247 ; CHECK-LABEL: name: test_fma_intrin
1248 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1249 ; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $s1
1250 ; CHECK: [[C:%[0-9]+]]:_(s32) = COPY $s2
1251 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FMA [[A]], [[B]], [[C]]
1252 ; CHECK: $s0 = COPY [[RES]]
1253 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.fma.f32(float %a, float %b, float %c)
1257 declare float @llvm.exp.f32(float)
1258 define float @test_exp_intrin(float %a) {
1259 ; CHECK-LABEL: name: test_exp_intrin
1260 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1261 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FEXP [[A]]
1262 ; CHECK: $s0 = COPY [[RES]]
1263 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.exp.f32(float %a)
1267 declare float @llvm.exp2.f32(float)
1268 define float @test_exp2_intrin(float %a) {
1269 ; CHECK-LABEL: name: test_exp2_intrin
1270 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1271 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FEXP2 [[A]]
1272 ; CHECK: $s0 = COPY [[RES]]
1273 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.exp2.f32(float %a)
1277 declare float @llvm.log.f32(float)
1278 define float @test_log_intrin(float %a) {
1279 ; CHECK-LABEL: name: test_log_intrin
1280 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1281 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FLOG [[A]]
1282 ; CHECK: $s0 = COPY [[RES]]
1283 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.log.f32(float %a)
1287 declare float @llvm.log2.f32(float)
1288 define float @test_log2_intrin(float %a) {
1289 ; CHECK-LABEL: name: test_log2_intrin
1290 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1291 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FLOG2 [[A]]
1292 ; CHECK: $s0 = COPY [[RES]]
1293 %res = call float @llvm.log2.f32(float %a)
1297 declare float @llvm.log10.f32(float)
1298 define float @test_log10_intrin(float %a) {
1299 ; CHECK-LABEL: name: test_log10_intrin
1300 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1301 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FLOG10 [[A]]
1302 ; CHECK: $s0 = COPY [[RES]]
1303 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.log10.f32(float %a)
1307 declare float @llvm.fabs.f32(float)
1308 define float @test_fabs_intrin(float %a) {
1309 ; CHECK-LABEL: name: test_fabs_intrin
1310 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1311 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FABS [[A]]
1312 ; CHECK: $s0 = COPY [[RES]]
1313 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.fabs.f32(float %a)
1317 declare float @llvm.copysign.f32(float, float)
1318 define float @test_fcopysign_intrin(float %a, float %b) {
1319 ; CHECK-LABEL: name: test_fcopysign_intrin
1320 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1321 ; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $s1
1322 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FCOPYSIGN [[A]], [[B]]
1323 ; CHECK: $s0 = COPY [[RES]]
1325 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.copysign.f32(float %a, float %b)
1329 declare float @llvm.canonicalize.f32(float)
1330 define float @test_fcanonicalize_intrin(float %a) {
1331 ; CHECK-LABEL: name: test_fcanonicalize_intrin
1332 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1333 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FCANONICALIZE [[A]]
1334 ; CHECK: $s0 = COPY [[RES]]
1335 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.canonicalize.f32(float %a)
1339 declare float @llvm.trunc.f32(float)
1340 define float @test_intrinsic_trunc(float %a) {
1341 ; CHECK-LABEL: name: test_intrinsic_trunc
1342 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1343 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_TRUNC [[A]]
1344 ; CHECK: $s0 = COPY [[RES]]
1345 %res = call float @llvm.trunc.f32(float %a)
1349 declare float @llvm.round.f32(float)
1350 define float @test_intrinsic_round(float %a) {
1351 ; CHECK-LABEL: name: test_intrinsic_round
1352 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1353 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_ROUND [[A]]
1354 ; CHECK: $s0 = COPY [[RES]]
1355 %res = call float @llvm.round.f32(float %a)
1359 declare i32 @llvm.ctlz.i32(i32, i1)
1360 define i32 @test_ctlz_intrinsic_zero_not_undef(i32 %a) {
1361 ; CHECK-LABEL: name: test_ctlz_intrinsic_zero_not_undef
1362 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1363 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTLZ [[A]]
1364 ; CHECK: $w0 = COPY [[RES]]
1365 %res = call i32 @llvm.ctlz.i32(i32 %a, i1 0)
1369 declare i32 @llvm.cttz.i32(i32, i1)
1370 define i32 @test_cttz_intrinsic_zero_undef(i32 %a) {
1371 ; CHECK-LABEL: name: test_cttz_intrinsic_zero_undef
1372 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1373 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[A]]
1374 ; CHECK: $w0 = COPY [[RES]]
1375 %res = call i32 @llvm.cttz.i32(i32 %a, i1 1)
1379 declare i32 @llvm.ctpop.i32(i32)
1380 define i32 @test_ctpop_intrinsic(i32 %a) {
1381 ; CHECK-LABEL: name: test_ctpop
1382 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1383 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTPOP [[A]]
1384 ; CHECK: $w0 = COPY [[RES]]
1385 %res = call i32 @llvm.ctpop.i32(i32 %a)
1389 declare i32 @llvm.bitreverse.i32(i32)
1390 define i32 @test_bitreverse_intrinsic(i32 %a) {
1391 ; CHECK-LABEL: name: test_bitreverse
1392 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1393 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_BITREVERSE [[A]]
1394 ; CHECK: $w0 = COPY [[RES]]
1395 %res = call i32 @llvm.bitreverse.i32(i32 %a)
1399 declare void @llvm.lifetime.start.p0i8(i64, i8*)
1400 declare void @llvm.lifetime.end.p0i8(i64, i8*)
1401 define void @test_lifetime_intrin() {
1402 ; CHECK-LABEL: name: test_lifetime_intrin
1403 ; CHECK: RET_ReallyLR
1404 ; O3-LABEL: name: test_lifetime_intrin
1405 ; O3: {{%[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.0.slot
1406 ; O3-NEXT: LIFETIME_START %stack.0.slot
1407 ; O3-NEXT: LIFETIME_END %stack.0.slot
1408 ; O3-NEXT: RET_ReallyLR
1409 %slot = alloca i8, i32 4
1410 call void @llvm.lifetime.start.p0i8(i64 0, i8* %slot)
1411 call void @llvm.lifetime.end.p0i8(i64 0, i8* %slot)
1415 define void @test_load_store_atomics(i8* %addr) {
1416 ; CHECK-LABEL: name: test_load_store_atomics
1417 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1418 ; CHECK: [[V0:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load unordered 1 from %ir.addr)
1419 ; CHECK: G_STORE [[V0]](s8), [[ADDR]](p0) :: (store monotonic 1 into %ir.addr)
1420 ; CHECK: [[V1:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load acquire 1 from %ir.addr)
1421 ; CHECK: G_STORE [[V1]](s8), [[ADDR]](p0) :: (store release 1 into %ir.addr)
1422 ; CHECK: [[V2:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load syncscope("singlethread") seq_cst 1 from %ir.addr)
1423 ; CHECK: G_STORE [[V2]](s8), [[ADDR]](p0) :: (store syncscope("singlethread") monotonic 1 into %ir.addr)
1424 %v0 = load atomic i8, i8* %addr unordered, align 1
1425 store atomic i8 %v0, i8* %addr monotonic, align 1
1427 %v1 = load atomic i8, i8* %addr acquire, align 1
1428 store atomic i8 %v1, i8* %addr release, align 1
1430 %v2 = load atomic i8, i8* %addr syncscope("singlethread") seq_cst, align 1
1431 store atomic i8 %v2, i8* %addr syncscope("singlethread") monotonic, align 1
1436 define float @test_fneg_f32(float %x) {
1437 ; CHECK-LABEL: name: test_fneg_f32
1438 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0
1439 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FNEG [[ARG]]
1440 ; CHECK: $s0 = COPY [[RES]](s32)
1441 %neg = fsub float -0.000000e+00, %x
1445 define float @test_fneg_f32_fmf(float %x) {
1446 ; CHECK-LABEL: name: test_fneg_f32
1447 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0
1448 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]]
1449 ; CHECK: $s0 = COPY [[RES]](s32)
1450 %neg = fsub fast float -0.000000e+00, %x
1454 define double @test_fneg_f64(double %x) {
1455 ; CHECK-LABEL: name: test_fneg_f64
1456 ; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0
1457 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FNEG [[ARG]]
1458 ; CHECK: $d0 = COPY [[RES]](s64)
1459 %neg = fsub double -0.000000e+00, %x
1463 define double @test_fneg_f64_fmf(double %x) {
1464 ; CHECK-LABEL: name: test_fneg_f64
1465 ; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0
1466 ; CHECK: [[RES:%[0-9]+]]:_(s64) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]]
1467 ; CHECK: $d0 = COPY [[RES]](s64)
1468 %neg = fsub fast double -0.000000e+00, %x
1472 define void @test_trivial_inlineasm() {
1473 ; CHECK-LABEL: name: test_trivial_inlineasm
1474 ; CHECK: INLINEASM &wibble, 1
1475 ; CHECK: INLINEASM &wibble, 0
1476 call void asm sideeffect "wibble", ""()
1477 call void asm "wibble", ""()
1481 define <2 x i32> @test_insertelement(<2 x i32> %vec, i32 %elt, i32 %idx){
1482 ; CHECK-LABEL: name: test_insertelement
1483 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1484 ; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0
1485 ; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w1
1486 ; CHECK: [[RES:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[VEC]], [[ELT]](s32), [[IDX]](s32)
1487 ; CHECK: $d0 = COPY [[RES]](<2 x s32>)
1488 %res = insertelement <2 x i32> %vec, i32 %elt, i32 %idx
1492 define i32 @test_extractelement(<2 x i32> %vec, i32 %idx) {
1493 ; CHECK-LABEL: name: test_extractelement
1494 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1495 ; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w0
1496 ; CHECK: [[IDXEXT:%[0-9]+]]:_(s64) = G_SEXT [[IDX]]
1497 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDXEXT]](s64)
1498 ; CHECK: $w0 = COPY [[RES]](s32)
1499 %res = extractelement <2 x i32> %vec, i32 %idx
1503 define i32 @test_extractelement_const_idx(<2 x i32> %vec) {
1504 ; CHECK-LABEL: name: test_extractelement
1505 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1506 ; CHECK: [[IDX:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1507 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDX]](s64)
1508 ; CHECK: $w0 = COPY [[RES]](s32)
1509 %res = extractelement <2 x i32> %vec, i32 1
1513 define i32 @test_singleelementvector(i32 %elt){
1514 ; CHECK-LABEL: name: test_singleelementvector
1515 ; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0
1516 ; CHECK-NOT: G_INSERT_VECTOR_ELT
1517 ; CHECK-NOT: G_EXTRACT_VECTOR_ELT
1518 ; CHECK: $w0 = COPY [[ELT]](s32)
1519 %vec = insertelement <1 x i32> undef, i32 %elt, i32 0
1520 %res = extractelement <1 x i32> %vec, i32 0
1524 define <2 x i32> @test_constantaggzerovector_v2i32() {
1525 ; CHECK-LABEL: name: test_constantaggzerovector_v2i32
1526 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1527 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32)
1528 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1529 ret <2 x i32> zeroinitializer
1532 define <2 x float> @test_constantaggzerovector_v2f32() {
1533 ; CHECK-LABEL: name: test_constantaggzerovector_v2f32
1534 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_FCONSTANT float 0.000000e+00
1535 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32)
1536 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1537 ret <2 x float> zeroinitializer
1540 define i32 @test_constantaggzerovector_v3i32() {
1541 ; CHECK-LABEL: name: test_constantaggzerovector_v3i32
1542 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1543 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32), [[ZERO]](s32)
1544 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1545 %elt = extractelement <3 x i32> zeroinitializer, i32 1
1549 define <2 x i32> @test_constantdatavector_v2i32() {
1550 ; CHECK-LABEL: name: test_constantdatavector_v2i32
1551 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1552 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1553 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32)
1554 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1555 ret <2 x i32> <i32 1, i32 2>
1558 define i32 @test_constantdatavector_v3i32() {
1559 ; CHECK-LABEL: name: test_constantdatavector_v3i32
1560 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1561 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1562 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1563 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32), [[C3]](s32)
1564 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1565 %elt = extractelement <3 x i32> <i32 1, i32 2, i32 3>, i32 1
1569 define <4 x i32> @test_constantdatavector_v4i32() {
1570 ; CHECK-LABEL: name: test_constantdatavector_v4i32
1571 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1572 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1573 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1574 ; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
1575 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32), [[C3]](s32), [[C4]](s32)
1576 ; CHECK: $q0 = COPY [[VEC]](<4 x s32>)
1577 ret <4 x i32> <i32 1, i32 2, i32 3, i32 4>
1580 define <2 x double> @test_constantdatavector_v2f64() {
1581 ; CHECK-LABEL: name: test_constantdatavector_v2f64
1582 ; CHECK: [[FC1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
1583 ; CHECK: [[FC2:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
1584 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[FC1]](s64), [[FC2]](s64)
1585 ; CHECK: $q0 = COPY [[VEC]](<2 x s64>)
1586 ret <2 x double> <double 1.0, double 2.0>
1589 define i32 @test_constantaggzerovector_v1s32(i32 %arg){
1590 ; CHECK-LABEL: name: test_constantaggzerovector_v1s32
1591 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1592 ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1593 ; CHECK-NOT: G_MERGE_VALUES
1594 ; CHECK: G_ADD [[ARG]], [[C0]]
1595 %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1596 %add = add <1 x i32> %vec, zeroinitializer
1597 %res = extractelement <1 x i32> %add, i32 0
1601 define i32 @test_constantdatavector_v1s32(i32 %arg){
1602 ; CHECK-LABEL: name: test_constantdatavector_v1s32
1603 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1604 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1605 ; CHECK-NOT: G_MERGE_VALUES
1606 ; CHECK: G_ADD [[ARG]], [[C1]]
1607 %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1608 %add = add <1 x i32> %vec, <i32 1>
1609 %res = extractelement <1 x i32> %add, i32 0
1613 declare ghccc float @different_call_conv_target(float %x)
1614 define float @test_different_call_conv_target(float %x) {
1615 ; CHECK-LABEL: name: test_different_call_conv
1616 ; CHECK: [[X:%[0-9]+]]:_(s32) = COPY $s0
1617 ; CHECK: $s8 = COPY [[X]]
1618 ; CHECK: BL @different_call_conv_target, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s8, implicit-def $s0
1619 %res = call ghccc float @different_call_conv_target(float %x)
1623 define <2 x i32> @test_shufflevector_s32_v2s32(i32 %arg) {
1624 ; CHECK-LABEL: name: test_shufflevector_s32_v2s32
1625 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1626 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
1627 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0, 0)
1628 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1629 %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1630 %res = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
1634 define i32 @test_shufflevector_v2s32_s32(<2 x i32> %arg) {
1635 ; CHECK-LABEL: name: test_shufflevector_v2s32_s32
1636 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1637 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(1)
1638 ; CHECK: $w0 = COPY [[RES]](s32)
1639 %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <1 x i32> <i32 1>
1640 %res = extractelement <1 x i32> %vec, i32 0
1644 define <2 x i32> @test_shufflevector_v2s32_v2s32_undef(<2 x i32> %arg) {
1645 ; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32_undef
1646 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1647 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1648 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(undef, undef)
1649 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1650 %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> undef
1654 define <2 x i32> @test_shufflevector_v2s32_v2s32_undef_0(<2 x i32> %arg) {
1655 ; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32_undef_0
1656 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1657 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1658 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(undef, 0)
1659 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1660 %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 undef, i32 0>
1664 define <2 x i32> @test_shufflevector_v2s32_v2s32_0_undef(<2 x i32> %arg) {
1665 ; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32_0_undef
1666 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1667 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1668 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(0, undef)
1669 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1670 %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 0, i32 undef>
1674 define i32 @test_shufflevector_v2s32_v3s32(<2 x i32> %arg) {
1675 ; CHECK-LABEL: name: test_shufflevector_v2s32_v3s32
1676 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1677 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1678 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(1, 0, 1)
1679 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1680 %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <3 x i32> <i32 1, i32 0, i32 1>
1681 %res = extractelement <3 x i32> %vec, i32 0
1685 define <4 x i32> @test_shufflevector_v2s32_v4s32(<2 x i32> %arg1, <2 x i32> %arg2) {
1686 ; CHECK-LABEL: name: test_shufflevector_v2s32_v4s32
1687 ; CHECK: [[ARG1:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1688 ; CHECK: [[ARG2:%[0-9]+]]:_(<2 x s32>) = COPY $d1
1689 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[ARG1]](<2 x s32>), [[ARG2]], shufflemask(0, 1, 2, 3)
1690 ; CHECK: $q0 = COPY [[VEC]](<4 x s32>)
1691 %res = shufflevector <2 x i32> %arg1, <2 x i32> %arg2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1695 define <2 x i32> @test_shufflevector_v4s32_v2s32(<4 x i32> %arg) {
1696 ; CHECK-LABEL: name: test_shufflevector_v4s32_v2s32
1697 ; CHECK: [[ARG:%[0-9]+]]:_(<4 x s32>) = COPY $q0
1698 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF
1699 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<4 x s32>), [[UNDEF]], shufflemask(1, 3)
1700 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1701 %res = shufflevector <4 x i32> %arg, <4 x i32> undef, <2 x i32> <i32 1, i32 3>
1706 define <16 x i8> @test_shufflevector_v8s8_v16s8(<8 x i8> %arg1, <8 x i8> %arg2) {
1707 ; CHECK-LABEL: name: test_shufflevector_v8s8_v16s8
1708 ; CHECK: [[ARG1:%[0-9]+]]:_(<8 x s8>) = COPY $d0
1709 ; CHECK: [[ARG2:%[0-9]+]]:_(<8 x s8>) = COPY $d1
1710 ; CHECK: [[VEC:%[0-9]+]]:_(<16 x s8>) = G_SHUFFLE_VECTOR [[ARG1]](<8 x s8>), [[ARG2]], shufflemask(0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15)
1711 ; CHECK: $q0 = COPY [[VEC]](<16 x s8>)
1712 %res = shufflevector <8 x i8> %arg1, <8 x i8> %arg2, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
1716 ; CHECK-LABEL: test_constant_vector
1717 ; CHECK: [[UNDEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
1718 ; CHECK: [[F:%[0-9]+]]:_(s16) = G_FCONSTANT half 0xH3C00
1719 ; CHECK: [[M:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UNDEF]](s16), [[UNDEF]](s16), [[UNDEF]](s16), [[F]](s16)
1720 ; CHECK: $d0 = COPY [[M]](<4 x s16>)
1721 define <4 x half> @test_constant_vector() {
1722 ret <4 x half> <half undef, half undef, half undef, half 0xH3C00>
1725 define i32 @test_target_mem_intrinsic(i32* %addr) {
1726 ; CHECK-LABEL: name: test_target_mem_intrinsic
1727 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1728 ; CHECK: [[VAL:%[0-9]+]]:_(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), [[ADDR]](p0) :: (volatile load 4 from %ir.addr)
1729 ; CHECK: G_TRUNC [[VAL]](s64)
1730 %val = call i64 @llvm.aarch64.ldxr.p0i32(i32* %addr)
1731 %trunc = trunc i64 %val to i32
1735 declare i64 @llvm.aarch64.ldxr.p0i32(i32*) nounwind
1737 %zerosize_type = type {}
1739 define %zerosize_type @test_empty_load_store(%zerosize_type *%ptr, %zerosize_type %in) noinline optnone {
1740 ; CHECK-LABEL: name: test_empty_load_store
1741 ; CHECK-NOT: G_STORE
1743 ; CHECK: RET_ReallyLR
1745 store %zerosize_type undef, %zerosize_type* undef, align 4
1746 %val = load %zerosize_type, %zerosize_type* %ptr, align 4
1747 ret %zerosize_type %in
1751 define i64 @test_phi_loop(i32 %n) {
1752 ; CHECK-LABEL: name: test_phi_loop
1753 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
1754 ; CHECK: [[CST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1755 ; CHECK: [[CST2:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1756 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
1757 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1759 ; CHECK: [[PN1:%[0-9]+]]:_(s32) = G_PHI [[ARG1]](s32), %bb.1, [[SUB:%[0-9]+]](s32), %bb.2
1760 ; CHECK: [[PN2:%[0-9]+]]:_(s64) = G_PHI [[CST3]](s64), %bb.1, [[PN3:%[0-9]+]](s64), %bb.2
1761 ; CHECK: [[PN3]]:_(s64) = G_PHI [[CST4]](s64), %bb.1, [[ADD:%[0-9]+]](s64), %bb.2
1762 ; CHECK: [[ADD]]:_(s64) = G_ADD [[PN2]], [[PN3]]
1763 ; CHECK: [[SUB]]:_(s32) = G_SUB [[PN1]], [[CST1]]
1764 ; CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(sle), [[PN1]](s32), [[CST2]]
1765 ; CHECK: G_BRCOND [[CMP]](s1), %bb.3
1768 ; CHECK: $x0 = COPY [[PN2]](s64)
1769 ; CHECK: RET_ReallyLR implicit $x0
1774 %counter = phi i32 [ %n, %entry ], [ %counter.dec, %loop ]
1775 %elem = phi { i64, i64 } [ { i64 0, i64 1 }, %entry ], [ %updated, %loop ]
1776 %prev = extractvalue { i64, i64 } %elem, 0
1777 %curr = extractvalue { i64, i64 } %elem, 1
1778 %next = add i64 %prev, %curr
1779 %shifted = insertvalue { i64, i64 } %elem, i64 %curr, 0
1780 %updated = insertvalue { i64, i64 } %shifted, i64 %next, 1
1781 %counter.dec = sub i32 %counter, 1
1782 %cond = icmp sle i32 %counter, 0
1783 br i1 %cond, label %exit, label %loop
1786 %res = extractvalue { i64, i64 } %elem, 0
1790 define void @test_phi_diamond({ i8, i16, i32 }* %a.ptr, { i8, i16, i32 }* %b.ptr, i1 %selector, { i8, i16, i32 }* %dst) {
1791 ; CHECK-LABEL: name: test_phi_diamond
1792 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
1793 ; CHECK: [[ARG2:%[0-9]+]]:_(p0) = COPY $x1
1794 ; CHECK: [[ARG3:%[0-9]+]]:_(s32) = COPY $w2
1795 ; CHECK: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[ARG3]](s32)
1796 ; CHECK: [[ARG4:%[0-9]+]]:_(p0) = COPY $x3
1797 ; CHECK: G_BRCOND [[TRUNC]](s1), %bb.2
1800 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD [[ARG1]](p0) :: (load 1 from %ir.a.ptr, align 4)
1801 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1802 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[ARG1]], [[CST1]](s64)
1803 ; CHECK: [[LD2:%[0-9]+]]:_(s16) = G_LOAD [[GEP1]](p0) :: (load 2 from %ir.a.ptr + 2)
1804 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1805 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP [[ARG1]], [[CST2]](s64)
1806 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.a.ptr + 4)
1809 ; CHECK: [[LD4:%[0-9]+]]:_(s8) = G_LOAD [[ARG2]](p0) :: (load 1 from %ir.b.ptr, align 4)
1810 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1811 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP [[ARG2]], [[CST3]](s64)
1812 ; CHECK: [[LD5:%[0-9]+]]:_(s16) = G_LOAD [[GEP3]](p0) :: (load 2 from %ir.b.ptr + 2)
1813 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1814 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP [[ARG2]], [[CST4]](s64)
1815 ; CHECK: [[LD6:%[0-9]+]]:_(s32) = G_LOAD [[GEP4]](p0) :: (load 4 from %ir.b.ptr + 4)
1817 ; CHECK: [[PN1:%[0-9]+]]:_(s8) = G_PHI [[LD1]](s8), %bb.2, [[LD4]](s8), %bb.3
1818 ; CHECK: [[PN2:%[0-9]+]]:_(s16) = G_PHI [[LD2]](s16), %bb.2, [[LD5]](s16), %bb.3
1819 ; CHECK: [[PN3:%[0-9]+]]:_(s32) = G_PHI [[LD3]](s32), %bb.2, [[LD6]](s32), %bb.3
1820 ; CHECK: G_STORE [[PN1]](s8), [[ARG4]](p0) :: (store 1 into %ir.dst, align 4)
1821 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1822 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP [[ARG4]], [[CST5]](s64)
1823 ; CHECK: G_STORE [[PN2]](s16), [[GEP5]](p0) :: (store 2 into %ir.dst + 2)
1824 ; CHECK: [[CST6:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1825 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP [[ARG4]], [[CST6]](s64)
1826 ; CHECK: G_STORE [[PN3]](s32), [[GEP6]](p0) :: (store 4 into %ir.dst + 4)
1827 ; CHECK: RET_ReallyLR
1830 br i1 %selector, label %store.a, label %store.b
1833 %a = load { i8, i16, i32 }, { i8, i16, i32 }* %a.ptr
1837 %b = load { i8, i16, i32 }, { i8, i16, i32 }* %b.ptr
1841 %v = phi { i8, i16, i32 } [ %a, %store.a ], [ %b, %store.b ]
1842 store { i8, i16, i32 } %v, { i8, i16, i32 }* %dst
1846 %agg.inner.inner = type {i64, i64}
1847 %agg.inner = type {i16, i8, %agg.inner.inner }
1848 %agg.nested = type {i32, i32, %agg.inner, i32}
1850 define void @test_nested_aggregate_const(%agg.nested *%ptr) {
1851 ; CHECK-LABEL: name: test_nested_aggregate_const
1852 ; CHECK: [[BASE:%[0-9]+]]:_(p0) = COPY $x0
1853 ; CHECK: [[CST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1854 ; CHECK: [[CST2:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
1855 ; CHECK: [[CST3:%[0-9]+]]:_(s8) = G_CONSTANT i8 3
1856 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
1857 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1858 ; CHECK: [[CST6:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
1859 ; CHECK: G_STORE [[CST1]](s32), [[BASE]](p0) :: (store 4 into %ir.ptr, align 8)
1860 ; CHECK: [[CST7:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1861 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST7]](s64)
1862 ; CHECK: G_STORE [[CST1]](s32), [[GEP1]](p0) :: (store 4 into %ir.ptr + 4)
1863 ; CHECK: [[CST8:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1864 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST8]](s64)
1865 ; CHECK: G_STORE [[CST2]](s16), [[GEP2]](p0) :: (store 2 into %ir.ptr + 8, align 8)
1866 ; CHECK: [[CST9:%[0-9]+]]:_(s64) = G_CONSTANT i64 10
1867 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST9]](s64)
1868 ; CHECK: G_STORE [[CST3]](s8), [[GEP3]](p0) :: (store 1 into %ir.ptr + 10, align 2)
1869 ; CHECK: [[CST10:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
1870 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST10]](s64)
1871 ; CHECK: G_STORE [[CST4]](s64), [[GEP4]](p0) :: (store 8 into %ir.ptr + 16)
1872 ; CHECK: [[CST11:%[0-9]+]]:_(s64) = G_CONSTANT i64 24
1873 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST11]](s64)
1874 ; CHECK: G_STORE [[CST5]](s64), [[GEP5]](p0) :: (store 8 into %ir.ptr + 24)
1875 ; CHECK: [[CST12:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
1876 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST12]](s64)
1877 ; CHECK: G_STORE [[CST6]](s32), [[GEP6]](p0) :: (store 4 into %ir.ptr + 32, align 8)
1878 store %agg.nested { i32 1, i32 1, %agg.inner { i16 2, i8 3, %agg.inner.inner {i64 5, i64 8} }, i32 13}, %agg.nested *%ptr
1882 define i1 @return_i1_zext() {
1883 ; AAPCS ABI says that booleans can only be 1 or 0, so we need to zero-extend.
1884 ; CHECK-LABEL: name: return_i1_zext
1885 ; CHECK: [[CST:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
1886 ; CHECK: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[CST]](s1)
1887 ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
1888 ; CHECK: $w0 = COPY [[ANYEXT]](s32)
1889 ; CHECK: RET_ReallyLR implicit $w0
1894 define i32 @test_atomic_cmpxchg_1(i32* %addr) {
1895 ; CHECK-LABEL: name: test_atomic_cmpxchg_1
1896 ; CHECK: bb.1.entry:
1897 ; CHECK-NEXT: successors: %bb.{{[^)]+}}
1898 ; CHECK-NEXT: liveins: $x0
1899 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1900 ; CHECK-NEXT: [[OLDVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1901 ; CHECK-NEXT: [[NEWVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1902 ; CHECK: bb.2.repeat:
1903 ; CHECK-NEXT: successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
1904 ; CHECK: [[OLDVALRES:%[0-9]+]]:_(s32), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store monotonic monotonic 4 on %ir.addr)
1905 ; CHECK-NEXT: G_BRCOND [[SUCCESS]](s1), %bb.3
1906 ; CHECK-NEXT: G_BR %bb.2
1911 %val_success = cmpxchg i32* %addr, i32 0, i32 1 monotonic monotonic
1912 %value_loaded = extractvalue { i32, i1 } %val_success, 0
1913 %success = extractvalue { i32, i1 } %val_success, 1
1914 br i1 %success, label %done, label %repeat
1916 ret i32 %value_loaded
1919 ; Try one cmpxchg with a small type and high atomic ordering.
1920 define i16 @test_atomic_cmpxchg_2(i16* %addr) {
1921 ; CHECK-LABEL: name: test_atomic_cmpxchg_2
1922 ; CHECK: bb.1.entry:
1923 ; CHECK-NEXT: successors: %bb.2({{[^)]+}})
1924 ; CHECK-NEXT: liveins: $x0
1925 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1926 ; CHECK-NEXT: [[OLDVAL:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
1927 ; CHECK-NEXT: [[NEWVAL:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
1928 ; CHECK: bb.2.repeat:
1929 ; CHECK-NEXT: successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
1930 ; CHECK: [[OLDVALRES:%[0-9]+]]:_(s16), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store seq_cst seq_cst 2 on %ir.addr)
1931 ; CHECK-NEXT: G_BRCOND [[SUCCESS]](s1), %bb.3
1932 ; CHECK-NEXT: G_BR %bb.2
1937 %val_success = cmpxchg i16* %addr, i16 0, i16 1 seq_cst seq_cst
1938 %value_loaded = extractvalue { i16, i1 } %val_success, 0
1939 %success = extractvalue { i16, i1 } %val_success, 1
1940 br i1 %success, label %done, label %repeat
1942 ret i16 %value_loaded
1945 ; Try one cmpxchg where the success order and failure order differ.
1946 define i64 @test_atomic_cmpxchg_3(i64* %addr) {
1947 ; CHECK-LABEL: name: test_atomic_cmpxchg_3
1948 ; CHECK: bb.1.entry:
1949 ; CHECK-NEXT: successors: %bb.2({{[^)]+}})
1950 ; CHECK-NEXT: liveins: $x0
1951 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1952 ; CHECK-NEXT: [[OLDVAL:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
1953 ; CHECK-NEXT: [[NEWVAL:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1954 ; CHECK: bb.2.repeat:
1955 ; CHECK-NEXT: successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
1956 ; CHECK: [[OLDVALRES:%[0-9]+]]:_(s64), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store seq_cst acquire 8 on %ir.addr)
1957 ; CHECK-NEXT: G_BRCOND [[SUCCESS]](s1), %bb.3
1958 ; CHECK-NEXT: G_BR %bb.2
1963 %val_success = cmpxchg i64* %addr, i64 0, i64 1 seq_cst acquire
1964 %value_loaded = extractvalue { i64, i1 } %val_success, 0
1965 %success = extractvalue { i64, i1 } %val_success, 1
1966 br i1 %success, label %done, label %repeat
1968 ret i64 %value_loaded
1971 ; Try a monotonic atomicrmw xchg
1972 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
1973 define i32 @test_atomicrmw_xchg(i256* %addr) {
1974 ; CHECK-LABEL: name: test_atomicrmw_xchg
1975 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
1976 ; CHECK-NEXT: liveins: $x0
1977 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1978 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
1979 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_XCHG [[ADDR]](p0), [[VAL]] :: (load store monotonic 32 on %ir.addr)
1980 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
1981 %oldval = atomicrmw xchg i256* %addr, i256 1 monotonic
1982 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
1983 ; test so work around it by truncating to i32 for now.
1984 %oldval.trunc = trunc i256 %oldval to i32
1985 ret i32 %oldval.trunc
1988 ; Try an acquire atomicrmw add
1989 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
1990 define i32 @test_atomicrmw_add(i256* %addr) {
1991 ; CHECK-LABEL: name: test_atomicrmw_add
1992 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
1993 ; CHECK-NEXT: liveins: $x0
1994 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1995 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
1996 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_ADD [[ADDR]](p0), [[VAL]] :: (load store acquire 32 on %ir.addr)
1997 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
1998 %oldval = atomicrmw add i256* %addr, i256 1 acquire
1999 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2000 ; test so work around it by truncating to i32 for now.
2001 %oldval.trunc = trunc i256 %oldval to i32
2002 ret i32 %oldval.trunc
2005 ; Try a release atomicrmw sub
2006 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2007 define i32 @test_atomicrmw_sub(i256* %addr) {
2008 ; CHECK-LABEL: name: test_atomicrmw_sub
2009 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2010 ; CHECK-NEXT: liveins: $x0
2011 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2012 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2013 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_SUB [[ADDR]](p0), [[VAL]] :: (load store release 32 on %ir.addr)
2014 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2015 %oldval = atomicrmw sub i256* %addr, i256 1 release
2016 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2017 ; test so work around it by truncating to i32 for now.
2018 %oldval.trunc = trunc i256 %oldval to i32
2019 ret i32 %oldval.trunc
2022 ; Try an acq_rel atomicrmw and
2023 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2024 define i32 @test_atomicrmw_and(i256* %addr) {
2025 ; CHECK-LABEL: name: test_atomicrmw_and
2026 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2027 ; CHECK-NEXT: liveins: $x0
2028 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2029 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2030 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_AND [[ADDR]](p0), [[VAL]] :: (load store acq_rel 32 on %ir.addr)
2031 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2032 %oldval = atomicrmw and i256* %addr, i256 1 acq_rel
2033 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2034 ; test so work around it by truncating to i32 for now.
2035 %oldval.trunc = trunc i256 %oldval to i32
2036 ret i32 %oldval.trunc
2039 ; Try an seq_cst atomicrmw nand
2040 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2041 define i32 @test_atomicrmw_nand(i256* %addr) {
2042 ; CHECK-LABEL: name: test_atomicrmw_nand
2043 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2044 ; CHECK-NEXT: liveins: $x0
2045 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2046 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2047 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_NAND [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2048 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2049 %oldval = atomicrmw nand i256* %addr, i256 1 seq_cst
2050 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2051 ; test so work around it by truncating to i32 for now.
2052 %oldval.trunc = trunc i256 %oldval to i32
2053 ret i32 %oldval.trunc
2056 ; Try an seq_cst atomicrmw or
2057 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2058 define i32 @test_atomicrmw_or(i256* %addr) {
2059 ; CHECK-LABEL: name: test_atomicrmw_or
2060 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2061 ; CHECK-NEXT: liveins: $x0
2062 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2063 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2064 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_OR [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2065 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2066 %oldval = atomicrmw or i256* %addr, i256 1 seq_cst
2067 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2068 ; test so work around it by truncating to i32 for now.
2069 %oldval.trunc = trunc i256 %oldval to i32
2070 ret i32 %oldval.trunc
2073 ; Try an seq_cst atomicrmw xor
2074 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2075 define i32 @test_atomicrmw_xor(i256* %addr) {
2076 ; CHECK-LABEL: name: test_atomicrmw_xor
2077 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2078 ; CHECK-NEXT: liveins: $x0
2079 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2080 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2081 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_XOR [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2082 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2083 %oldval = atomicrmw xor i256* %addr, i256 1 seq_cst
2084 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2085 ; test so work around it by truncating to i32 for now.
2086 %oldval.trunc = trunc i256 %oldval to i32
2087 ret i32 %oldval.trunc
2090 ; Try an seq_cst atomicrmw min
2091 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2092 define i32 @test_atomicrmw_min(i256* %addr) {
2093 ; CHECK-LABEL: name: test_atomicrmw_min
2094 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2095 ; CHECK-NEXT: liveins: $x0
2096 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2097 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2098 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_MIN [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2099 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2100 %oldval = atomicrmw min i256* %addr, i256 1 seq_cst
2101 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2102 ; test so work around it by truncating to i32 for now.
2103 %oldval.trunc = trunc i256 %oldval to i32
2104 ret i32 %oldval.trunc
2107 ; Try an seq_cst atomicrmw max
2108 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2109 define i32 @test_atomicrmw_max(i256* %addr) {
2110 ; CHECK-LABEL: name: test_atomicrmw_max
2111 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2112 ; CHECK-NEXT: liveins: $x0
2113 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2114 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2115 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_MAX [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2116 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2117 %oldval = atomicrmw max i256* %addr, i256 1 seq_cst
2118 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2119 ; test so work around it by truncating to i32 for now.
2120 %oldval.trunc = trunc i256 %oldval to i32
2121 ret i32 %oldval.trunc
2124 ; Try an seq_cst atomicrmw unsigned min
2125 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2126 define i32 @test_atomicrmw_umin(i256* %addr) {
2127 ; CHECK-LABEL: name: test_atomicrmw_umin
2128 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2129 ; CHECK-NEXT: liveins: $x0
2130 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2131 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2132 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_UMIN [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2133 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2134 %oldval = atomicrmw umin i256* %addr, i256 1 seq_cst
2135 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2136 ; test so work around it by truncating to i32 for now.
2137 %oldval.trunc = trunc i256 %oldval to i32
2138 ret i32 %oldval.trunc
2141 ; Try an seq_cst atomicrmw unsigned max
2142 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2143 define i32 @test_atomicrmw_umax(i256* %addr) {
2144 ; CHECK-LABEL: name: test_atomicrmw_umax
2145 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2146 ; CHECK-NEXT: liveins: $x0
2147 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2148 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2149 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_UMAX [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2150 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2151 %oldval = atomicrmw umax i256* %addr, i256 1 seq_cst
2152 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2153 ; test so work around it by truncating to i32 for now.
2154 %oldval.trunc = trunc i256 %oldval to i32
2155 ret i32 %oldval.trunc
2158 @addr = global i8* null
2160 define void @test_blockaddress() {
2161 ; CHECK-LABEL: name: test_blockaddress
2162 ; CHECK: [[BADDR:%[0-9]+]]:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
2163 ; CHECK: G_STORE [[BADDR]](p0)
2164 store i8* blockaddress(@test_blockaddress, %block), i8** @addr
2165 indirectbr i8* blockaddress(@test_blockaddress, %block), [label %block]
2171 declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) readonly nounwind
2172 declare void @llvm.invariant.end.p0i8({}*, i64, i8* nocapture) nounwind
2173 define void @test_invariant_intrin() {
2174 ; CHECK-LABEL: name: test_invariant_intrin
2175 ; CHECK: %{{[0-9]+}}:_(s64) = G_IMPLICIT_DEF
2176 ; CHECK-NEXT: RET_ReallyLR
2178 %y = bitcast %t* %x to i8*
2179 %inv = call {}* @llvm.invariant.start.p0i8(i64 8, i8* %y)
2180 call void @llvm.invariant.end.p0i8({}* %inv, i64 8, i8* %y)
2184 declare float @llvm.ceil.f32(float)
2185 define float @test_ceil_f32(float %x) {
2186 ; CHECK-LABEL: name: test_ceil_f32
2187 ; CHECK: %{{[0-9]+}}:_(s32) = G_FCEIL %{{[0-9]+}}
2188 %y = call float @llvm.ceil.f32(float %x)
2192 declare double @llvm.ceil.f64(double)
2193 define double @test_ceil_f64(double %x) {
2194 ; CHECK-LABEL: name: test_ceil_f64
2195 ; CHECK: %{{[0-9]+}}:_(s64) = G_FCEIL %{{[0-9]+}}
2196 %y = call double @llvm.ceil.f64(double %x)
2200 declare <2 x float> @llvm.ceil.v2f32(<2 x float>)
2201 define <2 x float> @test_ceil_v2f32(<2 x float> %x) {
2202 ; CHECK-LABEL: name: test_ceil_v2f32
2203 ; CHECK: %{{[0-9]+}}:_(<2 x s32>) = G_FCEIL %{{[0-9]+}}
2204 %y = call <2 x float> @llvm.ceil.v2f32(<2 x float> %x)
2208 declare <4 x float> @llvm.ceil.v4f32(<4 x float>)
2209 define <4 x float> @test_ceil_v4f32(<4 x float> %x) {
2210 ; CHECK-LABEL: name: test_ceil_v4f32
2211 ; CHECK: %{{[0-9]+}}:_(<4 x s32>) = G_FCEIL %{{[0-9]+}}
2212 ; SELECT: %{{[0-9]+}}:fpr128 = FRINTPv4f32 %{{[0-9]+}}
2213 %y = call <4 x float> @llvm.ceil.v4f32(<4 x float> %x)
2217 declare <2 x double> @llvm.ceil.v2f64(<2 x double>)
2218 define <2 x double> @test_ceil_v2f64(<2 x double> %x) {
2219 ; CHECK-LABEL: name: test_ceil_v2f64
2220 ; CHECK: %{{[0-9]+}}:_(<2 x s64>) = G_FCEIL %{{[0-9]+}}
2221 %y = call <2 x double> @llvm.ceil.v2f64(<2 x double> %x)
2225 declare float @llvm.cos.f32(float)
2226 define float @test_cos_f32(float %x) {
2227 ; CHECK-LABEL: name: test_cos_f32
2228 ; CHECK: %{{[0-9]+}}:_(s32) = G_FCOS %{{[0-9]+}}
2229 %y = call float @llvm.cos.f32(float %x)
2233 declare float @llvm.sin.f32(float)
2234 define float @test_sin_f32(float %x) {
2235 ; CHECK-LABEL: name: test_sin_f32
2236 ; CHECK: %{{[0-9]+}}:_(s32) = G_FSIN %{{[0-9]+}}
2237 %y = call float @llvm.sin.f32(float %x)
2241 declare float @llvm.sqrt.f32(float)
2242 define float @test_sqrt_f32(float %x) {
2243 ; CHECK-LABEL: name: test_sqrt_f32
2244 ; CHECK: %{{[0-9]+}}:_(s32) = G_FSQRT %{{[0-9]+}}
2245 %y = call float @llvm.sqrt.f32(float %x)
2249 declare float @llvm.floor.f32(float)
2250 define float @test_floor_f32(float %x) {
2251 ; CHECK-LABEL: name: test_floor_f32
2252 ; CHECK: %{{[0-9]+}}:_(s32) = G_FFLOOR %{{[0-9]+}}
2253 %y = call float @llvm.floor.f32(float %x)
2257 declare float @llvm.nearbyint.f32(float)
2258 define float @test_nearbyint_f32(float %x) {
2259 ; CHECK-LABEL: name: test_nearbyint_f32
2260 ; CHECK: %{{[0-9]+}}:_(s32) = G_FNEARBYINT %{{[0-9]+}}
2261 %y = call float @llvm.nearbyint.f32(float %x)
2265 ; CHECK-LABEL: name: test_llvm.aarch64.neon.ld3.v4i32.p0i32
2266 ; CHECK: %1:_(<4 x s32>), %2:_(<4 x s32>), %3:_(<4 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld3), %0(p0) :: (load 48 from %ir.ptr, align 64)
2267 define void @test_llvm.aarch64.neon.ld3.v4i32.p0i32(i32* %ptr) {
2268 %arst = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i32(i32* %ptr)
2272 declare { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i32(i32*) #3
2274 define void @test_i1_arg_zext(void (i1)* %f) {
2275 ; CHECK-LABEL: name: test_i1_arg_zext
2276 ; CHECK: [[I1:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
2277 ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[I1]](s1)
2278 ; CHECK: $w0 = COPY [[ZEXT]](s32)
2279 call void %f(i1 true)
2283 declare i8* @llvm.stacksave()
2284 declare void @llvm.stackrestore(i8*)
2285 define void @test_stacksaverestore() {
2286 ; CHECK-LABEL: name: test_stacksaverestore
2287 ; CHECK: [[SAVE:%[0-9]+]]:_(p0) = COPY $sp
2288 ; CHECK-NEXT: $sp = COPY [[SAVE]](p0)
2289 ; CHECK-NEXT: RET_ReallyLR
2290 %sp = call i8* @llvm.stacksave()
2291 call void @llvm.stackrestore(i8* %sp)
2295 declare float @llvm.rint.f32(float)
2296 define float @test_rint_f32(float %x) {
2297 ; CHECK-LABEL: name: test_rint_f32
2298 ; CHECK: %{{[0-9]+}}:_(s32) = G_FRINT %{{[0-9]+}}
2299 %y = call float @llvm.rint.f32(float %x)
2303 declare void @llvm.assume(i1)
2304 define void @test_assume(i1 %x) {
2305 ; CHECK-LABEL: name: test_assume
2306 ; CHECK-NOT: llvm.assume
2307 ; CHECK: RET_ReallyLR
2308 call void @llvm.assume(i1 %x)
2312 declare void @llvm.sideeffect()
2313 define void @test_sideeffect() {
2314 ; CHECK-LABEL: name: test_sideeffect
2315 ; CHECK-NOT: llvm.sideeffect
2316 ; CHECK: RET_ReallyLR
2317 call void @llvm.sideeffect()
2321 declare void @llvm.var.annotation(i8*, i8*, i8*, i32)
2322 define void @test_var_annotation(i8*, i8*, i8*, i32) {
2323 ; CHECK-LABEL: name: test_var_annotation
2324 ; CHECK-NOT: llvm.var.annotation
2325 ; CHECK: RET_ReallyLR
2326 call void @llvm.var.annotation(i8* %0, i8* %1, i8* %2, i32 %3)
2330 !0 = !{ i64 0, i64 2 }