llvm-project/llvm/test/CodeGen/AArch64/callbr-asm-outputs-indirect-isel.ll
Samuel Tebbs 72a60e770c [AArch64][NFC] Use regexes in register class tests
Some MIR and IR tests include checks for register class IDs, which are
unnecessary since the register class name is also checked for and that
doesn't change when new classes are added. This patch replaces the
hard-coded register class ID checks with regexes so they don't have to
be updated every time a new class is added.
2024-02-29 11:46:07 +00:00

558 lines
21 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
; RUN: llc -mtriple=aarch64-linux-gnu %s -o - -verify-machineinstrs \
; RUN: -start-before=aarch64-isel -stop-after=finalize-isel \
; RUN: -global-isel=0 -fast-isel=0 | FileCheck %s
; This file was initially generated via:
; $ opt -S -callbrprepare llvm/test/CodeGen/AArch64/callbr-prepare.ll -o \
; llvm/test/CodeGen/AArch64/callbr-asm-outputs-indirect-isel.ll
; TODO: should we remove test cases that don't use landingpad intrinsic?
; They're not interesting IMO.
; Removed is the test case for x86 machine specific physreg constraints.
define i32 @test0() {
; CHECK-LABEL: name: test0
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.2(0x80000000), %bb.1(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"# $0", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %5, 13 /* imm */, %bb.1
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %5
; CHECK-NEXT: B %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.entry.indirect_crit_edge (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: successors: %bb.5(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY %5
; CHECK-NEXT: B %bb.5
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.direct:
; CHECK-NEXT: successors: %bb.4(0x80000000), %bb.3(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"# $0", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %7, 13 /* imm */, %bb.3
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32all = COPY %7
; CHECK-NEXT: B %bb.4
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3.direct.indirect_crit_edge (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: successors: %bb.5(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr32all = COPY %7
; CHECK-NEXT: B %bb.5
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.4.direct2:
; CHECK-NEXT: [[COPY4:%[0-9]+]]:gpr32all = COPY $wzr
; CHECK-NEXT: $w0 = COPY [[COPY4]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.5.indirect:
; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32all = PHI [[COPY1]], %bb.1, [[COPY3]], %bb.3
; CHECK-NEXT: $w0 = COPY [[PHI]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%out = callbr i32 asm "# $0", "=r,!i"()
to label %direct [label %entry.indirect_crit_edge]
entry.indirect_crit_edge: ; preds = %entry
%0 = call i32 @llvm.callbr.landingpad.i32(i32 %out)
br label %indirect
direct: ; preds = %entry
%out2 = callbr i32 asm "# $0", "=r,!i"()
to label %direct2 [label %direct.indirect_crit_edge]
direct.indirect_crit_edge: ; preds = %direct
%1 = call i32 @llvm.callbr.landingpad.i32(i32 %out2)
br label %indirect
direct2: ; preds = %direct
ret i32 0
indirect: ; preds = %direct.indirect_crit_edge, %entry.indirect_crit_edge
%out3 = phi i32 [ %0, %entry.indirect_crit_edge ], [ %1, %direct.indirect_crit_edge ]
ret i32 %out3
}
define i32 @dont_split0() {
; CHECK-LABEL: name: dont_split0
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.1(0x80000000), %bb.2(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, 13 /* imm */, %bb.2
; CHECK-NEXT: B %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.x:
; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42
; CHECK-NEXT: $w0 = COPY [[MOVi32imm]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.y (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY $wzr
; CHECK-NEXT: $w0 = COPY [[COPY]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
callbr void asm "", "!i"()
to label %x [label %y]
x: ; preds = %entry
ret i32 42
y: ; preds = %entry
ret i32 0
}
define i32 @dont_split1() {
; CHECK-LABEL: name: dont_split1
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.1(0x80000000), %bb.2(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %1, 13 /* imm */, %bb.2
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %1
; CHECK-NEXT: B %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.x:
; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42
; CHECK-NEXT: $w0 = COPY [[MOVi32imm]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.y (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: $w0 = COPY %1
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%0 = callbr i32 asm "", "=r,!i"()
to label %x [label %y]
x: ; preds = %entry
ret i32 42
y: ; preds = %entry
%1 = call i32 @llvm.callbr.landingpad.i32(i32 %0)
ret i32 %1
}
define i32 @dont_split2() {
; CHECK-LABEL: name: dont_split2
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.1(0x80000000), %bb.2(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY [[MOVi32imm]]
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, 13 /* imm */, %bb.2
; CHECK-NEXT: B %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.x:
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY $wzr
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32all = COPY [[COPY1]]
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.y (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32all = PHI [[COPY]], %bb.0, [[COPY2]], %bb.1
; CHECK-NEXT: $w0 = COPY [[PHI]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
callbr void asm "", "!i"()
to label %x [label %y]
x: ; preds = %entry
br label %y
y: ; preds = %x, %entry
%0 = phi i32 [ 0, %x ], [ 42, %entry ]
ret i32 %0
}
define i32 @dont_split3() {
; CHECK-LABEL: name: dont_split3
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.1(0x80000000), %bb.2(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %0, 13 /* imm */, %bb.2
; CHECK-NEXT: B %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.x:
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.v (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42
; CHECK-NEXT: $w0 = COPY [[MOVi32imm]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%0 = callbr i32 asm "", "=r,!i"()
to label %x [label %v]
x: ; preds = %entry
br label %v
v: ; preds = %x, %entry
ret i32 42
}
define i32 @split_me0() {
; CHECK-LABEL: name: split_me0
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.2(0x80000000), %bb.1(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %3, 13 /* imm */, %bb.1
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %3
; CHECK-NEXT: B %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.entry.y_crit_edge (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: successors: %bb.3(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY %3
; CHECK-NEXT: B %bb.3
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.x:
; CHECK-NEXT: successors: %bb.3(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32all = COPY [[MOVi32imm]]
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3.y:
; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32all = PHI [[COPY1]], %bb.1, [[COPY2]], %bb.2
; CHECK-NEXT: $w0 = COPY [[PHI]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%0 = callbr i32 asm "", "=r,!i"()
to label %x [label %entry.y_crit_edge]
entry.y_crit_edge: ; preds = %entry
%1 = call i32 @llvm.callbr.landingpad.i32(i32 %0)
br label %y
x: ; preds = %entry
br label %y
y: ; preds = %entry.y_crit_edge, %x
%2 = phi i32 [ %1, %entry.y_crit_edge ], [ 42, %x ]
ret i32 %2
}
define i32 @split_me1(i1 %z) {
; CHECK-LABEL: name: split_me1
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
; CHECK-NEXT: liveins: $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr32all = IMPLICIT_DEF
; CHECK-NEXT: TBZW [[COPY]], 0, %bb.4
; CHECK-NEXT: B %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.w:
; CHECK-NEXT: successors: %bb.3(0x80000000), %bb.2(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %5, 13 /* imm */, %bb.2, 13 /* imm */, %bb.2
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY %5
; CHECK-NEXT: B %bb.3
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.w.v_crit_edge (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: successors: %bb.4(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32all = COPY %5
; CHECK-NEXT: B %bb.4
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3.x:
; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42
; CHECK-NEXT: $w0 = COPY [[MOVi32imm]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.4.v:
; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32all = PHI [[DEF]], %bb.0, [[COPY2]], %bb.2
; CHECK-NEXT: $w0 = COPY [[PHI]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
br i1 %z, label %w, label %v
w: ; preds = %entry
%0 = callbr i32 asm "", "=r,!i,!i"()
to label %x [label %w.v_crit_edge, label %w.v_crit_edge]
w.v_crit_edge: ; preds = %w, %w
%1 = call i32 @llvm.callbr.landingpad.i32(i32 %0)
br label %v
x: ; preds = %w
ret i32 42
v: ; preds = %w.v_crit_edge, %entry
%2 = phi i32 [ %1, %w.v_crit_edge ], [ undef, %entry ]
ret i32 %2
}
define i32 @split_me2(i1 %z) {
; CHECK-LABEL: name: split_me2
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
; CHECK-NEXT: liveins: $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[MOVi32imm]]
; CHECK-NEXT: TBZW [[COPY]], 0, %bb.4
; CHECK-NEXT: B %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.w:
; CHECK-NEXT: successors: %bb.3(0x80000000), %bb.2(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %6, 13 /* imm */, %bb.2, 13 /* imm */, %bb.2
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32all = COPY %6
; CHECK-NEXT: B %bb.3
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.w.v_crit_edge (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: successors: %bb.4(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr32all = COPY %6
; CHECK-NEXT: B %bb.4
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3.x:
; CHECK-NEXT: [[MOVi32imm1:%[0-9]+]]:gpr32 = MOVi32imm 42
; CHECK-NEXT: $w0 = COPY [[MOVi32imm1]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.4.v:
; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32all = PHI [[COPY1]], %bb.0, [[COPY3]], %bb.2
; CHECK-NEXT: $w0 = COPY [[PHI]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
br i1 %z, label %w, label %v
w: ; preds = %entry
%0 = callbr i32 asm "", "=r,!i,!i"()
to label %x [label %w.v_crit_edge, label %w.v_crit_edge]
w.v_crit_edge: ; preds = %w, %w
%1 = call i32 @llvm.callbr.landingpad.i32(i32 %0)
br label %v
x: ; preds = %w
ret i32 42
v: ; preds = %w.v_crit_edge, %entry
%2 = phi i32 [ %1, %w.v_crit_edge ], [ 42, %entry ]
ret i32 %2
}
define i32 @dont_split4() {
; CHECK-LABEL: name: dont_split4
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.1(0x80000000), %bb.2(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %3, 13 /* imm */, %bb.2
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %3
; CHECK-NEXT: B %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.x:
; CHECK-NEXT: successors: %bb.3(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: B %bb.3
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.y (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: successors: %bb.3(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY %3
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3.out:
; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32all = PHI [[COPY1]], %bb.2, [[COPY]], %bb.1
; CHECK-NEXT: $w0 = COPY [[PHI]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%0 = callbr i32 asm "", "=r,!i"()
to label %x [label %y]
x: ; preds = %entry
br label %out
y: ; preds = %entry
%1 = call i32 @llvm.callbr.landingpad.i32(i32 %0)
br label %out
out: ; preds = %y, %x
%2 = phi i32 [ %1, %y ], [ %0, %x ]
ret i32 %2
}
define i32 @dont_split5() {
; CHECK-LABEL: name: dont_split5
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.2(0x80000000), %bb.1(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %3, 13 /* imm */, %bb.1
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %3
; CHECK-NEXT: B %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.y (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY %3
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.out:
; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32all = PHI [[COPY]], %bb.0, [[COPY1]], %bb.1
; CHECK-NEXT: $w0 = COPY [[PHI]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%0 = callbr i32 asm "", "=r,!i"()
to label %out [label %y]
y: ; preds = %entry
%1 = call i32 @llvm.callbr.landingpad.i32(i32 %0)
br label %out
out: ; preds = %y, %entry
%2 = phi i32 [ %1, %y ], [ %0, %entry ]
ret i32 %2
}
define i32 @split_me3() {
; CHECK-LABEL: name: split_me3
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.2(0x80000000), %bb.1(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %3, 13 /* imm */, %bb.1
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %3
; CHECK-NEXT: B %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.entry.out_crit_edge (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: successors: %bb.3(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY %3
; CHECK-NEXT: B %bb.3
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.y:
; CHECK-NEXT: successors: %bb.3(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3.out:
; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32all = PHI [[COPY1]], %bb.1, [[COPY]], %bb.2
; CHECK-NEXT: $w0 = COPY [[PHI]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%0 = callbr i32 asm "", "=r,!i"()
to label %y [label %entry.out_crit_edge]
entry.out_crit_edge: ; preds = %entry
%1 = call i32 @llvm.callbr.landingpad.i32(i32 %0)
br label %out
y: ; preds = %entry
br label %out
out: ; preds = %entry.out_crit_edge, %y
%2 = phi i32 [ %1, %entry.out_crit_edge ], [ %0, %y ]
ret i32 %2
}
define i32 @dont_split6(i32 %0) {
; CHECK-LABEL: name: dont_split6
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.1(0x80000000)
; CHECK-NEXT: liveins: $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.loop:
; CHECK-NEXT: successors: %bb.3(0x80000000), %bb.2(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32all = PHI [[COPY]], %bb.0, %2, %bb.2
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32common = COPY [[PHI]]
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %4, 2147483657 /* reguse tiedto:$0 */, [[COPY1]](tied-def 3), 13 /* imm */, %bb.2
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32all = COPY %4
; CHECK-NEXT: B %bb.3
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.loop.loop_crit_edge (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: successors: %bb.1(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr32all = COPY %4
; CHECK-NEXT: B %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3.exit:
; CHECK-NEXT: [[COPY4:%[0-9]+]]:gpr32all = COPY $wzr
; CHECK-NEXT: $w0 = COPY [[COPY4]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
br label %loop
loop: ; preds = %loop.loop_crit_edge, %entry
%1 = phi i32 [ %0, %entry ], [ %3, %loop.loop_crit_edge ]
%2 = callbr i32 asm "", "=r,0,!i"(i32 %1)
to label %exit [label %loop.loop_crit_edge]
loop.loop_crit_edge: ; preds = %loop
%3 = call i32 @llvm.callbr.landingpad.i32(i32 %2)
br label %loop
exit: ; preds = %loop
ret i32 0
}
define i32 @split_me4() {
; CHECK-LABEL: name: split_me4
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.2(0x80000000), %bb.1(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %3, 13 /* imm */, %bb.1
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %3
; CHECK-NEXT: B %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.entry.same_crit_edge (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY %3
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.same:
; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32all = PHI [[COPY]], %bb.0, [[COPY1]], %bb.1
; CHECK-NEXT: $w0 = COPY [[PHI]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%0 = callbr i32 asm "", "=r,!i"()
to label %same [label %entry.same_crit_edge]
entry.same_crit_edge: ; preds = %entry
%1 = call i32 @llvm.callbr.landingpad.i32(i32 %0)
br label %same
same: ; preds = %entry.same_crit_edge, %entry
%2 = phi i32 [ %1, %entry.same_crit_edge ], [ %0, %entry ]
ret i32 %2
}
define i32 @split_me5() {
; CHECK-LABEL: name: split_me5
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.2(0x80000000), %bb.1(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %3, 13 /* imm */, %bb.1
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY %3
; CHECK-NEXT: B %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.entry.same_crit_edge (machine-block-address-taken, inlineasm-br-indirect-target):
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY %3
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.same:
; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32all = PHI [[COPY]], %bb.0, [[COPY1]], %bb.1
; CHECK-NEXT: $w0 = COPY [[PHI]]
; CHECK-NEXT: RET_ReallyLR implicit $w0
entry:
%0 = callbr i32 asm "", "=r,!i"()
to label %same [label %entry.same_crit_edge]
entry.same_crit_edge: ; preds = %entry
%1 = call i32 @llvm.callbr.landingpad.i32(i32 %0)
br label %same
same: ; preds = %entry.same_crit_edge, %entry
%2 = phi i32 [ %1, %entry.same_crit_edge ], [ %0, %entry ]
ret i32 %2
}
; Function Attrs: nounwind
declare i32 @llvm.callbr.landingpad.i32(i32) #0
; Function Attrs: nounwind
declare i64 @llvm.callbr.landingpad.i64(i64) #0
attributes #0 = { nounwind }