Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -26544,8 +26544,8 @@ 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(); @@ -26568,7 +26568,7 @@ .addRegMask(RI.getNoPreservedMask()); } - unsigned IReg = MRI->createVirtualRegister(&X86::GR32RegClass); + 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)) @@ -26576,13 +26576,54 @@ .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 Base = MRI->createVirtualRegister(&X86::GR64RegClass); + unsigned IReg64 = MRI->createVirtualRegister(&X86::GR64_NOSPRegClass); + + BuildMI(DispContBB, DL, TII->get(X86::LEA64r), Base) + .addReg(X86::RIP) + .addImm(1) + .addReg(0) + .addJumpTableIndex(MJTI) + .addReg(0); + BuildMI(DispContBB, DL, TII->get(TargetOpcode::SUBREG_TO_REG), IReg64) + .addImm(0) + .addReg(IReg) + .addImm(X86::sub_32bit); + + if (JTE == MachineJumpTableInfo::EK_BlockAddress) { + BuildMI(DispContBB, DL, TII->get(X86::JMP64m)) + .addReg(Base) + .addImm(8) + .addReg(IReg64) + .addImm(0) + .addReg(0); + } else { + assert(JTE == MachineJumpTableInfo::EK_LabelDifference32); + unsigned Offset = MRI->createVirtualRegister(&X86::GR32RegClass); + unsigned Offset64 = MRI->createVirtualRegister(&X86::GR64RegClass); + unsigned TargetAddr = MRI->createVirtualRegister(&X86::GR64RegClass); + BuildMI(DispContBB, DL, TII->get(X86::MOV32rm), Offset) + .addReg(Base) + .addImm(4) + .addReg(IReg64) + .addImm(0) + .addReg(0); + BuildMI(DispContBB, DL, TII->get(X86::MOVSX64rr32), Offset64) + .addReg(Offset); + BuildMI(DispContBB, DL, TII->get(X86::ADD64rr), TargetAddr) + .addReg(Offset64) + .addReg(Base); + BuildMI(DispContBB, DL, TII->get(X86::JMP64r)).addReg(TargetAddr); + } + } else { + BuildMI(DispContBB, DL, TII->get(X86::JMP32m)) + .addReg(0) + .addImm(Subtarget.is64Bit() ? 8 : 4) + .addReg(IReg) + .addJumpTableIndex(MJTI) + .addReg(0); + } // Add the jump table entries as successors to the MBB. SmallPtrSet SeenMBBs; Index: test/CodeGen/X86/sjlj-eh.ll =================================================================== --- test/CodeGen/X86/sjlj-eh.ll +++ test/CodeGen/X86/sjlj-eh.ll @@ -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,11 @@ ; 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: leaq .[[TABLE:LJTI[0-9]+_[0-9]+]](%rip), %rcx +; CHECK-X64-LINUX: jmpq *(%rcx,%rax,8)