Skip to content

Commit b5f35ec

Browse files
committed
[X86] Implement TargetRegisterInfo::getCustomEHPadPreservedMask
This method needs to be implemented so that the register allocator can correctly split live ranges of loop invariant virtual registers. This default return value is correct for DWARF unwinder, which preserves all registers (except exception pointer/selector), but not for SjLj, which only preserves sp/fp and possibly bp (they should be reserved). In the added test `rcx` on the entry to the loop contains the argument to `foo`. It survives the call due to `preserve_allcc`, but not the unwind edge entering LBB0_3, and so must be recomputed before going to the next iteration. Similarly, `rdx` holds the address of a jump table and is recomputed on every iteration rather than once before the loop.
1 parent 46745b0 commit b5f35ec

File tree

3 files changed

+18
-7
lines changed

3 files changed

+18
-7
lines changed

llvm/lib/Target/X86/X86RegisterInfo.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,13 @@ X86RegisterInfo::getNoPreservedMask() const {
525525
return CSR_NoRegs_RegMask;
526526
}
527527

528+
const uint32_t *
529+
X86RegisterInfo::getCustomEHPadPreservedMask(const MachineFunction &MF) const {
530+
if (MF.getTarget().Options.ExceptionModel == ExceptionHandling::SjLj)
531+
return getNoPreservedMask();
532+
return TargetRegisterInfo::getCustomEHPadPreservedMask(MF);
533+
}
534+
528535
const uint32_t *X86RegisterInfo::getDarwinTLSCallPreservedMask() const {
529536
return CSR_64_TLS_Darwin_RegMask;
530537
}

llvm/lib/Target/X86/X86RegisterInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ class X86RegisterInfo final : public X86GenRegisterInfo {
102102
const uint32_t *getCallPreservedMask(const MachineFunction &MF,
103103
CallingConv::ID) const override;
104104
const uint32_t *getNoPreservedMask() const override;
105+
const uint32_t *
106+
getCustomEHPadPreservedMask(const MachineFunction &MF) const override;
105107

106108
// Calls involved in thread-local variable lookup save more registers than
107109
// normal calls, so they need a different mask to represent this.

llvm/test/CodeGen/X86/sjlj-unwind-clobber.ll

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,28 @@ define void @test() personality ptr @__gxx_personality_sj0 {
2222
; CHECK-NEXT: movq $.LBB0_3, -80(%rbp)
2323
; CHECK-NEXT: leaq -136(%rbp), %rdi
2424
; CHECK-NEXT: callq _Unwind_SjLj_Register@PLT
25-
; CHECK-NEXT: leaq -44(%rbp), %rdi
26-
; CHECK-NEXT: leaq .LJTI0_0(%rip), %rax
25+
; CHECK-NEXT: leaq -44(%rbp), %rcx
2726
; CHECK-NEXT: .LBB0_1: # %while.cond
2827
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
2928
; CHECK-NEXT: movl $1, -128(%rbp)
3029
; CHECK-NEXT: .Ltmp0:
30+
; CHECK-NEXT: movq %rcx, %rdi
3131
; CHECK-NEXT: callq foo
3232
; CHECK-NEXT: .Ltmp1:
3333
; CHECK-NEXT: jmp .LBB0_2
3434
; CHECK-NEXT: .LBB0_3: # in Loop: Header=BB0_1 Depth=1
35-
; CHECK-NEXT: movl -128(%rbp), %ecx
36-
; CHECK-NEXT: cmpl $1, %ecx
35+
; CHECK-NEXT: leaq -44(%rbp), %rcx
36+
; CHECK-NEXT: movl -128(%rbp), %eax
37+
; CHECK-NEXT: cmpl $1, %eax
3738
; CHECK-NEXT: jae .LBB0_5
3839
; CHECK-NEXT: # %bb.4: # in Loop: Header=BB0_1 Depth=1
39-
; CHECK-NEXT: jmpq *(%rax,%rcx,8)
40+
; CHECK-NEXT: leaq .LJTI0_0(%rip), %rdx
41+
; CHECK-NEXT: jmpq *(%rdx,%rax,8)
4042
; CHECK-NEXT: .LBB0_6: # %lpad
4143
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
4244
; CHECK-NEXT: .Ltmp2:
43-
; CHECK-NEXT: movl -124(%rbp), %ecx
44-
; CHECK-NEXT: movl -120(%rbp), %ecx
45+
; CHECK-NEXT: movl -124(%rbp), %eax
46+
; CHECK-NEXT: movl -120(%rbp), %eax
4547
; CHECK-NEXT: jmp .LBB0_1
4648
; CHECK-NEXT: .LBB0_2: # %while.end
4749
; CHECK-NEXT: leaq -136(%rbp), %rdi

0 commit comments

Comments
 (0)