Skip to content

Commit 4d3c427

Browse files
authored
[CodeGen] Use first EHLabel as a stop gate for live range shrinking (#114195)
This fixes issue #114194 The issue happens during the `LiveRangeShrink` pass, which runs early, before phi elimination. LandingPads, which are lowered to EHLabels, need to be the first non phi instruction in an EHPad. In case of a phi node being in front of the EHLabel and a use being after the EHLabel, we hoist the use in front of the label. This results in a portion of the landingpad missing due to being hoisted in front of the label.
1 parent 6ca816f commit 4d3c427

File tree

2 files changed

+127
-6
lines changed

2 files changed

+127
-6
lines changed

llvm/lib/CodeGen/LiveRangeShrink.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,24 @@ bool LiveRangeShrink::runOnMachineFunction(MachineFunction &MF) {
124124
for (MachineBasicBlock &MBB : MF) {
125125
if (MBB.empty())
126126
continue;
127-
bool SawStore = false;
128-
BuildInstOrderMap(MBB.begin(), IOM);
127+
128+
MachineBasicBlock::iterator Next = MBB.begin();
129+
if (MBB.isEHPad()) {
130+
// Do not track PHIs in IOM when handling EHPads.
131+
// Otherwise their uses may be hoisted outside a landingpad range.
132+
Next = MBB.SkipPHIsLabelsAndDebug(Next);
133+
if (Next == MBB.end())
134+
continue;
135+
}
136+
137+
BuildInstOrderMap(Next, IOM);
138+
Next = MBB.SkipPHIsLabelsAndDebug(Next);
129139
UseMap.clear();
140+
bool SawStore = false;
130141

131-
for (MachineBasicBlock::iterator Next = MBB.begin(); Next != MBB.end();) {
142+
while (Next != MBB.end()) {
132143
MachineInstr &MI = *Next;
133-
++Next;
134-
if (MI.isPHI() || MI.isDebugOrPseudoInstr())
135-
continue;
144+
Next = MBB.SkipPHIsLabelsAndDebug(++Next);
136145
if (MI.mayStore())
137146
SawStore = true;
138147

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2+
; RUN: llc -mtriple x86_64-unknown-linux-gnu %s -o - | FileCheck %s
3+
4+
declare i32 @__gxx_personality_v0(...)
5+
declare void @maythrow()
6+
declare void @cleanup(i32)
7+
8+
@external_bool = external global i1
9+
@externalA = external global i32
10+
@externalB = external global i32
11+
@externalC = external global i32
12+
@externalD = external global i32
13+
14+
define void @test() personality ptr @__gxx_personality_v0 {
15+
; CHECK-LABEL: test:
16+
; CHECK: # %bb.0:
17+
; CHECK-NEXT: pushq %rbp
18+
; CHECK-NEXT: .cfi_def_cfa_offset 16
19+
; CHECK-NEXT: pushq %r15
20+
; CHECK-NEXT: .cfi_def_cfa_offset 24
21+
; CHECK-NEXT: pushq %r14
22+
; CHECK-NEXT: .cfi_def_cfa_offset 32
23+
; CHECK-NEXT: pushq %r13
24+
; CHECK-NEXT: .cfi_def_cfa_offset 40
25+
; CHECK-NEXT: pushq %r12
26+
; CHECK-NEXT: .cfi_def_cfa_offset 48
27+
; CHECK-NEXT: pushq %rbx
28+
; CHECK-NEXT: .cfi_def_cfa_offset 56
29+
; CHECK-NEXT: pushq %rax
30+
; CHECK-NEXT: .cfi_def_cfa_offset 64
31+
; CHECK-NEXT: .cfi_offset %rbx, -56
32+
; CHECK-NEXT: .cfi_offset %r12, -48
33+
; CHECK-NEXT: .cfi_offset %r13, -40
34+
; CHECK-NEXT: .cfi_offset %r14, -32
35+
; CHECK-NEXT: .cfi_offset %r15, -24
36+
; CHECK-NEXT: .cfi_offset %rbp, -16
37+
; CHECK-NEXT: movq external_bool@GOTPCREL(%rip), %rax
38+
; CHECK-NEXT: cmpb $1, (%rax)
39+
; CHECK-NEXT: jne .LBB0_3
40+
; CHECK-NEXT: # %bb.1: # %branchA
41+
; CHECK-NEXT: movq externalA@GOTPCREL(%rip), %rax
42+
; CHECK-NEXT: movl (%rax), %eax
43+
; CHECK-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
44+
; CHECK-NEXT: movq externalC@GOTPCREL(%rip), %rax
45+
; CHECK-NEXT: movl (%rax), %eax
46+
; CHECK-NEXT: movl %eax, (%rsp) # 4-byte Spill
47+
; CHECK-NEXT: #APP
48+
; CHECK-NEXT: #NO_APP
49+
; CHECK-NEXT: .Ltmp2:
50+
; CHECK-NEXT: callq maythrow@PLT
51+
; CHECK-NEXT: .Ltmp3:
52+
; CHECK-NEXT: jmp .LBB0_4
53+
; CHECK-NEXT: .LBB0_3: # %branchB
54+
; CHECK-NEXT: movq externalB@GOTPCREL(%rip), %rax
55+
; CHECK-NEXT: movl (%rax), %eax
56+
; CHECK-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
57+
; CHECK-NEXT: movq externalD@GOTPCREL(%rip), %rax
58+
; CHECK-NEXT: movl (%rax), %eax
59+
; CHECK-NEXT: movl %eax, (%rsp) # 4-byte Spill
60+
; CHECK-NEXT: #APP
61+
; CHECK-NEXT: #NO_APP
62+
; CHECK-NEXT: .Ltmp0:
63+
; CHECK-NEXT: callq maythrow@PLT
64+
; CHECK-NEXT: .Ltmp1:
65+
; CHECK-NEXT: .LBB0_4: # %end
66+
; CHECK-NEXT: addq $8, %rsp
67+
; CHECK-NEXT: .cfi_def_cfa_offset 56
68+
; CHECK-NEXT: popq %rbx
69+
; CHECK-NEXT: .cfi_def_cfa_offset 48
70+
; CHECK-NEXT: popq %r12
71+
; CHECK-NEXT: .cfi_def_cfa_offset 40
72+
; CHECK-NEXT: popq %r13
73+
; CHECK-NEXT: .cfi_def_cfa_offset 32
74+
; CHECK-NEXT: popq %r14
75+
; CHECK-NEXT: .cfi_def_cfa_offset 24
76+
; CHECK-NEXT: popq %r15
77+
; CHECK-NEXT: .cfi_def_cfa_offset 16
78+
; CHECK-NEXT: popq %rbp
79+
; CHECK-NEXT: .cfi_def_cfa_offset 8
80+
; CHECK-NEXT: retq
81+
; CHECK-NEXT: .LBB0_2: # %lpad
82+
; CHECK-NEXT: .cfi_def_cfa_offset 64
83+
; CHECK-NEXT: .Ltmp4:
84+
; CHECK-NEXT: movq %rax, %rbx
85+
; CHECK-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
86+
; CHECK-NEXT: addl (%rsp), %edi # 4-byte Folded Reload
87+
; CHECK-NEXT: callq cleanup@PLT
88+
; CHECK-NEXT: movq %rbx, %rdi
89+
; CHECK-NEXT: callq _Unwind_Resume@PLT
90+
%1 = load i1, ptr @external_bool
91+
br i1 %1, label %branchA, label %branchB
92+
branchA:
93+
%valueA = load i32, ptr @externalA
94+
%valueC = load i32, ptr @externalC
95+
call void asm sideeffect "", "~{rbp},~{rsi},~{rdi},~{rcx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{flags}"()
96+
invoke void @maythrow() to label %end unwind label %lpad
97+
branchB:
98+
%valueB = load i32, ptr @externalB
99+
%valueD = load i32, ptr @externalD
100+
call void asm sideeffect "", "~{rbp},~{rsi},~{rdi},~{rcx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{flags}"()
101+
invoke void @maythrow() to label %end unwind label %lpad
102+
lpad:
103+
%phiValue = phi i32 [%valueA, %branchA], [%valueB, %branchB]
104+
%phiValue2 = phi i32 [%valueC, %branchA], [%valueD, %branchB]
105+
%lp = landingpad { ptr, i32 }
106+
cleanup
107+
%3 = add i32 %phiValue2, %phiValue
108+
call void @cleanup(i32 %3)
109+
resume { ptr, i32 } %lp
110+
end:
111+
ret void
112+
}

0 commit comments

Comments
 (0)