forked from OSchip/llvm-project
[X86] Fix using the SJLJ jump table on x86_64
The previous version didn't work if the jump table base address didn't fit in 32 bit, since it was encoded as an immediate offset. And in case the jump table is encoded as 32 bit label differences, we need to load and add them to the table base first. This solves the first half of the issues mentioned in PR34720. Also fix some of the errors pointed out by -verify-machineinstrs, by using GR32_NOSPRegClass. Differential Revision: https://reviews.llvm.org/D38333 llvm-svn: 314876
This commit is contained in:
parent
68ea360ed1
commit
e14145dcb0
|
@ -26653,8 +26653,8 @@ X86TargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
|
|||
SetupEntryBlockForSjLj(MI, BB, DispatchBB, FI);
|
||||
|
||||
// Create the jump table and associated information
|
||||
MachineJumpTableInfo *JTI =
|
||||
MF->getOrCreateJumpTableInfo(getJumpTableEncoding());
|
||||
unsigned JTE = getJumpTableEncoding();
|
||||
MachineJumpTableInfo *JTI = MF->getOrCreateJumpTableInfo(JTE);
|
||||
unsigned MJTI = JTI->createJumpTableIndex(LPadList);
|
||||
|
||||
const X86RegisterInfo &RI = TII->getRegisterInfo();
|
||||
|
@ -26677,7 +26677,8 @@ X86TargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
|
|||
.addRegMask(RI.getNoPreservedMask());
|
||||
}
|
||||
|
||||
unsigned IReg = MRI->createVirtualRegister(&X86::GR32RegClass);
|
||||
// IReg is used as an index in a memory operand and therefore can't be SP
|
||||
unsigned IReg = MRI->createVirtualRegister(&X86::GR32_NOSPRegClass);
|
||||
addFrameReference(BuildMI(DispatchBB, DL, TII->get(X86::MOV32rm), IReg), FI,
|
||||
Subtarget.is64Bit() ? 8 : 4);
|
||||
BuildMI(DispatchBB, DL, TII->get(X86::CMP32ri))
|
||||
|
@ -26685,13 +26686,67 @@ X86TargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
|
|||
.addImm(LPadList.size());
|
||||
BuildMI(DispatchBB, DL, TII->get(X86::JAE_1)).addMBB(TrapBB);
|
||||
|
||||
BuildMI(DispContBB, DL,
|
||||
TII->get(Subtarget.is64Bit() ? X86::JMP64m : X86::JMP32m))
|
||||
.addReg(0)
|
||||
.addImm(Subtarget.is64Bit() ? 8 : 4)
|
||||
.addReg(IReg)
|
||||
.addJumpTableIndex(MJTI)
|
||||
.addReg(0);
|
||||
if (Subtarget.is64Bit()) {
|
||||
unsigned BReg = MRI->createVirtualRegister(&X86::GR64RegClass);
|
||||
unsigned IReg64 = MRI->createVirtualRegister(&X86::GR64_NOSPRegClass);
|
||||
|
||||
// leaq .LJTI0_0(%rip), BReg
|
||||
BuildMI(DispContBB, DL, TII->get(X86::LEA64r), BReg)
|
||||
.addReg(X86::RIP)
|
||||
.addImm(1)
|
||||
.addReg(0)
|
||||
.addJumpTableIndex(MJTI)
|
||||
.addReg(0);
|
||||
// movzx IReg64, IReg
|
||||
BuildMI(DispContBB, DL, TII->get(TargetOpcode::SUBREG_TO_REG), IReg64)
|
||||
.addImm(0)
|
||||
.addReg(IReg)
|
||||
.addImm(X86::sub_32bit);
|
||||
|
||||
switch (JTE) {
|
||||
case MachineJumpTableInfo::EK_BlockAddress:
|
||||
// jmpq *(BReg,IReg64,8)
|
||||
BuildMI(DispContBB, DL, TII->get(X86::JMP64m))
|
||||
.addReg(BReg)
|
||||
.addImm(8)
|
||||
.addReg(IReg64)
|
||||
.addImm(0)
|
||||
.addReg(0);
|
||||
break;
|
||||
case MachineJumpTableInfo::EK_LabelDifference32: {
|
||||
unsigned OReg = MRI->createVirtualRegister(&X86::GR32RegClass);
|
||||
unsigned OReg64 = MRI->createVirtualRegister(&X86::GR64RegClass);
|
||||
unsigned TReg = MRI->createVirtualRegister(&X86::GR64RegClass);
|
||||
|
||||
// movl (BReg,IReg64,4), OReg
|
||||
BuildMI(DispContBB, DL, TII->get(X86::MOV32rm), OReg)
|
||||
.addReg(BReg)
|
||||
.addImm(4)
|
||||
.addReg(IReg64)
|
||||
.addImm(0)
|
||||
.addReg(0);
|
||||
// movsx OReg64, OReg
|
||||
BuildMI(DispContBB, DL, TII->get(X86::MOVSX64rr32), OReg64).addReg(OReg);
|
||||
// addq BReg, OReg64, TReg
|
||||
BuildMI(DispContBB, DL, TII->get(X86::ADD64rr), TReg)
|
||||
.addReg(OReg64)
|
||||
.addReg(BReg);
|
||||
// jmpq *TReg
|
||||
BuildMI(DispContBB, DL, TII->get(X86::JMP64r)).addReg(TReg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("Unexpected jump table encoding");
|
||||
}
|
||||
} else {
|
||||
// jmpl *.LJTI0_0(,IReg,4)
|
||||
BuildMI(DispContBB, DL, TII->get(X86::JMP32m))
|
||||
.addReg(0)
|
||||
.addImm(4)
|
||||
.addReg(IReg)
|
||||
.addJumpTableIndex(MJTI)
|
||||
.addReg(0);
|
||||
}
|
||||
|
||||
// Add the jump table entries as successors to the MBB.
|
||||
SmallPtrSet<MachineBasicBlock *, 8> SeenMBBs;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
; RUN: llc -mtriple i386-windows-gnu -exception-model sjlj -filetype asm -o - %s | FileCheck %s
|
||||
; RUN: llc -mtriple x86_64-windows-gnu -exception-model sjlj -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-X64
|
||||
; RUN: llc -mtriple x86_64-linux -exception-model sjlj -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-X64-LINUX
|
||||
|
||||
declare void @_Z20function_that_throwsv()
|
||||
declare i32 @__gxx_personality_sj0(...)
|
||||
|
@ -116,4 +117,19 @@ try.cont:
|
|||
; CHECK-X64: ud2
|
||||
; CHECK-X64: [[CONT]]:
|
||||
; *Handlers[UFC.__callsite]
|
||||
; CHECK-X64: jmpq *.LJTI
|
||||
; CHECK-X64: leaq .[[TABLE:LJTI[0-9]+_[0-9]+]](%rip), %rcx
|
||||
; CHECK-X64: movl (%rcx,%rax,4), %eax
|
||||
; CHECK-X64: cltq
|
||||
; CHECK-X64: addq %rcx, %rax
|
||||
; CHECK-X64: jmpq *%rax
|
||||
|
||||
; CHECK-X64-LINUX: .[[RESUME:LBB[0-9]+_[0-9]+]]:
|
||||
; assert(UFC.__callsite < 1);
|
||||
; CHECK-X64-LINUX: movl -120(%rbp), %eax
|
||||
; CHECK-X64-LINUX: cmpl $1, %eax
|
||||
; CHECK-X64-LINUX: jb .[[CONT:LBB[0-9]+_[0-9]+]]
|
||||
; CHECK-X64-LINUX: ud2
|
||||
; CHECK-X64-LINUX: [[CONT]]:
|
||||
; *Handlers[UFC.__callsite]
|
||||
; CHECK-X64-LINUX: leaq .[[TABLE:LJTI[0-9]+_[0-9]+]](%rip), %rcx
|
||||
; CHECK-X64-LINUX: jmpq *(%rcx,%rax,8)
|
||||
|
|
Loading…
Reference in New Issue