Skip to content

Commit 02989d7

Browse files
committed
[SelectionDAGBuilder] Look for apropriate INLINEASM_BR instruction to verify
1 parent 9b7b382 commit 02989d7

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12731,23 +12731,37 @@ void SelectionDAGBuilder::visitVectorSplice(const CallInst &I) {
1273112731
// increase in virtreg number from there. If a callbr has no outputs, then it
1273212732
// should not have a corresponding callbr landingpad; in fact, the callbr
1273312733
// landingpad would not even be able to refer to such a callbr.
12734-
static Register FollowCopyChain(MachineRegisterInfo &MRI, Register Reg) {
12734+
static Register FollowCopyChain(MachineRegisterInfo &MRI, Register Reg,
12735+
MachineBasicBlock *CallBrMBB) {
1273512736
MachineInstr *MI = MRI.def_begin(Reg)->getParent();
1273612737
// There is definitely at least one copy.
1273712738
assert(MI->getOpcode() == TargetOpcode::COPY &&
1273812739
"start of copy chain MUST be COPY");
1273912740
Reg = MI->getOperand(1).getReg();
12741+
12742+
// If the copied register in the first copy must be virtual.
12743+
assert(Reg.isVirtual() && "expected COPY of virtual register");
1274012744
MI = MRI.def_begin(Reg)->getParent();
12745+
1274112746
// There may be an optional second copy.
1274212747
if (MI->getOpcode() == TargetOpcode::COPY) {
1274312748
assert(Reg.isVirtual() && "expected COPY of virtual register");
1274412749
Reg = MI->getOperand(1).getReg();
1274512750
assert(Reg.isPhysical() && "expected COPY of physical register");
12746-
MI = MRI.def_begin(Reg)->getParent();
12751+
12752+
// Look for the machine callbr instruction.
12753+
for (auto Def : MRI.def_operands(Reg))
12754+
if (Def.getParent()->getOpcode() == TargetOpcode::INLINEASM_BR &&
12755+
Def.getParent()->getParent() == CallBrMBB) {
12756+
MI = Def.getParent();
12757+
break;
12758+
}
1274712759
}
12760+
1274812761
// The start of the chain must be an INLINEASM_BR.
1274912762
assert(MI->getOpcode() == TargetOpcode::INLINEASM_BR &&
1275012763
"end of copy chain MUST be INLINEASM_BR");
12764+
1275112765
return Reg;
1275212766
}
1275312767

@@ -12766,6 +12780,7 @@ void SelectionDAGBuilder::visitCallBrLandingPad(const CallInst &I) {
1276612780
MachineRegisterInfo &MRI = DAG.getMachineFunction().getRegInfo();
1276712781

1276812782
Register InitialDef = FuncInfo.ValueMap[CBR];
12783+
MachineBasicBlock *CallBrMBB = FuncInfo.getMBB(CBR->getParent());
1276912784
SDValue Chain = DAG.getRoot();
1277012785

1277112786
// Re-parse the asm constraints string.
@@ -12789,7 +12804,7 @@ void SelectionDAGBuilder::visitCallBrLandingPad(const CallInst &I) {
1278912804
// getRegistersForValue may produce 1 to many registers based on whether
1279012805
// the OpInfo.ConstraintVT is legal on the target or not.
1279112806
for (Register &Reg : OpInfo.AssignedRegs.Regs) {
12792-
Register OriginalDef = FollowCopyChain(MRI, InitialDef++);
12807+
Register OriginalDef = FollowCopyChain(MRI, InitialDef++, CallBrMBB);
1279312808
if (OriginalDef.isPhysical())
1279412809
FuncInfo.MBB->addLiveIn(OriginalDef);
1279512810
// Update the assigned registers to use the original defs.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
3+
; RUN: llc -O0 -mtriple=i686-- -verify-machineinstrs < %s | FileCheck %s
4+
5+
; Test that causes multiple defs of %eax.
6+
; FIXME: The testcase hangs with -O1/2/3 enabled.
7+
define i32 @loop1() {
8+
; CHECK-LABEL: loop1:
9+
; CHECK: # %bb.0: # %entry
10+
; CHECK-NEXT: pushl %esi
11+
; CHECK-NEXT: .cfi_def_cfa_offset 8
12+
; CHECK-NEXT: .cfi_offset %esi, -8
13+
; CHECK-NEXT: jmp .LBB0_1
14+
; CHECK-NEXT: .LBB0_1: # %tailrecurse
15+
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
16+
; CHECK-NEXT: xorl %eax, %eax
17+
; CHECK-NEXT: movl $1, %edx
18+
; CHECK-NEXT: #APP
19+
; CHECK-NEXT: #NO_APP
20+
; CHECK-NEXT: movl %eax, %ecx
21+
; CHECK-NEXT: movl %edx, %esi
22+
; CHECK-NEXT: jmp .LBB0_3
23+
; CHECK-NEXT: .LBB0_2: # Inline asm indirect target
24+
; CHECK-NEXT: # %tailrecurse.tailrecurse.backedge_crit_edge
25+
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
26+
; CHECK-NEXT: # Label of block must be emitted
27+
; CHECK-NEXT: .LBB0_3: # %tailrecurse.backedge
28+
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
29+
; CHECK-NEXT: jmp .LBB0_1
30+
; CHECK-NEXT: .LBB0_4: # Inline asm indirect target
31+
; CHECK-NEXT: # %lab2.split
32+
; CHECK-NEXT: # Label of block must be emitted
33+
; CHECK-NEXT: movl %edx, %eax
34+
; CHECK-NEXT: popl %esi
35+
; CHECK-NEXT: .cfi_def_cfa_offset 4
36+
; CHECK-NEXT: retl
37+
entry:
38+
br label %tailrecurse
39+
40+
tailrecurse:
41+
%0 = callbr { i32, i32 } asm "", "={ax},={dx},0,1,!i,!i"(i32 0, i32 1) #1
42+
to label %tailrecurse.backedge [label %tailrecurse.backedge, label %lab2.split]
43+
44+
tailrecurse.backedge:
45+
br label %tailrecurse
46+
47+
lab2.split:
48+
%asmresult5 = extractvalue { i32, i32 } %0, 1
49+
ret i32 %asmresult5
50+
}

0 commit comments

Comments
 (0)