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: 0, 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: 0, 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: 0, 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
133 ; This gets lowered to a very straightforward sequence of comparisons for now.
134 ; CHECK-LABEL: name: switch
137 ; CHECK: bb.{{[a-zA-Z0-9.]+}}:
138 ; CHECK-NEXT: successors: %[[BB_CASE100:bb.[0-9]+]](0x40000000), %[[BB_NOTCASE100_CHECKNEXT:bb.[0-9]+]](0x40000000)
139 ; CHECK: %0:_(s32) = COPY $w0
140 ; CHECK: %[[reg100:[0-9]+]]:_(s32) = G_CONSTANT i32 100
141 ; CHECK: %[[reg200:[0-9]+]]:_(s32) = G_CONSTANT i32 200
142 ; CHECK: %[[reg2:[0-9]+]]:_(s32) = G_CONSTANT i32 2
143 ; CHECK: %[[reg1:[0-9]+]]:_(s32) = G_CONSTANT i32 1
144 ; CHECK: %[[reg0:[0-9]+]]:_(s32) = G_CONSTANT i32 0
145 ; CHECK: %[[regicmp100:[0-9]+]]:_(s1) = G_ICMP intpred(eq), %[[reg100]](s32), %0
146 ; CHECK: G_BRCOND %[[regicmp100]](s1), %[[BB_CASE100]]
147 ; CHECK: G_BR %[[BB_NOTCASE100_CHECKNEXT]]
149 ; CHECK: [[BB_NOTCASE100_CHECKNEXT]].{{[a-zA-Z0-9.]+}}:
150 ; CHECK-NEXT: successors: %[[BB_CASE200:bb.[0-9]+]](0x40000000), %[[BB_NOTCASE200_CHECKNEXT:bb.[0-9]+]](0x40000000)
151 ; CHECK: %[[regicmp200:[0-9]+]]:_(s1) = G_ICMP intpred(eq), %[[reg200]](s32), %0
152 ; CHECK: G_BRCOND %[[regicmp200]](s1), %[[BB_CASE200]]
153 ; CHECK: G_BR %[[BB_NOTCASE200_CHECKNEXT]]
155 ; CHECK: [[BB_NOTCASE200_CHECKNEXT]].{{[a-zA-Z0-9.]+}}:
156 ; CHECK-NEXT: successors: %[[BB_DEFAULT:bb.[0-9]+]](0x80000000)
157 ; CHECK: G_BR %[[BB_DEFAULT]]
159 ; CHECK: [[BB_DEFAULT]].{{[a-zA-Z0-9.]+}}:
160 ; CHECK-NEXT: successors: %[[BB_RET:bb.[0-9]+]](0x80000000)
161 ; CHECK: %[[regretdefault:[0-9]+]]:_(s32) = G_ADD %0, %[[reg0]]
162 ; CHECK: G_BR %[[BB_RET]]
164 ; CHECK: [[BB_CASE100]].{{[a-zA-Z0-9.]+}}:
165 ; CHECK-NEXT: successors: %[[BB_RET:bb.[0-9]+]](0x80000000)
166 ; CHECK: %[[regretc100:[0-9]+]]:_(s32) = G_ADD %0, %[[reg1]]
167 ; CHECK: G_BR %[[BB_RET]]
169 ; CHECK: [[BB_CASE200]].{{[a-zA-Z0-9.]+}}:
170 ; CHECK-NEXT: successors: %[[BB_RET]](0x80000000)
171 ; CHECK: %[[regretc200:[0-9]+]]:_(s32) = G_ADD %0, %[[reg2]]
173 ; CHECK: [[BB_RET]].{{[a-zA-Z0-9.]+}}:
174 ; CHECK-NEXT: %[[regret:[0-9]+]]:_(s32) = G_PHI %[[regretdefault]](s32), %[[BB_DEFAULT]], %[[regretc100]](s32), %[[BB_CASE100]]
175 ; CHECK: $w0 = COPY %[[regret]](s32)
176 ; CHECK: RET_ReallyLR implicit $w0
178 define i32 @switch(i32 %argc) {
180 switch i32 %argc, label %default [
181 i32 100, label %case100
182 i32 200, label %case200
186 %tmp0 = add i32 %argc, 0
190 %tmp1 = add i32 %argc, 1
194 %tmp2 = add i32 %argc, 2
198 %res = phi i32 [ %tmp0, %default ], [ %tmp1, %case100 ], [ %tmp2, %case200 ]
202 ; The switch lowering code changes the CFG, which means that the original
203 ; %entry block is no longer a predecessor for the phi instruction. We need to
204 ; use the correct lowered MachineBasicBlock instead.
205 ; CHECK-LABEL: name: test_cfg_remap
206 ; CHECK: bb.{{[0-9]+.[a-zA-Z0-9.]+}}:
207 ; CHECK-NEXT: successors: %{{bb.[0-9]+}}(0x40000000), %[[NOTCASE1_BLOCK:bb.[0-9]+]](0x40000000)
208 ; CHECK: [[NOTCASE1_BLOCK]].{{[a-zA-Z0-9.]+}}:
209 ; CHECK-NEXT: successors: %{{bb.[0-9]+}}(0x40000000), %[[NOTCASE57_BLOCK:bb.[0-9]+]](0x40000000)
210 ; CHECK: [[NOTCASE57_BLOCK]].{{[a-zA-Z0-9.]+}}:
211 ; CHECK-NEXT: successors: %[[PHI_BLOCK:bb.[0-9]+]](0x80000000)
212 ; CHECK: G_BR %[[PHI_BLOCK]]
214 ; CHECK: [[PHI_BLOCK]].{{[a-zA-Z0-9.]+}}:
215 ; CHECK-NEXT: G_PHI %{{.*}}(s32), %[[NOTCASE57_BLOCK:bb.[0-9]+]], %{{.*}}(s32),
217 define i32 @test_cfg_remap(i32 %in) {
219 switch i32 %in, label %phi.block [i32 1, label %next
220 i32 57, label %other]
229 %res = phi i32 [1, %entry], [42, %next]
233 ; CHECK-LABEL: name: test_cfg_remap_multiple_preds
234 ; CHECK: G_PHI [[ENTRY:%.*]](s32), %bb.{{[0-9]+}}, [[ENTRY]](s32), %bb.{{[0-9]+}}
235 define i32 @test_cfg_remap_multiple_preds(i32 %in) {
237 switch i32 %in, label %odd [i32 1, label %next
239 i32 128, label %phi.block
240 i32 256, label %phi.block]
251 %res = phi i32 [1, %entry], [1, %entry], [42, %next]
255 ; Tests for indirect br.
256 ; CHECK-LABEL: name: indirectbr
259 ; ABI/constant lowering and IR-level entry basic block.
260 ; CHECK: bb.{{[0-9]+.[a-zA-Z0-9.]+}}:
261 ; Make sure we have one successor
262 ; CHECK-NEXT: successors: %[[BB_L1:bb.[0-9]+]](0x80000000)
265 ; Check basic block L1 has 2 successors: BBL1 and BBL2
266 ; CHECK: [[BB_L1]].{{[a-zA-Z0-9.]+}} (address-taken):
267 ; CHECK-NEXT: successors: %[[BB_L1]](0x40000000),
268 ; CHECK: %[[BB_L2:bb.[0-9]+]](0x40000000)
269 ; CHECK: G_BRINDIRECT %{{[0-9]+}}(p0)
271 ; Check basic block L2 is the return basic block
272 ; CHECK: [[BB_L2]].{{[a-zA-Z0-9.]+}} (address-taken):
273 ; CHECK-NEXT: RET_ReallyLR
275 @indirectbr.L = internal unnamed_addr constant [3 x i8*] [i8* blockaddress(@indirectbr, %L1), i8* blockaddress(@indirectbr, %L2), i8* null], align 8
277 define void @indirectbr() {
280 L1: ; preds = %entry, %L1
281 %i = phi i32 [ 0, %entry ], [ %inc, %L1 ]
283 %idxprom = zext i32 %i to i64
284 %arrayidx = getelementptr inbounds [3 x i8*], [3 x i8*]* @indirectbr.L, i64 0, i64 %idxprom
285 %brtarget = load i8*, i8** %arrayidx, align 8
286 indirectbr i8* %brtarget, [label %L1, label %L2]
292 ; CHECK-LABEL: name: ori64
293 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
294 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
295 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_OR [[ARG1]], [[ARG2]]
296 ; CHECK-NEXT: $x0 = COPY [[RES]]
297 ; CHECK-NEXT: RET_ReallyLR implicit $x0
298 define i64 @ori64(i64 %arg1, i64 %arg2) {
299 %res = or i64 %arg1, %arg2
303 ; CHECK-LABEL: name: ori32
304 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
305 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
306 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_OR [[ARG1]], [[ARG2]]
307 ; CHECK-NEXT: $w0 = COPY [[RES]]
308 ; CHECK-NEXT: RET_ReallyLR implicit $w0
309 define i32 @ori32(i32 %arg1, i32 %arg2) {
310 %res = or i32 %arg1, %arg2
315 ; CHECK-LABEL: name: xori64
316 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
317 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
318 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_XOR [[ARG1]], [[ARG2]]
319 ; CHECK-NEXT: $x0 = COPY [[RES]]
320 ; CHECK-NEXT: RET_ReallyLR implicit $x0
321 define i64 @xori64(i64 %arg1, i64 %arg2) {
322 %res = xor i64 %arg1, %arg2
326 ; CHECK-LABEL: name: xori32
327 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
328 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
329 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_XOR [[ARG1]], [[ARG2]]
330 ; CHECK-NEXT: $w0 = COPY [[RES]]
331 ; CHECK-NEXT: RET_ReallyLR implicit $w0
332 define i32 @xori32(i32 %arg1, i32 %arg2) {
333 %res = xor i32 %arg1, %arg2
338 ; CHECK-LABEL: name: andi64
339 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
340 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
341 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_AND [[ARG1]], [[ARG2]]
342 ; CHECK-NEXT: $x0 = COPY [[RES]]
343 ; CHECK-NEXT: RET_ReallyLR implicit $x0
344 define i64 @andi64(i64 %arg1, i64 %arg2) {
345 %res = and i64 %arg1, %arg2
349 ; CHECK-LABEL: name: andi32
350 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
351 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
352 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_AND [[ARG1]], [[ARG2]]
353 ; CHECK-NEXT: $w0 = COPY [[RES]]
354 ; CHECK-NEXT: RET_ReallyLR implicit $w0
355 define i32 @andi32(i32 %arg1, i32 %arg2) {
356 %res = and i32 %arg1, %arg2
361 ; CHECK-LABEL: name: subi64
362 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
363 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
364 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_SUB [[ARG1]], [[ARG2]]
365 ; CHECK-NEXT: $x0 = COPY [[RES]]
366 ; CHECK-NEXT: RET_ReallyLR implicit $x0
367 define i64 @subi64(i64 %arg1, i64 %arg2) {
368 %res = sub i64 %arg1, %arg2
372 ; CHECK-LABEL: name: subi32
373 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
374 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
375 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SUB [[ARG1]], [[ARG2]]
376 ; CHECK-NEXT: $w0 = COPY [[RES]]
377 ; CHECK-NEXT: RET_ReallyLR implicit $w0
378 define i32 @subi32(i32 %arg1, i32 %arg2) {
379 %res = sub i32 %arg1, %arg2
383 ; CHECK-LABEL: name: ptrtoint
384 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
385 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_PTRTOINT [[ARG1]]
386 ; CHECK: $x0 = COPY [[RES]]
387 ; CHECK: RET_ReallyLR implicit $x0
388 define i64 @ptrtoint(i64* %a) {
389 %val = ptrtoint i64* %a to i64
393 ; CHECK-LABEL: name: inttoptr
394 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
395 ; CHECK: [[RES:%[0-9]+]]:_(p0) = G_INTTOPTR [[ARG1]]
396 ; CHECK: $x0 = COPY [[RES]]
397 ; CHECK: RET_ReallyLR implicit $x0
398 define i64* @inttoptr(i64 %a) {
399 %val = inttoptr i64 %a to i64*
403 ; CHECK-LABEL: name: trivial_bitcast
404 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
405 ; CHECK: $x0 = COPY [[ARG1]]
406 ; CHECK: RET_ReallyLR implicit $x0
407 define i64* @trivial_bitcast(i8* %a) {
408 %val = bitcast i8* %a to i64*
412 ; CHECK-LABEL: name: trivial_bitcast_with_copy
413 ; CHECK: [[A:%[0-9]+]]:_(p0) = COPY $x0
414 ; CHECK: G_BR %[[CAST:bb\.[0-9]+]]
416 ; CHECK: [[END:bb\.[0-9]+]].{{[a-zA-Z0-9.]+}}:
417 ; CHECK: $x0 = COPY [[A]]
419 ; CHECK: [[CAST]].{{[a-zA-Z0-9.]+}}:
420 ; CHECK: G_BR %[[END]]
421 define i64* @trivial_bitcast_with_copy(i8* %a) {
428 %val = bitcast i8* %a to i64*
432 ; CHECK-LABEL: name: bitcast
433 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
434 ; CHECK: [[RES1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[ARG1]]
435 ; CHECK: [[RES2:%[0-9]+]]:_(s64) = G_BITCAST [[RES1]]
436 ; CHECK: $x0 = COPY [[RES2]]
437 ; CHECK: RET_ReallyLR implicit $x0
438 define i64 @bitcast(i64 %a) {
439 %res1 = bitcast i64 %a to <2 x i32>
440 %res2 = bitcast <2 x i32> %res1 to i64
444 ; CHECK-LABEL: name: addrspacecast
445 ; CHECK: [[ARG1:%[0-9]+]]:_(p1) = COPY $x0
446 ; CHECK: [[RES1:%[0-9]+]]:_(p2) = G_ADDRSPACE_CAST [[ARG1]]
447 ; CHECK: [[RES2:%[0-9]+]]:_(p0) = G_ADDRSPACE_CAST [[RES1]]
448 ; CHECK: $x0 = COPY [[RES2]]
449 ; CHECK: RET_ReallyLR implicit $x0
450 define i64* @addrspacecast(i32 addrspace(1)* %a) {
451 %res1 = addrspacecast i32 addrspace(1)* %a to i64 addrspace(2)*
452 %res2 = addrspacecast i64 addrspace(2)* %res1 to i64*
456 ; CHECK-LABEL: name: trunc
457 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
458 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_LOAD
459 ; CHECK: [[RES1:%[0-9]+]]:_(s8) = G_TRUNC [[ARG1]]
460 ; CHECK: [[RES2:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[VEC]]
461 define void @trunc(i64 %a) {
462 %vecptr = alloca <4 x i32>
463 %vec = load <4 x i32>, <4 x i32>* %vecptr
464 %res1 = trunc i64 %a to i8
465 %res2 = trunc <4 x i32> %vec to <4 x i16>
469 ; CHECK-LABEL: name: load
470 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
471 ; CHECK: [[ADDR42:%[0-9]+]]:_(p42) = COPY $x1
472 ; CHECK: [[VAL1:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (load 8 from %ir.addr, align 16)
473 ; CHECK: [[VAL2:%[0-9]+]]:_(s64) = G_LOAD [[ADDR42]](p42) :: (load 8 from %ir.addr42, addrspace 42)
474 ; CHECK: [[SUM2:%.*]]:_(s64) = G_ADD [[VAL1]], [[VAL2]]
475 ; CHECK: [[VAL3:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (volatile load 8 from %ir.addr)
476 ; CHECK: [[SUM3:%[0-9]+]]:_(s64) = G_ADD [[SUM2]], [[VAL3]]
477 ; CHECK: $x0 = COPY [[SUM3]]
478 ; CHECK: RET_ReallyLR implicit $x0
479 define i64 @load(i64* %addr, i64 addrspace(42)* %addr42) {
480 %val1 = load i64, i64* %addr, align 16
482 %val2 = load i64, i64 addrspace(42)* %addr42
483 %sum2 = add i64 %val1, %val2
485 %val3 = load volatile i64, i64* %addr
486 %sum3 = add i64 %sum2, %val3
490 ; CHECK-LABEL: name: store
491 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
492 ; CHECK: [[ADDR42:%[0-9]+]]:_(p42) = COPY $x1
493 ; CHECK: [[VAL1:%[0-9]+]]:_(s64) = COPY $x2
494 ; CHECK: [[VAL2:%[0-9]+]]:_(s64) = COPY $x3
495 ; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (store 8 into %ir.addr, align 16)
496 ; CHECK: G_STORE [[VAL2]](s64), [[ADDR42]](p42) :: (store 8 into %ir.addr42, addrspace 42)
497 ; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (volatile store 8 into %ir.addr)
498 ; CHECK: RET_ReallyLR
499 define void @store(i64* %addr, i64 addrspace(42)* %addr42, i64 %val1, i64 %val2) {
500 store i64 %val1, i64* %addr, align 16
501 store i64 %val2, i64 addrspace(42)* %addr42
502 store volatile i64 %val1, i64* %addr
503 %sum = add i64 %val1, %val2
507 ; CHECK-LABEL: name: intrinsics
508 ; CHECK: [[CUR:%[0-9]+]]:_(s32) = COPY $w0
509 ; CHECK: [[BITS:%[0-9]+]]:_(s32) = COPY $w1
510 ; CHECK: [[CREG:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
511 ; CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTRINSIC intrinsic(@llvm.returnaddress), [[CREG]]
512 ; CHECK: [[PTR_VEC:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.ptr.vec
513 ; CHECK: [[VEC:%[0-9]+]]:_(<8 x s8>) = G_LOAD [[PTR_VEC]]
514 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), [[VEC]](<8 x s8>), [[VEC]](<8 x s8>), [[PTR]](p0)
515 ; CHECK: RET_ReallyLR
516 declare i8* @llvm.returnaddress(i32)
517 declare void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8>, <8 x i8>, i8*)
518 declare { <8 x i8>, <8 x i8> } @llvm.aarch64.neon.ld2.v8i8.p0v8i8(<8 x i8>*)
519 define void @intrinsics(i32 %cur, i32 %bits) {
520 %ptr = call i8* @llvm.returnaddress(i32 0)
521 %ptr.vec = alloca <8 x i8>
522 %vec = load <8 x i8>, <8 x i8>* %ptr.vec
523 call void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8> %vec, <8 x i8> %vec, i8* %ptr)
527 ; CHECK-LABEL: name: test_phi
528 ; CHECK: G_BRCOND {{%.*}}, %[[TRUE:bb\.[0-9]+]]
529 ; CHECK: G_BR %[[FALSE:bb\.[0-9]+]]
531 ; CHECK: [[TRUE]].{{[a-zA-Z0-9.]+}}:
532 ; CHECK: [[RES1:%[0-9]+]]:_(s32) = G_LOAD
534 ; CHECK: [[FALSE]].{{[a-zA-Z0-9.]+}}:
535 ; CHECK: [[RES2:%[0-9]+]]:_(s32) = G_LOAD
537 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_PHI [[RES1]](s32), %[[TRUE]], [[RES2]](s32), %[[FALSE]]
538 ; CHECK: $w0 = COPY [[RES]]
539 define i32 @test_phi(i32* %addr1, i32* %addr2, i1 %tst) {
540 br i1 %tst, label %true, label %false
543 %res1 = load i32, i32* %addr1
547 %res2 = load i32, i32* %addr2
551 %res = phi i32 [%res1, %true], [%res2, %false]
555 ; CHECK-LABEL: name: unreachable
559 define void @unreachable(i32 %a) {
560 %sum = add i32 %a, %a
564 ; It's important that constants are after argument passing, but before the
565 ; rest of the entry block.
566 ; CHECK-LABEL: name: constant_int
567 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
568 ; CHECK: [[ONE:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
570 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
571 ; CHECK: [[SUM1:%[0-9]+]]:_(s32) = G_ADD [[IN]], [[ONE]]
572 ; CHECK: [[SUM2:%[0-9]+]]:_(s32) = G_ADD [[IN]], [[ONE]]
573 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_ADD [[SUM1]], [[SUM2]]
574 ; CHECK: $w0 = COPY [[RES]]
576 define i32 @constant_int(i32 %in) {
580 %sum1 = add i32 %in, 1
581 %sum2 = add i32 %in, 1
582 %res = add i32 %sum1, %sum2
586 ; CHECK-LABEL: name: constant_int_start
587 ; CHECK: [[TWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
588 ; CHECK: [[ANSWER:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
589 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_ADD [[TWO]], [[ANSWER]]
590 define i32 @constant_int_start() {
595 ; CHECK-LABEL: name: test_undef
596 ; CHECK: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
597 ; CHECK: $w0 = COPY [[UNDEF]]
598 define i32 @test_undef() {
602 ; CHECK-LABEL: name: test_constant_inttoptr
603 ; CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
604 ; CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[ONE]]
605 ; CHECK: $x0 = COPY [[PTR]]
606 define i8* @test_constant_inttoptr() {
607 ret i8* inttoptr(i64 1 to i8*)
610 ; This failed purely because the Constant -> VReg map was kept across
611 ; functions, so reuse the "i64 1" from above.
612 ; CHECK-LABEL: name: test_reused_constant
613 ; CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
614 ; CHECK: $x0 = COPY [[ONE]]
615 define i64 @test_reused_constant() {
619 ; CHECK-LABEL: name: test_sext
620 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
621 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_SEXT [[IN]]
622 ; CHECK: $x0 = COPY [[RES]]
623 define i64 @test_sext(i32 %in) {
624 %res = sext i32 %in to i64
628 ; CHECK-LABEL: name: test_zext
629 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
630 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_ZEXT [[IN]]
631 ; CHECK: $x0 = COPY [[RES]]
632 define i64 @test_zext(i32 %in) {
633 %res = zext i32 %in to i64
637 ; CHECK-LABEL: name: test_shl
638 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
639 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
640 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SHL [[ARG1]], [[ARG2]]
641 ; CHECK-NEXT: $w0 = COPY [[RES]]
642 ; CHECK-NEXT: RET_ReallyLR implicit $w0
643 define i32 @test_shl(i32 %arg1, i32 %arg2) {
644 %res = shl i32 %arg1, %arg2
649 ; CHECK-LABEL: name: test_lshr
650 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
651 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
652 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_LSHR [[ARG1]], [[ARG2]]
653 ; CHECK-NEXT: $w0 = COPY [[RES]]
654 ; CHECK-NEXT: RET_ReallyLR implicit $w0
655 define i32 @test_lshr(i32 %arg1, i32 %arg2) {
656 %res = lshr i32 %arg1, %arg2
660 ; CHECK-LABEL: name: test_ashr
661 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
662 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
663 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_ASHR [[ARG1]], [[ARG2]]
664 ; CHECK-NEXT: $w0 = COPY [[RES]]
665 ; CHECK-NEXT: RET_ReallyLR implicit $w0
666 define i32 @test_ashr(i32 %arg1, i32 %arg2) {
667 %res = ashr i32 %arg1, %arg2
671 ; CHECK-LABEL: name: test_sdiv
672 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
673 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
674 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SDIV [[ARG1]], [[ARG2]]
675 ; CHECK-NEXT: $w0 = COPY [[RES]]
676 ; CHECK-NEXT: RET_ReallyLR implicit $w0
677 define i32 @test_sdiv(i32 %arg1, i32 %arg2) {
678 %res = sdiv i32 %arg1, %arg2
682 ; CHECK-LABEL: name: test_udiv
683 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
684 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
685 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_UDIV [[ARG1]], [[ARG2]]
686 ; CHECK-NEXT: $w0 = COPY [[RES]]
687 ; CHECK-NEXT: RET_ReallyLR implicit $w0
688 define i32 @test_udiv(i32 %arg1, i32 %arg2) {
689 %res = udiv i32 %arg1, %arg2
693 ; CHECK-LABEL: name: test_srem
694 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
695 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
696 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SREM [[ARG1]], [[ARG2]]
697 ; CHECK-NEXT: $w0 = COPY [[RES]]
698 ; CHECK-NEXT: RET_ReallyLR implicit $w0
699 define i32 @test_srem(i32 %arg1, i32 %arg2) {
700 %res = srem i32 %arg1, %arg2
704 ; CHECK-LABEL: name: test_urem
705 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
706 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
707 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_UREM [[ARG1]], [[ARG2]]
708 ; CHECK-NEXT: $w0 = COPY [[RES]]
709 ; CHECK-NEXT: RET_ReallyLR implicit $w0
710 define i32 @test_urem(i32 %arg1, i32 %arg2) {
711 %res = urem i32 %arg1, %arg2
715 ; CHECK-LABEL: name: test_constant_null
716 ; CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
717 ; CHECK: [[NULL:%[0-9]+]]:_(p0) = G_INTTOPTR [[ZERO]]
718 ; CHECK: $x0 = COPY [[NULL]]
719 define i8* @test_constant_null() {
723 ; CHECK-LABEL: name: test_struct_memops
724 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
725 ; CHECK: [[VAL1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
726 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
727 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST1]](s64)
728 ; CHECK: [[VAL2:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load 4 from %ir.addr + 4)
729 ; CHECK: G_STORE [[VAL1]](s8), [[ADDR]](p0) :: (store 1 into %ir.addr, align 4)
730 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
731 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST2]](s64)
732 ; CHECK: G_STORE [[VAL2]](s32), [[GEP2]](p0) :: (store 4 into %ir.addr + 4)
733 define void @test_struct_memops({ i8, i32 }* %addr) {
734 %val = load { i8, i32 }, { i8, i32 }* %addr
735 store { i8, i32 } %val, { i8, i32 }* %addr
739 ; CHECK-LABEL: name: test_i1_memops
740 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
741 ; CHECK: [[VAL:%[0-9]+]]:_(s1) = G_LOAD [[ADDR]](p0) :: (load 1 from %ir.addr)
742 ; CHECK: G_STORE [[VAL]](s1), [[ADDR]](p0) :: (store 1 into %ir.addr)
743 define void @test_i1_memops(i1* %addr) {
744 %val = load i1, i1* %addr
745 store i1 %val, i1* %addr
749 ; CHECK-LABEL: name: int_comparison
750 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
751 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
752 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
753 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[LHS]](s32), [[RHS]]
754 ; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0)
755 define void @int_comparison(i32 %a, i32 %b, i1* %addr) {
756 %res = icmp ne i32 %a, %b
757 store i1 %res, i1* %addr
761 ; CHECK-LABEL: name: ptr_comparison
762 ; CHECK: [[LHS:%[0-9]+]]:_(p0) = COPY $x0
763 ; CHECK: [[RHS:%[0-9]+]]:_(p0) = COPY $x1
764 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
765 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[LHS]](p0), [[RHS]]
766 ; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0)
767 define void @ptr_comparison(i8* %a, i8* %b, i1* %addr) {
768 %res = icmp eq i8* %a, %b
769 store i1 %res, i1* %addr
773 ; CHECK-LABEL: name: test_fadd
774 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
775 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
776 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FADD [[ARG1]], [[ARG2]]
777 ; CHECK-NEXT: $s0 = COPY [[RES]]
778 ; CHECK-NEXT: RET_ReallyLR implicit $s0
779 define float @test_fadd(float %arg1, float %arg2) {
780 %res = fadd float %arg1, %arg2
784 ; CHECK-LABEL: name: test_fsub
785 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
786 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
787 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FSUB [[ARG1]], [[ARG2]]
788 ; CHECK-NEXT: $s0 = COPY [[RES]]
789 ; CHECK-NEXT: RET_ReallyLR implicit $s0
790 define float @test_fsub(float %arg1, float %arg2) {
791 %res = fsub float %arg1, %arg2
795 ; CHECK-LABEL: name: test_fmul
796 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
797 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
798 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FMUL [[ARG1]], [[ARG2]]
799 ; CHECK-NEXT: $s0 = COPY [[RES]]
800 ; CHECK-NEXT: RET_ReallyLR implicit $s0
801 define float @test_fmul(float %arg1, float %arg2) {
802 %res = fmul float %arg1, %arg2
806 ; CHECK-LABEL: name: test_fdiv
807 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
808 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
809 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FDIV [[ARG1]], [[ARG2]]
810 ; CHECK-NEXT: $s0 = COPY [[RES]]
811 ; CHECK-NEXT: RET_ReallyLR implicit $s0
812 define float @test_fdiv(float %arg1, float %arg2) {
813 %res = fdiv float %arg1, %arg2
817 ; CHECK-LABEL: name: test_frem
818 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
819 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
820 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FREM [[ARG1]], [[ARG2]]
821 ; CHECK-NEXT: $s0 = COPY [[RES]]
822 ; CHECK-NEXT: RET_ReallyLR implicit $s0
823 define float @test_frem(float %arg1, float %arg2) {
824 %res = frem float %arg1, %arg2
828 ; CHECK-LABEL: name: test_fneg
829 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
830 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FNEG [[ARG1]]
831 ; CHECK-NEXT: $s0 = COPY [[RES]]
832 ; CHECK-NEXT: RET_ReallyLR implicit $s0
833 define float @test_fneg(float %arg1) {
834 %res = fneg float %arg1
838 ; CHECK-LABEL: name: test_sadd_overflow
839 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
840 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
841 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
842 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SADDO [[LHS]], [[RHS]]
843 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
844 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
845 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
846 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
847 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
848 define void @test_sadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
849 %res = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %lhs, i32 %rhs)
850 store { i32, i1 } %res, { i32, i1 }* %addr
854 ; CHECK-LABEL: name: test_uadd_overflow
855 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
856 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
857 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
858 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_UADDO [[LHS]], [[RHS]]
859 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
860 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
861 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
862 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
863 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
864 define void @test_uadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
865 %res = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %lhs, i32 %rhs)
866 store { i32, i1 } %res, { i32, i1 }* %addr
870 ; CHECK-LABEL: name: test_ssub_overflow
871 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
872 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
873 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
874 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SSUBO [[LHS]], [[RHS]]
875 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.subr)
876 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
877 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
878 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.subr + 4, align 4)
879 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
880 define void @test_ssub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) {
881 %res = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %lhs, i32 %rhs)
882 store { i32, i1 } %res, { i32, i1 }* %subr
886 ; CHECK-LABEL: name: test_usub_overflow
887 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
888 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
889 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
890 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_USUBO [[LHS]], [[RHS]]
891 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.subr)
892 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
893 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
894 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.subr + 4, align 4)
895 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
896 define void @test_usub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) {
897 %res = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %lhs, i32 %rhs)
898 store { i32, i1 } %res, { i32, i1 }* %subr
902 ; CHECK-LABEL: name: test_smul_overflow
903 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
904 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
905 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
906 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SMULO [[LHS]], [[RHS]]
907 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
908 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
909 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
910 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
911 declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)
912 define void @test_smul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
913 %res = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %lhs, i32 %rhs)
914 store { i32, i1 } %res, { i32, i1 }* %addr
918 ; CHECK-LABEL: name: test_umul_overflow
919 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
920 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
921 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
922 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_UMULO [[LHS]], [[RHS]]
923 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
924 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
925 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
926 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
927 declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
928 define void @test_umul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
929 %res = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %lhs, i32 %rhs)
930 store { i32, i1 } %res, { i32, i1 }* %addr
934 ; CHECK-LABEL: name: test_extractvalue
935 ; CHECK: %0:_(p0) = COPY $x0
936 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
937 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
938 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
939 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4)
940 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
941 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
942 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8)
943 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
944 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
945 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12)
946 ; CHECK: $w0 = COPY [[LD3]](s32)
947 %struct.nested = type {i8, { i8, i32 }, i32}
948 define i32 @test_extractvalue(%struct.nested* %addr) {
949 %struct = load %struct.nested, %struct.nested* %addr
950 %res = extractvalue %struct.nested %struct, 1, 1
954 ; CHECK-LABEL: name: test_extractvalue_agg
955 ; CHECK: %0:_(p0) = COPY $x0
956 ; CHECK: %1:_(p0) = COPY $x1
957 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
958 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
959 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
960 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4)
961 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
962 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
963 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8)
964 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
965 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
966 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12)
967 ; CHECK: G_STORE [[LD2]](s8), %1(p0) :: (store 1 into %ir.addr2, align 4)
968 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
969 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP %1, [[CST4]](s64)
970 ; CHECK: G_STORE [[LD3]](s32), [[GEP4]](p0) :: (store 4 into %ir.addr2 + 4)
971 define void @test_extractvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
972 %struct = load %struct.nested, %struct.nested* %addr
973 %res = extractvalue %struct.nested %struct, 1
974 store {i8, i32} %res, {i8, i32}* %addr2
978 ; CHECK-LABEL: name: test_insertvalue
979 ; CHECK: %0:_(p0) = COPY $x0
980 ; CHECK: %1:_(s32) = COPY $w1
981 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
982 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
983 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
984 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4)
985 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
986 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
987 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8)
988 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
989 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
990 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12)
991 ; CHECK: G_STORE [[LD1]](s8), %0(p0) :: (store 1 into %ir.addr, align 4)
992 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
993 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP %0, [[CST4]](s64)
994 ; CHECK: G_STORE [[LD2]](s8), [[GEP4]](p0) :: (store 1 into %ir.addr + 4, align 4)
995 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
996 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP %0, [[CST5]](s64)
997 ; CHECK: G_STORE %1(s32), [[GEP5]](p0) :: (store 4 into %ir.addr + 8)
998 ; CHECK: [[CST6:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
999 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP %0, [[CST6]](s64)
1000 ; CHECK: G_STORE [[LD4]](s32), [[GEP6]](p0) :: (store 4 into %ir.addr + 12)
1001 define void @test_insertvalue(%struct.nested* %addr, i32 %val) {
1002 %struct = load %struct.nested, %struct.nested* %addr
1003 %newstruct = insertvalue %struct.nested %struct, i32 %val, 1, 1
1004 store %struct.nested %newstruct, %struct.nested* %addr
1008 define [1 x i64] @test_trivial_insert([1 x i64] %s, i64 %val) {
1009 ; CHECK-LABEL: name: test_trivial_insert
1010 ; CHECK: [[STRUCT:%[0-9]+]]:_(s64) = COPY $x0
1011 ; CHECK: [[VAL:%[0-9]+]]:_(s64) = COPY $x1
1012 ; CHECK: $x0 = COPY [[VAL]]
1013 %res = insertvalue [1 x i64] %s, i64 %val, 0
1017 define [1 x i8*] @test_trivial_insert_ptr([1 x i8*] %s, i8* %val) {
1018 ; CHECK-LABEL: name: test_trivial_insert_ptr
1019 ; CHECK: [[STRUCT:%[0-9]+]]:_(s64) = COPY $x0
1020 ; CHECK: [[VAL:%[0-9]+]]:_(p0) = COPY $x1
1021 ; CHECK: $x0 = COPY [[VAL]]
1022 %res = insertvalue [1 x i8*] %s, i8* %val, 0
1026 ; CHECK-LABEL: name: test_insertvalue_agg
1027 ; CHECK: %0:_(p0) = COPY $x0
1028 ; CHECK: %1:_(p0) = COPY $x1
1029 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %1(p0) :: (load 1 from %ir.addr2, align 4)
1030 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1031 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %1, [[CST1]](s64)
1032 ; CHECK: [[LD2:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load 4 from %ir.addr2 + 4)
1033 ; CHECK: [[LD3:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
1034 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1035 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
1036 ; CHECK: [[LD4:%[0-9]+]]:_(s8) = G_LOAD [[GEP2]](p0) :: (load 1 from %ir.addr + 4, align 4)
1037 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1038 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
1039 ; CHECK: [[LD5:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 8)
1040 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
1041 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP %0, [[CST4]](s64)
1042 ; CHECK: [[LD6:%[0-9]+]]:_(s32) = G_LOAD [[GEP4]](p0) :: (load 4 from %ir.addr + 12)
1043 ; CHECK: G_STORE [[LD3]](s8), %0(p0) :: (store 1 into %ir.addr, align 4)
1044 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1045 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP %0, [[CST5]](s64)
1046 ; CHECK: G_STORE [[LD1]](s8), [[GEP5]](p0) :: (store 1 into %ir.addr + 4, align 4)
1047 ; CHECK: [[CST6:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1048 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP %0, [[CST6]](s64)
1049 ; CHECK: G_STORE [[LD2]](s32), [[GEP6]](p0) :: (store 4 into %ir.addr + 8)
1050 ; CHECK: [[CST7:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
1051 ; CHECK: [[GEP7:%[0-9]+]]:_(p0) = G_GEP %0, [[CST7]](s64)
1052 ; CHECK: G_STORE [[LD6]](s32), [[GEP7]](p0) :: (store 4 into %ir.addr + 12)
1053 define void @test_insertvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
1054 %smallstruct = load {i8, i32}, {i8, i32}* %addr2
1055 %struct = load %struct.nested, %struct.nested* %addr
1056 %res = insertvalue %struct.nested %struct, {i8, i32} %smallstruct, 1
1057 store %struct.nested %res, %struct.nested* %addr
1061 ; CHECK-LABEL: name: test_select
1062 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
1063 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]]
1064 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w1
1065 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w2
1066 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
1067 ; CHECK: $w0 = COPY [[RES]]
1068 define i32 @test_select(i1 %tst, i32 %lhs, i32 %rhs) {
1069 %res = select i1 %tst, i32 %lhs, i32 %rhs
1073 ; CHECK-LABEL: name: test_select_ptr
1074 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
1075 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]]
1076 ; CHECK: [[LHS:%[0-9]+]]:_(p0) = COPY $x1
1077 ; CHECK: [[RHS:%[0-9]+]]:_(p0) = COPY $x2
1078 ; CHECK: [[RES:%[0-9]+]]:_(p0) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
1079 ; CHECK: $x0 = COPY [[RES]]
1080 define i8* @test_select_ptr(i1 %tst, i8* %lhs, i8* %rhs) {
1081 %res = select i1 %tst, i8* %lhs, i8* %rhs
1085 ; CHECK-LABEL: name: test_select_vec
1086 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
1087 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]]
1088 ; CHECK: [[LHS:%[0-9]+]]:_(<4 x s32>) = COPY $q0
1089 ; CHECK: [[RHS:%[0-9]+]]:_(<4 x s32>) = COPY $q1
1090 ; CHECK: [[RES:%[0-9]+]]:_(<4 x s32>) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
1091 ; CHECK: $q0 = COPY [[RES]]
1092 define <4 x i32> @test_select_vec(i1 %tst, <4 x i32> %lhs, <4 x i32> %rhs) {
1093 %res = select i1 %tst, <4 x i32> %lhs, <4 x i32> %rhs
1097 ; CHECK-LABEL: name: test_vselect_vec
1098 ; CHECK: [[TST32:%[0-9]+]]:_(<4 x s32>) = COPY $q0
1099 ; CHECK: [[LHS:%[0-9]+]]:_(<4 x s32>) = COPY $q1
1100 ; CHECK: [[RHS:%[0-9]+]]:_(<4 x s32>) = COPY $q2
1101 ; CHECK: [[TST:%[0-9]+]]:_(<4 x s1>) = G_TRUNC [[TST32]](<4 x s32>)
1102 ; CHECK: [[RES:%[0-9]+]]:_(<4 x s32>) = G_SELECT [[TST]](<4 x s1>), [[LHS]], [[RHS]]
1103 ; CHECK: $q0 = COPY [[RES]]
1104 define <4 x i32> @test_vselect_vec(<4 x i32> %tst32, <4 x i32> %lhs, <4 x i32> %rhs) {
1105 %tst = trunc <4 x i32> %tst32 to <4 x i1>
1106 %res = select <4 x i1> %tst, <4 x i32> %lhs, <4 x i32> %rhs
1110 ; CHECK-LABEL: name: test_fptosi
1111 ; CHECK: [[FPADDR:%[0-9]+]]:_(p0) = COPY $x0
1112 ; CHECK: [[FP:%[0-9]+]]:_(s32) = G_LOAD [[FPADDR]](p0)
1113 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPTOSI [[FP]](s32)
1114 ; CHECK: $x0 = COPY [[RES]]
1115 define i64 @test_fptosi(float* %fp.addr) {
1116 %fp = load float, float* %fp.addr
1117 %res = fptosi float %fp to i64
1121 ; CHECK-LABEL: name: test_fptoui
1122 ; CHECK: [[FPADDR:%[0-9]+]]:_(p0) = COPY $x0
1123 ; CHECK: [[FP:%[0-9]+]]:_(s32) = G_LOAD [[FPADDR]](p0)
1124 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPTOUI [[FP]](s32)
1125 ; CHECK: $x0 = COPY [[RES]]
1126 define i64 @test_fptoui(float* %fp.addr) {
1127 %fp = load float, float* %fp.addr
1128 %res = fptoui float %fp to i64
1132 ; CHECK-LABEL: name: test_sitofp
1133 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1134 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w1
1135 ; CHECK: [[FP:%[0-9]+]]:_(s64) = G_SITOFP [[IN]](s32)
1136 ; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0)
1137 define void @test_sitofp(double* %addr, i32 %in) {
1138 %fp = sitofp i32 %in to double
1139 store double %fp, double* %addr
1143 ; CHECK-LABEL: name: test_uitofp
1144 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1145 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w1
1146 ; CHECK: [[FP:%[0-9]+]]:_(s64) = G_UITOFP [[IN]](s32)
1147 ; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0)
1148 define void @test_uitofp(double* %addr, i32 %in) {
1149 %fp = uitofp i32 %in to double
1150 store double %fp, double* %addr
1154 ; CHECK-LABEL: name: test_fpext
1155 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $s0
1156 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPEXT [[IN]](s32)
1157 ; CHECK: $d0 = COPY [[RES]]
1158 define double @test_fpext(float %in) {
1159 %res = fpext float %in to double
1163 ; CHECK-LABEL: name: test_fptrunc
1164 ; CHECK: [[IN:%[0-9]+]]:_(s64) = COPY $d0
1165 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FPTRUNC [[IN]](s64)
1166 ; CHECK: $s0 = COPY [[RES]]
1167 define float @test_fptrunc(double %in) {
1168 %res = fptrunc double %in to float
1172 ; CHECK-LABEL: name: test_constant_float
1173 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1174 ; CHECK: [[TMP:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.500000e+00
1175 ; CHECK: G_STORE [[TMP]](s32), [[ADDR]](p0)
1176 define void @test_constant_float(float* %addr) {
1177 store float 1.5, float* %addr
1181 ; CHECK-LABEL: name: float_comparison
1182 ; CHECK: [[LHSADDR:%[0-9]+]]:_(p0) = COPY $x0
1183 ; CHECK: [[RHSADDR:%[0-9]+]]:_(p0) = COPY $x1
1184 ; CHECK: [[BOOLADDR:%[0-9]+]]:_(p0) = COPY $x2
1185 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = G_LOAD [[LHSADDR]](p0)
1186 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = G_LOAD [[RHSADDR]](p0)
1187 ; CHECK: [[TST:%[0-9]+]]:_(s1) = nnan ninf nsz arcp contract afn reassoc G_FCMP floatpred(oge), [[LHS]](s32), [[RHS]]
1188 ; CHECK: G_STORE [[TST]](s1), [[BOOLADDR]](p0)
1189 define void @float_comparison(float* %a.addr, float* %b.addr, i1* %bool.addr) {
1190 %a = load float, float* %a.addr
1191 %b = load float, float* %b.addr
1192 %res = fcmp nnan ninf nsz arcp contract afn reassoc oge float %a, %b
1193 store i1 %res, i1* %bool.addr
1197 ; CHECK-LABEL: name: trivial_float_comparison
1198 ; CHECK: [[ENTRY_R1:%[0-9]+]]:_(s1) = G_CONSTANT i1 false
1199 ; CHECK: [[ENTRY_R2:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
1200 ; CHECK: [[R1:%[0-9]+]]:_(s1) = COPY [[ENTRY_R1]](s1)
1201 ; CHECK: [[R2:%[0-9]+]]:_(s1) = COPY [[ENTRY_R2]](s1)
1202 ; CHECK: G_ADD [[R1]], [[R2]]
1203 define i1 @trivial_float_comparison(double %a, double %b) {
1204 %r1 = fcmp false double %a, %b
1205 %r2 = fcmp true double %a, %b
1206 %sum = add i1 %r1, %r2
1212 define i32* @test_global() {
1213 ; CHECK-LABEL: name: test_global
1214 ; CHECK: [[TMP:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @var{{$}}
1215 ; CHECK: $x0 = COPY [[TMP]](p0)
1220 @var1 = addrspace(42) global i32 0
1221 define i32 addrspace(42)* @test_global_addrspace() {
1222 ; CHECK-LABEL: name: test_global
1223 ; CHECK: [[TMP:%[0-9]+]]:_(p42) = G_GLOBAL_VALUE @var1{{$}}
1224 ; CHECK: $x0 = COPY [[TMP]](p42)
1226 ret i32 addrspace(42)* @var1
1230 define void()* @test_global_func() {
1231 ; CHECK-LABEL: name: test_global_func
1232 ; CHECK: [[TMP:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @allocai64{{$}}
1233 ; CHECK: $x0 = COPY [[TMP]](p0)
1235 ret void()* @allocai64
1238 declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
1239 define void @test_memcpy(i8* %dst, i8* %src, i64 %size) {
1240 ; CHECK-LABEL: name: test_memcpy
1241 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1242 ; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1
1243 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1244 ; CHECK: $x0 = COPY [[DST]]
1245 ; CHECK: $x1 = COPY [[SRC]]
1246 ; CHECK: $x2 = COPY [[SIZE]]
1247 ; CHECK: BL &memcpy, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $x1, implicit $x2
1248 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 0)
1252 declare void @llvm.memmove.p0i8.p0i8.i64(i8*, i8*, i64, i1)
1253 define void @test_memmove(i8* %dst, i8* %src, i64 %size) {
1254 ; CHECK-LABEL: name: test_memmove
1255 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1256 ; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1
1257 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1258 ; CHECK: $x0 = COPY [[DST]]
1259 ; CHECK: $x1 = COPY [[SRC]]
1260 ; CHECK: $x2 = COPY [[SIZE]]
1261 ; CHECK: BL &memmove, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $x1, implicit $x2
1262 call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 0)
1266 declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i1)
1267 define void @test_memset(i8* %dst, i8 %val, i64 %size) {
1268 ; CHECK-LABEL: name: test_memset
1269 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1270 ; CHECK: [[SRC_C:%[0-9]+]]:_(s32) = COPY $w1
1271 ; CHECK: [[SRC:%[0-9]+]]:_(s8) = G_TRUNC [[SRC_C]]
1272 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1273 ; CHECK: $x0 = COPY [[DST]]
1274 ; CHECK: [[SRC_TMP:%[0-9]+]]:_(s32) = G_ANYEXT [[SRC]]
1275 ; CHECK: $w1 = COPY [[SRC_TMP]]
1276 ; CHECK: $x2 = COPY [[SIZE]]
1277 ; CHECK: BL &memset, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $w1, implicit $x2
1278 call void @llvm.memset.p0i8.i64(i8* %dst, i8 %val, i64 %size, i1 0)
1282 declare i64 @llvm.objectsize.i64(i8*, i1)
1283 declare i32 @llvm.objectsize.i32(i8*, i1)
1284 define void @test_objectsize(i8* %addr0, i8* %addr1) {
1285 ; CHECK-LABEL: name: test_objectsize
1286 ; CHECK: [[ADDR0:%[0-9]+]]:_(p0) = COPY $x0
1287 ; CHECK: [[ADDR1:%[0-9]+]]:_(p0) = COPY $x1
1288 ; CHECK: {{%[0-9]+}}:_(s64) = G_CONSTANT i64 -1
1289 ; CHECK: {{%[0-9]+}}:_(s64) = G_CONSTANT i64 0
1290 ; CHECK: {{%[0-9]+}}:_(s32) = G_CONSTANT i32 -1
1291 ; CHECK: {{%[0-9]+}}:_(s32) = G_CONSTANT i32 0
1292 %size64.0 = call i64 @llvm.objectsize.i64(i8* %addr0, i1 0)
1293 %size64.intmin = call i64 @llvm.objectsize.i64(i8* %addr0, i1 1)
1294 %size32.0 = call i32 @llvm.objectsize.i32(i8* %addr0, i1 0)
1295 %size32.intmin = call i32 @llvm.objectsize.i32(i8* %addr0, i1 1)
1299 define void @test_large_const(i128* %addr) {
1300 ; CHECK-LABEL: name: test_large_const
1301 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1302 ; CHECK: [[VAL:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
1303 ; CHECK: G_STORE [[VAL]](s128), [[ADDR]](p0)
1304 store i128 42, i128* %addr
1308 ; When there was no formal argument handling (so the first BB was empty) we used
1309 ; to insert the constants at the end of the block, even if they were encountered
1310 ; after the block's terminators had been emitted. Also make sure the order is
1312 define i8* @test_const_placement() {
1313 ; CHECK-LABEL: name: test_const_placement
1314 ; CHECK: bb.{{[0-9]+}} (%ir-block.{{[0-9]+}}):
1315 ; CHECK: [[VAL_INT:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
1316 ; CHECK: [[VAL:%[0-9]+]]:_(p0) = G_INTTOPTR [[VAL_INT]](s32)
1317 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
1321 ret i8* inttoptr(i32 42 to i8*)
1324 declare void @llvm.va_end(i8*)
1325 define void @test_va_end(i8* %list) {
1326 ; CHECK-LABEL: name: test_va_end
1328 ; CHECK-NOT: INTRINSIC
1329 ; CHECK: RET_ReallyLR
1330 call void @llvm.va_end(i8* %list)
1334 define void @test_va_arg(i8* %list) {
1335 ; CHECK-LABEL: test_va_arg
1336 ; CHECK: [[LIST:%[0-9]+]]:_(p0) = COPY $x0
1337 ; CHECK: G_VAARG [[LIST]](p0), 8
1338 ; CHECK: G_VAARG [[LIST]](p0), 1
1339 ; CHECK: G_VAARG [[LIST]](p0), 16
1341 %v0 = va_arg i8* %list, i64
1342 %v1 = va_arg i8* %list, i8
1343 %v2 = va_arg i8* %list, i128
1347 declare float @llvm.pow.f32(float, float)
1348 define float @test_pow_intrin(float %l, float %r) {
1349 ; CHECK-LABEL: name: test_pow_intrin
1350 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $s0
1351 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $s1
1352 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FPOW [[LHS]], [[RHS]]
1353 ; CHECK: $s0 = COPY [[RES]]
1354 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.pow.f32(float %l, float %r)
1358 declare float @llvm.fma.f32(float, float, float)
1359 define float @test_fma_intrin(float %a, float %b, float %c) {
1360 ; CHECK-LABEL: name: test_fma_intrin
1361 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1362 ; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $s1
1363 ; CHECK: [[C:%[0-9]+]]:_(s32) = COPY $s2
1364 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FMA [[A]], [[B]], [[C]]
1365 ; CHECK: $s0 = COPY [[RES]]
1366 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.fma.f32(float %a, float %b, float %c)
1370 declare float @llvm.exp.f32(float)
1371 define float @test_exp_intrin(float %a) {
1372 ; CHECK-LABEL: name: test_exp_intrin
1373 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1374 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FEXP [[A]]
1375 ; CHECK: $s0 = COPY [[RES]]
1376 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.exp.f32(float %a)
1380 declare float @llvm.exp2.f32(float)
1381 define float @test_exp2_intrin(float %a) {
1382 ; CHECK-LABEL: name: test_exp2_intrin
1383 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1384 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FEXP2 [[A]]
1385 ; CHECK: $s0 = COPY [[RES]]
1386 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.exp2.f32(float %a)
1390 declare float @llvm.log.f32(float)
1391 define float @test_log_intrin(float %a) {
1392 ; CHECK-LABEL: name: test_log_intrin
1393 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1394 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FLOG [[A]]
1395 ; CHECK: $s0 = COPY [[RES]]
1396 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.log.f32(float %a)
1400 declare float @llvm.log2.f32(float)
1401 define float @test_log2_intrin(float %a) {
1402 ; CHECK-LABEL: name: test_log2_intrin
1403 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1404 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FLOG2 [[A]]
1405 ; CHECK: $s0 = COPY [[RES]]
1406 %res = call float @llvm.log2.f32(float %a)
1410 declare float @llvm.log10.f32(float)
1411 define float @test_log10_intrin(float %a) {
1412 ; CHECK-LABEL: name: test_log10_intrin
1413 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1414 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FLOG10 [[A]]
1415 ; CHECK: $s0 = COPY [[RES]]
1416 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.log10.f32(float %a)
1420 declare float @llvm.fabs.f32(float)
1421 define float @test_fabs_intrin(float %a) {
1422 ; CHECK-LABEL: name: test_fabs_intrin
1423 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1424 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FABS [[A]]
1425 ; CHECK: $s0 = COPY [[RES]]
1426 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.fabs.f32(float %a)
1430 declare float @llvm.canonicalize.f32(float)
1431 define float @test_fcanonicalize_intrin(float %a) {
1432 ; CHECK-LABEL: name: test_fcanonicalize_intrin
1433 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1434 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FCANONICALIZE [[A]]
1435 ; CHECK: $s0 = COPY [[RES]]
1436 %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.canonicalize.f32(float %a)
1440 declare float @llvm.trunc.f32(float)
1441 define float @test_intrinsic_trunc(float %a) {
1442 ; CHECK-LABEL: name: test_intrinsic_trunc
1443 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1444 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_TRUNC [[A]]
1445 ; CHECK: $s0 = COPY [[RES]]
1446 %res = call float @llvm.trunc.f32(float %a)
1450 declare float @llvm.round.f32(float)
1451 define float @test_intrinsic_round(float %a) {
1452 ; CHECK-LABEL: name: test_intrinsic_round
1453 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1454 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_ROUND [[A]]
1455 ; CHECK: $s0 = COPY [[RES]]
1456 %res = call float @llvm.round.f32(float %a)
1460 declare i32 @llvm.ctlz.i32(i32, i1)
1461 define i32 @test_ctlz_intrinsic_zero_not_undef(i32 %a) {
1462 ; CHECK-LABEL: name: test_ctlz_intrinsic_zero_not_undef
1463 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1464 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTLZ [[A]]
1465 ; CHECK: $w0 = COPY [[RES]]
1466 %res = call i32 @llvm.ctlz.i32(i32 %a, i1 0)
1470 declare i32 @llvm.cttz.i32(i32, i1)
1471 define i32 @test_cttz_intrinsic_zero_undef(i32 %a) {
1472 ; CHECK-LABEL: name: test_cttz_intrinsic_zero_undef
1473 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1474 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[A]]
1475 ; CHECK: $w0 = COPY [[RES]]
1476 %res = call i32 @llvm.cttz.i32(i32 %a, i1 1)
1480 declare i32 @llvm.ctpop.i32(i32)
1481 define i32 @test_ctpop_intrinsic(i32 %a) {
1482 ; CHECK-LABEL: name: test_ctpop
1483 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1484 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTPOP [[A]]
1485 ; CHECK: $w0 = COPY [[RES]]
1486 %res = call i32 @llvm.ctpop.i32(i32 %a)
1490 declare void @llvm.lifetime.start.p0i8(i64, i8*)
1491 declare void @llvm.lifetime.end.p0i8(i64, i8*)
1492 define void @test_lifetime_intrin() {
1493 ; CHECK-LABEL: name: test_lifetime_intrin
1494 ; CHECK: RET_ReallyLR
1495 ; O3-LABEL: name: test_lifetime_intrin
1496 ; O3: {{%[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.0.slot
1497 ; O3-NEXT: LIFETIME_START %stack.0.slot
1498 ; O3-NEXT: LIFETIME_END %stack.0.slot
1499 ; O3-NEXT: RET_ReallyLR
1500 %slot = alloca i8, i32 4
1501 call void @llvm.lifetime.start.p0i8(i64 0, i8* %slot)
1502 call void @llvm.lifetime.end.p0i8(i64 0, i8* %slot)
1506 define void @test_load_store_atomics(i8* %addr) {
1507 ; CHECK-LABEL: name: test_load_store_atomics
1508 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1509 ; CHECK: [[V0:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load unordered 1 from %ir.addr)
1510 ; CHECK: G_STORE [[V0]](s8), [[ADDR]](p0) :: (store monotonic 1 into %ir.addr)
1511 ; CHECK: [[V1:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load acquire 1 from %ir.addr)
1512 ; CHECK: G_STORE [[V1]](s8), [[ADDR]](p0) :: (store release 1 into %ir.addr)
1513 ; CHECK: [[V2:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load syncscope("singlethread") seq_cst 1 from %ir.addr)
1514 ; CHECK: G_STORE [[V2]](s8), [[ADDR]](p0) :: (store syncscope("singlethread") monotonic 1 into %ir.addr)
1515 %v0 = load atomic i8, i8* %addr unordered, align 1
1516 store atomic i8 %v0, i8* %addr monotonic, align 1
1518 %v1 = load atomic i8, i8* %addr acquire, align 1
1519 store atomic i8 %v1, i8* %addr release, align 1
1521 %v2 = load atomic i8, i8* %addr syncscope("singlethread") seq_cst, align 1
1522 store atomic i8 %v2, i8* %addr syncscope("singlethread") monotonic, align 1
1527 define float @test_fneg_f32(float %x) {
1528 ; CHECK-LABEL: name: test_fneg_f32
1529 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0
1530 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FNEG [[ARG]]
1531 ; CHECK: $s0 = COPY [[RES]](s32)
1532 %neg = fsub float -0.000000e+00, %x
1536 define double @test_fneg_f64(double %x) {
1537 ; CHECK-LABEL: name: test_fneg_f64
1538 ; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0
1539 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FNEG [[ARG]]
1540 ; CHECK: $d0 = COPY [[RES]](s64)
1541 %neg = fsub double -0.000000e+00, %x
1545 define void @test_trivial_inlineasm() {
1546 ; CHECK-LABEL: name: test_trivial_inlineasm
1547 ; CHECK: INLINEASM &wibble, 1
1548 ; CHECK: INLINEASM &wibble, 0
1549 call void asm sideeffect "wibble", ""()
1550 call void asm "wibble", ""()
1554 define <2 x i32> @test_insertelement(<2 x i32> %vec, i32 %elt, i32 %idx){
1555 ; CHECK-LABEL: name: test_insertelement
1556 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1557 ; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0
1558 ; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w1
1559 ; CHECK: [[RES:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[VEC]], [[ELT]](s32), [[IDX]](s32)
1560 ; CHECK: $d0 = COPY [[RES]](<2 x s32>)
1561 %res = insertelement <2 x i32> %vec, i32 %elt, i32 %idx
1565 define i32 @test_extractelement(<2 x i32> %vec, i32 %idx) {
1566 ; CHECK-LABEL: name: test_extractelement
1567 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1568 ; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w0
1569 ; CHECK: [[IDXEXT:%[0-9]+]]:_(s64) = G_SEXT [[IDX]]
1570 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDXEXT]](s64)
1571 ; CHECK: $w0 = COPY [[RES]](s32)
1572 %res = extractelement <2 x i32> %vec, i32 %idx
1576 define i32 @test_extractelement_const_idx(<2 x i32> %vec) {
1577 ; CHECK-LABEL: name: test_extractelement
1578 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1579 ; CHECK: [[IDX:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1580 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDX]](s64)
1581 ; CHECK: $w0 = COPY [[RES]](s32)
1582 %res = extractelement <2 x i32> %vec, i32 1
1586 define i32 @test_singleelementvector(i32 %elt){
1587 ; CHECK-LABEL: name: test_singleelementvector
1588 ; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0
1589 ; CHECK-NOT: G_INSERT_VECTOR_ELT
1590 ; CHECK-NOT: G_EXTRACT_VECTOR_ELT
1591 ; CHECK: $w0 = COPY [[ELT]](s32)
1592 %vec = insertelement <1 x i32> undef, i32 %elt, i32 0
1593 %res = extractelement <1 x i32> %vec, i32 0
1597 define <2 x i32> @test_constantaggzerovector_v2i32() {
1598 ; CHECK-LABEL: name: test_constantaggzerovector_v2i32
1599 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1600 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32)
1601 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1602 ret <2 x i32> zeroinitializer
1605 define <2 x float> @test_constantaggzerovector_v2f32() {
1606 ; CHECK-LABEL: name: test_constantaggzerovector_v2f32
1607 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_FCONSTANT float 0.000000e+00
1608 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32)
1609 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1610 ret <2 x float> zeroinitializer
1613 define i32 @test_constantaggzerovector_v3i32() {
1614 ; CHECK-LABEL: name: test_constantaggzerovector_v3i32
1615 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1616 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32), [[ZERO]](s32)
1617 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1618 %elt = extractelement <3 x i32> zeroinitializer, i32 1
1622 define <2 x i32> @test_constantdatavector_v2i32() {
1623 ; CHECK-LABEL: name: test_constantdatavector_v2i32
1624 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1625 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1626 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32)
1627 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1628 ret <2 x i32> <i32 1, i32 2>
1631 define i32 @test_constantdatavector_v3i32() {
1632 ; CHECK-LABEL: name: test_constantdatavector_v3i32
1633 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1634 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1635 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1636 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32), [[C3]](s32)
1637 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1638 %elt = extractelement <3 x i32> <i32 1, i32 2, i32 3>, i32 1
1642 define <4 x i32> @test_constantdatavector_v4i32() {
1643 ; CHECK-LABEL: name: test_constantdatavector_v4i32
1644 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1645 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1646 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1647 ; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
1648 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32), [[C3]](s32), [[C4]](s32)
1649 ; CHECK: $q0 = COPY [[VEC]](<4 x s32>)
1650 ret <4 x i32> <i32 1, i32 2, i32 3, i32 4>
1653 define <2 x double> @test_constantdatavector_v2f64() {
1654 ; CHECK-LABEL: name: test_constantdatavector_v2f64
1655 ; CHECK: [[FC1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
1656 ; CHECK: [[FC2:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
1657 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[FC1]](s64), [[FC2]](s64)
1658 ; CHECK: $q0 = COPY [[VEC]](<2 x s64>)
1659 ret <2 x double> <double 1.0, double 2.0>
1662 define i32 @test_constantaggzerovector_v1s32(i32 %arg){
1663 ; CHECK-LABEL: name: test_constantaggzerovector_v1s32
1664 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1665 ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1666 ; CHECK-NOT: G_MERGE_VALUES
1667 ; CHECK: G_ADD [[ARG]], [[C0]]
1668 %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1669 %add = add <1 x i32> %vec, zeroinitializer
1670 %res = extractelement <1 x i32> %add, i32 0
1674 define i32 @test_constantdatavector_v1s32(i32 %arg){
1675 ; CHECK-LABEL: name: test_constantdatavector_v1s32
1676 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1677 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1678 ; CHECK-NOT: G_MERGE_VALUES
1679 ; CHECK: G_ADD [[ARG]], [[C1]]
1680 %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1681 %add = add <1 x i32> %vec, <i32 1>
1682 %res = extractelement <1 x i32> %add, i32 0
1686 declare ghccc float @different_call_conv_target(float %x)
1687 define float @test_different_call_conv_target(float %x) {
1688 ; CHECK-LABEL: name: test_different_call_conv
1689 ; CHECK: [[X:%[0-9]+]]:_(s32) = COPY $s0
1690 ; CHECK: $s8 = COPY [[X]]
1691 ; CHECK: BL @different_call_conv_target, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s8, implicit-def $s0
1692 %res = call ghccc float @different_call_conv_target(float %x)
1696 define <2 x i32> @test_shufflevector_s32_v2s32(i32 %arg) {
1697 ; CHECK-LABEL: name: test_shufflevector_s32_v2s32
1698 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1699 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
1700 ; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1701 ; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C0]](s32)
1702 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], [[MASK]](<2 x s32>)
1703 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1704 %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1705 %res = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
1709 define i32 @test_shufflevector_v2s32_s32(<2 x i32> %arg) {
1710 ; CHECK-LABEL: name: test_shufflevector_v2s32_s32
1711 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1712 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1713 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1714 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[C1]](s32)
1715 ; CHECK: $w0 = COPY [[RES]](s32)
1716 %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <1 x i32> <i32 1>
1717 %res = extractelement <1 x i32> %vec, i32 0
1721 define <2 x i32> @test_shufflevector_v2s32_v2s32(<2 x i32> %arg) {
1722 ; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32
1723 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1724 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1725 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1726 ; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1727 ; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C0]](s32)
1728 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[MASK]](<2 x s32>)
1729 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1730 %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 1, i32 0>
1734 define i32 @test_shufflevector_v2s32_v3s32(<2 x i32> %arg) {
1735 ; CHECK-LABEL: name: test_shufflevector_v2s32_v3s32
1736 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1737 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1738 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1739 ; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1740 ; CHECK-DAG: [[MASK:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C0]](s32), [[C1]](s32)
1741 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[MASK]](<3 x s32>)
1742 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1743 %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <3 x i32> <i32 1, i32 0, i32 1>
1744 %res = extractelement <3 x i32> %vec, i32 0
1748 define <4 x i32> @test_shufflevector_v2s32_v4s32(<2 x i32> %arg1, <2 x i32> %arg2) {
1749 ; CHECK-LABEL: name: test_shufflevector_v2s32_v4s32
1750 ; CHECK: [[ARG1:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1751 ; CHECK: [[ARG2:%[0-9]+]]:_(<2 x s32>) = COPY $d1
1752 ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1753 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1754 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1755 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1756 ; CHECK: [[MASK:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C1]](s32), [[C2]](s32), [[C3]](s32)
1757 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[ARG1]](<2 x s32>), [[ARG2]], [[MASK]](<4 x s32>)
1758 ; CHECK: $q0 = COPY [[VEC]](<4 x s32>)
1759 %res = shufflevector <2 x i32> %arg1, <2 x i32> %arg2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1763 define <2 x i32> @test_shufflevector_v4s32_v2s32(<4 x i32> %arg) {
1764 ; CHECK-LABEL: name: test_shufflevector_v4s32_v2s32
1765 ; CHECK: [[ARG:%[0-9]+]]:_(<4 x s32>) = COPY $q0
1766 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF
1767 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1768 ; CHECK-DAG: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1769 ; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C3]](s32)
1770 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<4 x s32>), [[UNDEF]], [[MASK]](<2 x s32>)
1771 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1772 %res = shufflevector <4 x i32> %arg, <4 x i32> undef, <2 x i32> <i32 1, i32 3>
1777 define <16 x i8> @test_shufflevector_v8s8_v16s8(<8 x i8> %arg1, <8 x i8> %arg2) {
1778 ; CHECK-LABEL: name: test_shufflevector_v8s8_v16s8
1779 ; CHECK: [[ARG1:%[0-9]+]]:_(<8 x s8>) = COPY $d0
1780 ; CHECK: [[ARG2:%[0-9]+]]:_(<8 x s8>) = COPY $d1
1781 ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1782 ; CHECK: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
1783 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1784 ; CHECK: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 9
1785 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1786 ; CHECK: [[C10:%[0-9]+]]:_(s32) = G_CONSTANT i32 10
1787 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1788 ; CHECK: [[C11:%[0-9]+]]:_(s32) = G_CONSTANT i32 11
1789 ; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
1790 ; CHECK: [[C12:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
1791 ; CHECK: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
1792 ; CHECK: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
1793 ; CHECK: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
1794 ; CHECK: [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 14
1795 ; CHECK: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
1796 ; CHECK: [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 15
1797 ; CHECK: [[MASK:%[0-9]+]]:_(<16 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C8]](s32), [[C1]](s32), [[C9]](s32), [[C2]](s32), [[C10]](s32), [[C3]](s32), [[C11]](s32), [[C4]](s32), [[C12]](s32), [[C5]](s32), [[C13]](s32), [[C6]](s32), [[C14]](s32), [[C7]](s32), [[C15]](s32)
1798 ; CHECK: [[VEC:%[0-9]+]]:_(<16 x s8>) = G_SHUFFLE_VECTOR [[ARG1]](<8 x s8>), [[ARG2]], [[MASK]](<16 x s32>)
1799 ; CHECK: $q0 = COPY [[VEC]](<16 x s8>)
1800 %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>
1804 ; CHECK-LABEL: test_constant_vector
1805 ; CHECK: [[UNDEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
1806 ; CHECK: [[F:%[0-9]+]]:_(s16) = G_FCONSTANT half 0xH3C00
1807 ; CHECK: [[M:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UNDEF]](s16), [[UNDEF]](s16), [[UNDEF]](s16), [[F]](s16)
1808 ; CHECK: $d0 = COPY [[M]](<4 x s16>)
1809 define <4 x half> @test_constant_vector() {
1810 ret <4 x half> <half undef, half undef, half undef, half 0xH3C00>
1813 define i32 @test_target_mem_intrinsic(i32* %addr) {
1814 ; CHECK-LABEL: name: test_target_mem_intrinsic
1815 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1816 ; CHECK: [[VAL:%[0-9]+]]:_(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), [[ADDR]](p0) :: (volatile load 4 from %ir.addr)
1817 ; CHECK: G_TRUNC [[VAL]](s64)
1818 %val = call i64 @llvm.aarch64.ldxr.p0i32(i32* %addr)
1819 %trunc = trunc i64 %val to i32
1823 declare i64 @llvm.aarch64.ldxr.p0i32(i32*) nounwind
1825 %zerosize_type = type {}
1827 define %zerosize_type @test_empty_load_store(%zerosize_type *%ptr, %zerosize_type %in) noinline optnone {
1828 ; CHECK-LABEL: name: test_empty_load_store
1829 ; CHECK-NOT: G_STORE
1831 ; CHECK: RET_ReallyLR
1833 store %zerosize_type undef, %zerosize_type* undef, align 4
1834 %val = load %zerosize_type, %zerosize_type* %ptr, align 4
1835 ret %zerosize_type %in
1839 define i64 @test_phi_loop(i32 %n) {
1840 ; CHECK-LABEL: name: test_phi_loop
1841 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
1842 ; CHECK: [[CST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1843 ; CHECK: [[CST2:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1844 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
1845 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1847 ; CHECK: [[PN1:%[0-9]+]]:_(s32) = G_PHI [[ARG1]](s32), %bb.1, [[SUB:%[0-9]+]](s32), %bb.2
1848 ; CHECK: [[PN2:%[0-9]+]]:_(s64) = G_PHI [[CST3]](s64), %bb.1, [[PN3:%[0-9]+]](s64), %bb.2
1849 ; CHECK: [[PN3]]:_(s64) = G_PHI [[CST4]](s64), %bb.1, [[ADD:%[0-9]+]](s64), %bb.2
1850 ; CHECK: [[ADD]]:_(s64) = G_ADD [[PN2]], [[PN3]]
1851 ; CHECK: [[SUB]]:_(s32) = G_SUB [[PN1]], [[CST1]]
1852 ; CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(sle), [[PN1]](s32), [[CST2]]
1853 ; CHECK: G_BRCOND [[CMP]](s1), %bb.3
1856 ; CHECK: $x0 = COPY [[PN2]](s64)
1857 ; CHECK: RET_ReallyLR implicit $x0
1862 %counter = phi i32 [ %n, %entry ], [ %counter.dec, %loop ]
1863 %elem = phi { i64, i64 } [ { i64 0, i64 1 }, %entry ], [ %updated, %loop ]
1864 %prev = extractvalue { i64, i64 } %elem, 0
1865 %curr = extractvalue { i64, i64 } %elem, 1
1866 %next = add i64 %prev, %curr
1867 %shifted = insertvalue { i64, i64 } %elem, i64 %curr, 0
1868 %updated = insertvalue { i64, i64 } %shifted, i64 %next, 1
1869 %counter.dec = sub i32 %counter, 1
1870 %cond = icmp sle i32 %counter, 0
1871 br i1 %cond, label %exit, label %loop
1874 %res = extractvalue { i64, i64 } %elem, 0
1878 define void @test_phi_diamond({ i8, i16, i32 }* %a.ptr, { i8, i16, i32 }* %b.ptr, i1 %selector, { i8, i16, i32 }* %dst) {
1879 ; CHECK-LABEL: name: test_phi_diamond
1880 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
1881 ; CHECK: [[ARG2:%[0-9]+]]:_(p0) = COPY $x1
1882 ; CHECK: [[ARG3:%[0-9]+]]:_(s32) = COPY $w2
1883 ; CHECK: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[ARG3]](s32)
1884 ; CHECK: [[ARG4:%[0-9]+]]:_(p0) = COPY $x3
1885 ; CHECK: G_BRCOND [[TRUNC]](s1), %bb.2
1888 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD [[ARG1]](p0) :: (load 1 from %ir.a.ptr, align 4)
1889 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1890 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[ARG1]], [[CST1]](s64)
1891 ; CHECK: [[LD2:%[0-9]+]]:_(s16) = G_LOAD [[GEP1]](p0) :: (load 2 from %ir.a.ptr + 2)
1892 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1893 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP [[ARG1]], [[CST2]](s64)
1894 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.a.ptr + 4)
1897 ; CHECK: [[LD4:%[0-9]+]]:_(s8) = G_LOAD [[ARG2]](p0) :: (load 1 from %ir.b.ptr, align 4)
1898 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1899 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP [[ARG2]], [[CST3]](s64)
1900 ; CHECK: [[LD5:%[0-9]+]]:_(s16) = G_LOAD [[GEP3]](p0) :: (load 2 from %ir.b.ptr + 2)
1901 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1902 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP [[ARG2]], [[CST4]](s64)
1903 ; CHECK: [[LD6:%[0-9]+]]:_(s32) = G_LOAD [[GEP4]](p0) :: (load 4 from %ir.b.ptr + 4)
1905 ; CHECK: [[PN1:%[0-9]+]]:_(s8) = G_PHI [[LD1]](s8), %bb.2, [[LD4]](s8), %bb.3
1906 ; CHECK: [[PN2:%[0-9]+]]:_(s16) = G_PHI [[LD2]](s16), %bb.2, [[LD5]](s16), %bb.3
1907 ; CHECK: [[PN3:%[0-9]+]]:_(s32) = G_PHI [[LD3]](s32), %bb.2, [[LD6]](s32), %bb.3
1908 ; CHECK: G_STORE [[PN1]](s8), [[ARG4]](p0) :: (store 1 into %ir.dst, align 4)
1909 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1910 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP [[ARG4]], [[CST5]](s64)
1911 ; CHECK: G_STORE [[PN2]](s16), [[GEP5]](p0) :: (store 2 into %ir.dst + 2)
1912 ; CHECK: [[CST6:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1913 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP [[ARG4]], [[CST6]](s64)
1914 ; CHECK: G_STORE [[PN3]](s32), [[GEP6]](p0) :: (store 4 into %ir.dst + 4)
1915 ; CHECK: RET_ReallyLR
1918 br i1 %selector, label %store.a, label %store.b
1921 %a = load { i8, i16, i32 }, { i8, i16, i32 }* %a.ptr
1925 %b = load { i8, i16, i32 }, { i8, i16, i32 }* %b.ptr
1929 %v = phi { i8, i16, i32 } [ %a, %store.a ], [ %b, %store.b ]
1930 store { i8, i16, i32 } %v, { i8, i16, i32 }* %dst
1934 %agg.inner.inner = type {i64, i64}
1935 %agg.inner = type {i16, i8, %agg.inner.inner }
1936 %agg.nested = type {i32, i32, %agg.inner, i32}
1938 define void @test_nested_aggregate_const(%agg.nested *%ptr) {
1939 ; CHECK-LABEL: name: test_nested_aggregate_const
1940 ; CHECK: [[BASE:%[0-9]+]]:_(p0) = COPY $x0
1941 ; CHECK: [[CST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1942 ; CHECK: [[CST2:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
1943 ; CHECK: [[CST3:%[0-9]+]]:_(s8) = G_CONSTANT i8 3
1944 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
1945 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1946 ; CHECK: [[CST6:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
1947 ; CHECK: G_STORE [[CST1]](s32), [[BASE]](p0) :: (store 4 into %ir.ptr, align 8)
1948 ; CHECK: [[CST7:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1949 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST7]](s64)
1950 ; CHECK: G_STORE [[CST1]](s32), [[GEP1]](p0) :: (store 4 into %ir.ptr + 4)
1951 ; CHECK: [[CST8:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1952 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST8]](s64)
1953 ; CHECK: G_STORE [[CST2]](s16), [[GEP2]](p0) :: (store 2 into %ir.ptr + 8, align 8)
1954 ; CHECK: [[CST9:%[0-9]+]]:_(s64) = G_CONSTANT i64 10
1955 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST9]](s64)
1956 ; CHECK: G_STORE [[CST3]](s8), [[GEP3]](p0) :: (store 1 into %ir.ptr + 10, align 2)
1957 ; CHECK: [[CST10:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
1958 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST10]](s64)
1959 ; CHECK: G_STORE [[CST4]](s64), [[GEP4]](p0) :: (store 8 into %ir.ptr + 16)
1960 ; CHECK: [[CST11:%[0-9]+]]:_(s64) = G_CONSTANT i64 24
1961 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST11]](s64)
1962 ; CHECK: G_STORE [[CST5]](s64), [[GEP5]](p0) :: (store 8 into %ir.ptr + 24)
1963 ; CHECK: [[CST12:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
1964 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST12]](s64)
1965 ; CHECK: G_STORE [[CST6]](s32), [[GEP6]](p0) :: (store 4 into %ir.ptr + 32, align 8)
1966 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
1970 define i1 @return_i1_zext() {
1971 ; AAPCS ABI says that booleans can only be 1 or 0, so we need to zero-extend.
1972 ; CHECK-LABEL: name: return_i1_zext
1973 ; CHECK: [[CST:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
1974 ; CHECK: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[CST]](s1)
1975 ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
1976 ; CHECK: $w0 = COPY [[ANYEXT]](s32)
1977 ; CHECK: RET_ReallyLR implicit $w0
1982 define i32 @test_atomic_cmpxchg_1(i32* %addr) {
1983 ; CHECK-LABEL: name: test_atomic_cmpxchg_1
1984 ; CHECK: bb.1.entry:
1985 ; CHECK-NEXT: successors: %bb.{{[^)]+}}
1986 ; CHECK-NEXT: liveins: $x0
1987 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1988 ; CHECK-NEXT: [[OLDVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1989 ; CHECK-NEXT: [[NEWVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1990 ; CHECK: bb.2.repeat:
1991 ; CHECK-NEXT: successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
1992 ; 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)
1993 ; CHECK-NEXT: G_BRCOND [[SUCCESS]](s1), %bb.3
1994 ; CHECK-NEXT: G_BR %bb.2
1999 %val_success = cmpxchg i32* %addr, i32 0, i32 1 monotonic monotonic
2000 %value_loaded = extractvalue { i32, i1 } %val_success, 0
2001 %success = extractvalue { i32, i1 } %val_success, 1
2002 br i1 %success, label %done, label %repeat
2004 ret i32 %value_loaded
2007 ; Try one cmpxchg with a small type and high atomic ordering.
2008 define i16 @test_atomic_cmpxchg_2(i16* %addr) {
2009 ; CHECK-LABEL: name: test_atomic_cmpxchg_2
2010 ; CHECK: bb.1.entry:
2011 ; CHECK-NEXT: successors: %bb.2({{[^)]+}})
2012 ; CHECK-NEXT: liveins: $x0
2013 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2014 ; CHECK-NEXT: [[OLDVAL:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
2015 ; CHECK-NEXT: [[NEWVAL:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
2016 ; CHECK: bb.2.repeat:
2017 ; CHECK-NEXT: successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
2018 ; 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)
2019 ; CHECK-NEXT: G_BRCOND [[SUCCESS]](s1), %bb.3
2020 ; CHECK-NEXT: G_BR %bb.2
2025 %val_success = cmpxchg i16* %addr, i16 0, i16 1 seq_cst seq_cst
2026 %value_loaded = extractvalue { i16, i1 } %val_success, 0
2027 %success = extractvalue { i16, i1 } %val_success, 1
2028 br i1 %success, label %done, label %repeat
2030 ret i16 %value_loaded
2033 ; Try one cmpxchg where the success order and failure order differ.
2034 define i64 @test_atomic_cmpxchg_3(i64* %addr) {
2035 ; CHECK-LABEL: name: test_atomic_cmpxchg_3
2036 ; CHECK: bb.1.entry:
2037 ; CHECK-NEXT: successors: %bb.2({{[^)]+}})
2038 ; CHECK-NEXT: liveins: $x0
2039 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2040 ; CHECK-NEXT: [[OLDVAL:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
2041 ; CHECK-NEXT: [[NEWVAL:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
2042 ; CHECK: bb.2.repeat:
2043 ; CHECK-NEXT: successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
2044 ; 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)
2045 ; CHECK-NEXT: G_BRCOND [[SUCCESS]](s1), %bb.3
2046 ; CHECK-NEXT: G_BR %bb.2
2051 %val_success = cmpxchg i64* %addr, i64 0, i64 1 seq_cst acquire
2052 %value_loaded = extractvalue { i64, i1 } %val_success, 0
2053 %success = extractvalue { i64, i1 } %val_success, 1
2054 br i1 %success, label %done, label %repeat
2056 ret i64 %value_loaded
2059 ; Try a monotonic atomicrmw xchg
2060 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2061 define i32 @test_atomicrmw_xchg(i256* %addr) {
2062 ; CHECK-LABEL: name: test_atomicrmw_xchg
2063 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2064 ; CHECK-NEXT: liveins: $x0
2065 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2066 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2067 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_XCHG [[ADDR]](p0), [[VAL]] :: (load store monotonic 32 on %ir.addr)
2068 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2069 %oldval = atomicrmw xchg i256* %addr, i256 1 monotonic
2070 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2071 ; test so work around it by truncating to i32 for now.
2072 %oldval.trunc = trunc i256 %oldval to i32
2073 ret i32 %oldval.trunc
2076 ; Try an acquire atomicrmw add
2077 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2078 define i32 @test_atomicrmw_add(i256* %addr) {
2079 ; CHECK-LABEL: name: test_atomicrmw_add
2080 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2081 ; CHECK-NEXT: liveins: $x0
2082 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2083 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2084 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_ADD [[ADDR]](p0), [[VAL]] :: (load store acquire 32 on %ir.addr)
2085 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2086 %oldval = atomicrmw add i256* %addr, i256 1 acquire
2087 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2088 ; test so work around it by truncating to i32 for now.
2089 %oldval.trunc = trunc i256 %oldval to i32
2090 ret i32 %oldval.trunc
2093 ; Try a release atomicrmw sub
2094 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2095 define i32 @test_atomicrmw_sub(i256* %addr) {
2096 ; CHECK-LABEL: name: test_atomicrmw_sub
2097 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2098 ; CHECK-NEXT: liveins: $x0
2099 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2100 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2101 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_SUB [[ADDR]](p0), [[VAL]] :: (load store release 32 on %ir.addr)
2102 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2103 %oldval = atomicrmw sub i256* %addr, i256 1 release
2104 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2105 ; test so work around it by truncating to i32 for now.
2106 %oldval.trunc = trunc i256 %oldval to i32
2107 ret i32 %oldval.trunc
2110 ; Try an acq_rel atomicrmw and
2111 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2112 define i32 @test_atomicrmw_and(i256* %addr) {
2113 ; CHECK-LABEL: name: test_atomicrmw_and
2114 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2115 ; CHECK-NEXT: liveins: $x0
2116 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2117 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2118 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_AND [[ADDR]](p0), [[VAL]] :: (load store acq_rel 32 on %ir.addr)
2119 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2120 %oldval = atomicrmw and i256* %addr, i256 1 acq_rel
2121 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2122 ; test so work around it by truncating to i32 for now.
2123 %oldval.trunc = trunc i256 %oldval to i32
2124 ret i32 %oldval.trunc
2127 ; Try an seq_cst atomicrmw nand
2128 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2129 define i32 @test_atomicrmw_nand(i256* %addr) {
2130 ; CHECK-LABEL: name: test_atomicrmw_nand
2131 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2132 ; CHECK-NEXT: liveins: $x0
2133 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2134 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2135 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_NAND [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2136 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2137 %oldval = atomicrmw nand i256* %addr, i256 1 seq_cst
2138 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2139 ; test so work around it by truncating to i32 for now.
2140 %oldval.trunc = trunc i256 %oldval to i32
2141 ret i32 %oldval.trunc
2144 ; Try an seq_cst atomicrmw or
2145 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2146 define i32 @test_atomicrmw_or(i256* %addr) {
2147 ; CHECK-LABEL: name: test_atomicrmw_or
2148 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2149 ; CHECK-NEXT: liveins: $x0
2150 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2151 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2152 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_OR [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2153 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2154 %oldval = atomicrmw or i256* %addr, i256 1 seq_cst
2155 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2156 ; test so work around it by truncating to i32 for now.
2157 %oldval.trunc = trunc i256 %oldval to i32
2158 ret i32 %oldval.trunc
2161 ; Try an seq_cst atomicrmw xor
2162 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2163 define i32 @test_atomicrmw_xor(i256* %addr) {
2164 ; CHECK-LABEL: name: test_atomicrmw_xor
2165 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2166 ; CHECK-NEXT: liveins: $x0
2167 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2168 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2169 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_XOR [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2170 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2171 %oldval = atomicrmw xor i256* %addr, i256 1 seq_cst
2172 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2173 ; test so work around it by truncating to i32 for now.
2174 %oldval.trunc = trunc i256 %oldval to i32
2175 ret i32 %oldval.trunc
2178 ; Try an seq_cst atomicrmw min
2179 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2180 define i32 @test_atomicrmw_min(i256* %addr) {
2181 ; CHECK-LABEL: name: test_atomicrmw_min
2182 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2183 ; CHECK-NEXT: liveins: $x0
2184 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2185 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2186 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_MIN [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2187 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2188 %oldval = atomicrmw min i256* %addr, i256 1 seq_cst
2189 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2190 ; test so work around it by truncating to i32 for now.
2191 %oldval.trunc = trunc i256 %oldval to i32
2192 ret i32 %oldval.trunc
2195 ; Try an seq_cst atomicrmw max
2196 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2197 define i32 @test_atomicrmw_max(i256* %addr) {
2198 ; CHECK-LABEL: name: test_atomicrmw_max
2199 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2200 ; CHECK-NEXT: liveins: $x0
2201 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2202 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2203 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_MAX [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2204 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2205 %oldval = atomicrmw max i256* %addr, i256 1 seq_cst
2206 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2207 ; test so work around it by truncating to i32 for now.
2208 %oldval.trunc = trunc i256 %oldval to i32
2209 ret i32 %oldval.trunc
2212 ; Try an seq_cst atomicrmw unsigned min
2213 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2214 define i32 @test_atomicrmw_umin(i256* %addr) {
2215 ; CHECK-LABEL: name: test_atomicrmw_umin
2216 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2217 ; CHECK-NEXT: liveins: $x0
2218 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2219 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2220 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_UMIN [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2221 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2222 %oldval = atomicrmw umin i256* %addr, i256 1 seq_cst
2223 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2224 ; test so work around it by truncating to i32 for now.
2225 %oldval.trunc = trunc i256 %oldval to i32
2226 ret i32 %oldval.trunc
2229 ; Try an seq_cst atomicrmw unsigned max
2230 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2231 define i32 @test_atomicrmw_umax(i256* %addr) {
2232 ; CHECK-LABEL: name: test_atomicrmw_umax
2233 ; CHECK: bb.1 (%ir-block.{{[0-9]+}}):
2234 ; CHECK-NEXT: liveins: $x0
2235 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2236 ; CHECK-NEXT: [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2237 ; CHECK-NEXT: [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_UMAX [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2238 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2239 %oldval = atomicrmw umax i256* %addr, i256 1 seq_cst
2240 ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2241 ; test so work around it by truncating to i32 for now.
2242 %oldval.trunc = trunc i256 %oldval to i32
2243 ret i32 %oldval.trunc
2246 @addr = global i8* null
2248 define void @test_blockaddress() {
2249 ; CHECK-LABEL: name: test_blockaddress
2250 ; CHECK: [[BADDR:%[0-9]+]]:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
2251 ; CHECK: G_STORE [[BADDR]](p0)
2252 store i8* blockaddress(@test_blockaddress, %block), i8** @addr
2253 indirectbr i8* blockaddress(@test_blockaddress, %block), [label %block]
2259 declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) readonly nounwind
2260 declare void @llvm.invariant.end.p0i8({}*, i64, i8* nocapture) nounwind
2261 define void @test_invariant_intrin() {
2262 ; CHECK-LABEL: name: test_invariant_intrin
2263 ; CHECK: %{{[0-9]+}}:_(s64) = G_IMPLICIT_DEF
2264 ; CHECK-NEXT: RET_ReallyLR
2266 %y = bitcast %t* %x to i8*
2267 %inv = call {}* @llvm.invariant.start.p0i8(i64 8, i8* %y)
2268 call void @llvm.invariant.end.p0i8({}* %inv, i64 8, i8* %y)
2272 declare float @llvm.ceil.f32(float)
2273 define float @test_ceil_f32(float %x) {
2274 ; CHECK-LABEL: name: test_ceil_f32
2275 ; CHECK: %{{[0-9]+}}:_(s32) = G_FCEIL %{{[0-9]+}}
2276 %y = call float @llvm.ceil.f32(float %x)
2280 declare double @llvm.ceil.f64(double)
2281 define double @test_ceil_f64(double %x) {
2282 ; CHECK-LABEL: name: test_ceil_f64
2283 ; CHECK: %{{[0-9]+}}:_(s64) = G_FCEIL %{{[0-9]+}}
2284 %y = call double @llvm.ceil.f64(double %x)
2288 declare <2 x float> @llvm.ceil.v2f32(<2 x float>)
2289 define <2 x float> @test_ceil_v2f32(<2 x float> %x) {
2290 ; CHECK-LABEL: name: test_ceil_v2f32
2291 ; CHECK: %{{[0-9]+}}:_(<2 x s32>) = G_FCEIL %{{[0-9]+}}
2292 %y = call <2 x float> @llvm.ceil.v2f32(<2 x float> %x)
2296 declare <4 x float> @llvm.ceil.v4f32(<4 x float>)
2297 define <4 x float> @test_ceil_v4f32(<4 x float> %x) {
2298 ; CHECK-LABEL: name: test_ceil_v4f32
2299 ; CHECK: %{{[0-9]+}}:_(<4 x s32>) = G_FCEIL %{{[0-9]+}}
2300 ; SELECT: %{{[0-9]+}}:fpr128 = FRINTPv4f32 %{{[0-9]+}}
2301 %y = call <4 x float> @llvm.ceil.v4f32(<4 x float> %x)
2305 declare <2 x double> @llvm.ceil.v2f64(<2 x double>)
2306 define <2 x double> @test_ceil_v2f64(<2 x double> %x) {
2307 ; CHECK-LABEL: name: test_ceil_v2f64
2308 ; CHECK: %{{[0-9]+}}:_(<2 x s64>) = G_FCEIL %{{[0-9]+}}
2309 %y = call <2 x double> @llvm.ceil.v2f64(<2 x double> %x)
2313 declare float @llvm.cos.f32(float)
2314 define float @test_cos_f32(float %x) {
2315 ; CHECK-LABEL: name: test_cos_f32
2316 ; CHECK: %{{[0-9]+}}:_(s32) = G_FCOS %{{[0-9]+}}
2317 %y = call float @llvm.cos.f32(float %x)
2321 declare float @llvm.sin.f32(float)
2322 define float @test_sin_f32(float %x) {
2323 ; CHECK-LABEL: name: test_sin_f32
2324 ; CHECK: %{{[0-9]+}}:_(s32) = G_FSIN %{{[0-9]+}}
2325 %y = call float @llvm.sin.f32(float %x)
2329 declare float @llvm.sqrt.f32(float)
2330 define float @test_sqrt_f32(float %x) {
2331 ; CHECK-LABEL: name: test_sqrt_f32
2332 ; CHECK: %{{[0-9]+}}:_(s32) = G_FSQRT %{{[0-9]+}}
2333 %y = call float @llvm.sqrt.f32(float %x)
2337 declare float @llvm.floor.f32(float)
2338 define float @test_floor_f32(float %x) {
2339 ; CHECK-LABEL: name: test_floor_f32
2340 ; CHECK: %{{[0-9]+}}:_(s32) = G_FFLOOR %{{[0-9]+}}
2341 %y = call float @llvm.floor.f32(float %x)
2345 ; CHECK-LABEL: name: test_llvm.aarch64.neon.ld3.v4i32.p0i32
2346 ; CHECK: %1:_(s384) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld3), %0(p0) :: (load 48 from %ir.ptr, align 64)
2347 define void @test_llvm.aarch64.neon.ld3.v4i32.p0i32(i32* %ptr) {
2348 %arst = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i32(i32* %ptr)
2352 declare { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i32(i32*) #3