Skip to content

Commit 2a49719

Browse files
authored
[SelectionDAGBuilder] Look for appropriate INLINEASM_BR instruction to verify (#152591)
Partially fix #149023. The original code `MRI.def_begin(Reg)->getParent()` may return the incorrect MI, as the physical register `Reg` may have multiple definitions. This patch selects the correct MI to verify by comparing the MBB of each definition. New testcase hangs with -O1/2/3 enabled. The BranchFolding may be to blame.
1 parent 48da848 commit 2a49719

File tree

2 files changed

+56
-4
lines changed

2 files changed

+56
-4
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12744,17 +12744,22 @@ static Register FollowCopyChain(MachineRegisterInfo &MRI, Register Reg) {
1274412744
assert(MI->getOpcode() == TargetOpcode::COPY &&
1274512745
"start of copy chain MUST be COPY");
1274612746
Reg = MI->getOperand(1).getReg();
12747+
12748+
// If the copied register in the first copy must be virtual.
12749+
assert(Reg.isVirtual() && "expected COPY of virtual register");
1274712750
MI = MRI.def_begin(Reg)->getParent();
12751+
1274812752
// There may be an optional second copy.
1274912753
if (MI->getOpcode() == TargetOpcode::COPY) {
1275012754
assert(Reg.isVirtual() && "expected COPY of virtual register");
1275112755
Reg = MI->getOperand(1).getReg();
1275212756
assert(Reg.isPhysical() && "expected COPY of physical register");
12753-
MI = MRI.def_begin(Reg)->getParent();
12757+
} else {
12758+
// The start of the chain must be an INLINEASM_BR.
12759+
assert(MI->getOpcode() == TargetOpcode::INLINEASM_BR &&
12760+
"end of copy chain MUST be INLINEASM_BR");
1275412761
}
12755-
// The start of the chain must be an INLINEASM_BR.
12756-
assert(MI->getOpcode() == TargetOpcode::INLINEASM_BR &&
12757-
"end of copy chain MUST be INLINEASM_BR");
12762+
1275812763
return Reg;
1275912764
}
1276012765

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
3+
; RUN: llc -O0 -mtriple=i686-- < %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() nounwind {
8+
; CHECK-LABEL: loop1:
9+
; CHECK: # %bb.0: # %entry
10+
; CHECK-NEXT: pushl %esi
11+
; CHECK-NEXT: jmp .LBB0_1
12+
; CHECK-NEXT: .LBB0_1: # %tailrecurse
13+
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
14+
; CHECK-NEXT: xorl %eax, %eax
15+
; CHECK-NEXT: movl $1, %edx
16+
; CHECK-NEXT: #APP
17+
; CHECK-NEXT: #NO_APP
18+
; CHECK-NEXT: movl %eax, %ecx
19+
; CHECK-NEXT: movl %edx, %esi
20+
; CHECK-NEXT: jmp .LBB0_3
21+
; CHECK-NEXT: .LBB0_2: # Inline asm indirect target
22+
; CHECK-NEXT: # %tailrecurse.tailrecurse.backedge_crit_edge
23+
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
24+
; CHECK-NEXT: # Label of block must be emitted
25+
; CHECK-NEXT: .LBB0_3: # %tailrecurse.backedge
26+
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
27+
; CHECK-NEXT: jmp .LBB0_1
28+
; CHECK-NEXT: .LBB0_4: # Inline asm indirect target
29+
; CHECK-NEXT: # %lab2.split
30+
; CHECK-NEXT: # Label of block must be emitted
31+
; CHECK-NEXT: movl %edx, %eax
32+
; CHECK-NEXT: popl %esi
33+
; CHECK-NEXT: retl
34+
entry:
35+
br label %tailrecurse
36+
37+
tailrecurse:
38+
%0 = callbr { i32, i32 } asm "", "={ax},={dx},0,1,!i,!i"(i32 0, i32 1) #1
39+
to label %tailrecurse.backedge [label %tailrecurse.backedge, label %lab2.split]
40+
41+
tailrecurse.backedge:
42+
br label %tailrecurse
43+
44+
lab2.split:
45+
%asmresult5 = extractvalue { i32, i32 } %0, 1
46+
ret i32 %asmresult5
47+
}

0 commit comments

Comments
 (0)