Skip to content

Commit

Permalink
[CodeGen] Use first EHLabel as a stop gate for live range shrinking
Browse files Browse the repository at this point in the history
This fixes issue llvm#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.
  • Loading branch information
MuellerMP committed Oct 31, 2024
1 parent f358422 commit 9565132
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 2 deletions.
9 changes: 7 additions & 2 deletions llvm/lib/CodeGen/LiveRangeShrink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,15 @@ bool LiveRangeShrink::runOnMachineFunction(MachineFunction &MF) {
if (MBB.empty())
continue;
bool SawStore = false;
BuildInstOrderMap(MBB.begin(), IOM);
MachineBasicBlock::iterator Next = MBB.begin();
if (MBB.isEHPad())
Next = MBB.SkipPHIsLabelsAndDebug(Next);
if (Next == MBB.end())
continue;
BuildInstOrderMap(Next, IOM);
UseMap.clear();

for (MachineBasicBlock::iterator Next = MBB.begin(); Next != MBB.end();) {
while (Next != MBB.end()) {
MachineInstr &MI = *Next;
++Next;
if (MI.isPHI() || MI.isDebugOrPseudoInstr())
Expand Down
112 changes: 112 additions & 0 deletions llvm/test/CodeGen/X86/lrshrink-ehpad-phis.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
; RUN: llc -mtriple x86_64-unknown-linux-gnu %s -o - | FileCheck %s

declare i32 @__gxx_personality_v0(...)
declare void @maythrow()
declare void @cleanup(i32)

@external_bool = external global i1
@externalA = external global i32
@externalB = external global i32
@externalC = external global i32
@externalD = external global i32

define void @test() personality ptr @__gxx_personality_v0 {
; CHECK-LABEL: test:
; CHECK: # %bb.0:
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: pushq %r15
; CHECK-NEXT: .cfi_def_cfa_offset 24
; CHECK-NEXT: pushq %r14
; CHECK-NEXT: .cfi_def_cfa_offset 32
; CHECK-NEXT: pushq %r13
; CHECK-NEXT: .cfi_def_cfa_offset 40
; CHECK-NEXT: pushq %r12
; CHECK-NEXT: .cfi_def_cfa_offset 48
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: .cfi_def_cfa_offset 56
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: .cfi_def_cfa_offset 64
; CHECK-NEXT: .cfi_offset %rbx, -56
; CHECK-NEXT: .cfi_offset %r12, -48
; CHECK-NEXT: .cfi_offset %r13, -40
; CHECK-NEXT: .cfi_offset %r14, -32
; CHECK-NEXT: .cfi_offset %r15, -24
; CHECK-NEXT: .cfi_offset %rbp, -16
; CHECK-NEXT: movq external_bool@GOTPCREL(%rip), %rax
; CHECK-NEXT: cmpb $1, (%rax)
; CHECK-NEXT: jne .LBB0_3
; CHECK-NEXT: # %bb.1: # %branchA
; CHECK-NEXT: movq externalA@GOTPCREL(%rip), %rax
; CHECK-NEXT: movl (%rax), %eax
; CHECK-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
; CHECK-NEXT: movq externalC@GOTPCREL(%rip), %rax
; CHECK-NEXT: movl (%rax), %eax
; CHECK-NEXT: movl %eax, (%rsp) # 4-byte Spill
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: .Ltmp2:
; CHECK-NEXT: callq maythrow@PLT
; CHECK-NEXT: .Ltmp3:
; CHECK-NEXT: jmp .LBB0_4
; CHECK-NEXT: .LBB0_3: # %branchB
; CHECK-NEXT: movq externalB@GOTPCREL(%rip), %rax
; CHECK-NEXT: movl (%rax), %eax
; CHECK-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
; CHECK-NEXT: movq externalD@GOTPCREL(%rip), %rax
; CHECK-NEXT: movl (%rax), %eax
; CHECK-NEXT: movl %eax, (%rsp) # 4-byte Spill
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: .Ltmp0:
; CHECK-NEXT: callq maythrow@PLT
; CHECK-NEXT: .Ltmp1:
; CHECK-NEXT: .LBB0_4: # %end
; CHECK-NEXT: addq $8, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 56
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: .cfi_def_cfa_offset 48
; CHECK-NEXT: popq %r12
; CHECK-NEXT: .cfi_def_cfa_offset 40
; CHECK-NEXT: popq %r13
; CHECK-NEXT: .cfi_def_cfa_offset 32
; CHECK-NEXT: popq %r14
; CHECK-NEXT: .cfi_def_cfa_offset 24
; CHECK-NEXT: popq %r15
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB0_2: # %lpad
; CHECK-NEXT: .cfi_def_cfa_offset 64
; CHECK-NEXT: .Ltmp4:
; CHECK-NEXT: movq %rax, %rbx
; CHECK-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
; CHECK-NEXT: addl (%rsp), %edi # 4-byte Folded Reload
; CHECK-NEXT: callq cleanup@PLT
; CHECK-NEXT: movq %rbx, %rdi
; CHECK-NEXT: callq _Unwind_Resume@PLT
%1 = load i1, ptr @external_bool
br i1 %1, label %branchA, label %branchB
branchA:
%valueA = load i32, ptr @externalA
%valueC = load i32, ptr @externalC
call void asm sideeffect "", "~{rbp},~{rsi},~{rdi},~{rcx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{flags}"()
invoke void @maythrow() to label %end unwind label %lpad
branchB:
%valueB = load i32, ptr @externalB
%valueD = load i32, ptr @externalD
call void asm sideeffect "", "~{rbp},~{rsi},~{rdi},~{rcx},~{rbx},~{r12},~{r13},~{r14},~{r15},~{flags}"()
invoke void @maythrow() to label %end unwind label %lpad
lpad:
%phiValue = phi i32 [%valueA, %branchA], [%valueB, %branchB]
%phiValue2 = phi i32 [%valueC, %branchA], [%valueD, %branchB]
%lp = landingpad { ptr, i32 }
cleanup
%3 = add i32 %phiValue2, %phiValue
call void @cleanup(i32 %3)
resume { ptr, i32 } %lp
end:
ret void
}

0 comments on commit 9565132

Please sign in to comment.