forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CodeGen] Use first EHLabel as a stop gate for live range shrinking
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
Showing
2 changed files
with
119 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |