From: Joseph Tremoulet Date: Sat, 7 Nov 2015 01:11:31 +0000 (+0000) Subject: [WinEH] Update exception pointer registers X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=de9bf0f80e8262b0eae2e826a35dde0a346391e4 [WinEH] Update exception pointer registers Summary: The CLR's personality routine passes these in rdx/edx, not rax/eax. Make getExceptionPointerRegister a virtual method parameterized by personality function to allow making this distinction. Similarly make getExceptionSelectorRegister a virtual method parameterized by personality function, for symmetry. Reviewers: pgavlin, majnemer, rnk Subscribers: jyknight, dsanders, llvm-commits Differential Revision: http://reviews.llvm.org/D14344 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252383 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index e17682f704e..d1770968d43 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -939,15 +939,19 @@ public: } /// If a physical register, this returns the register that receives the - /// exception address on entry to a landing pad. - unsigned getExceptionPointerRegister() const { - return ExceptionPointerRegister; + /// exception address on entry to an EH pad. + virtual unsigned + getExceptionPointerRegister(const Constant *PersonalityFn) const { + // 0 is guaranteed to be the NoRegister value on all targets + return 0; } /// If a physical register, this returns the register that receives the /// exception typeid on entry to a landing pad. - unsigned getExceptionSelectorRegister() const { - return ExceptionSelectorRegister; + virtual unsigned + getExceptionSelectorRegister(const Constant *PersonalityFn) const { + // 0 is guaranteed to be the NoRegister value on all targets + return 0; } /// Returns the target's jmp_buf size in bytes (if never set, the default is @@ -1228,18 +1232,6 @@ protected: StackPointerRegisterToSaveRestore = R; } - /// If set to a physical register, this sets the register that receives the - /// exception address on entry to a landing pad. - void setExceptionPointerRegister(unsigned R) { - ExceptionPointerRegister = R; - } - - /// If set to a physical register, this sets the register that receives the - /// exception typeid on entry to a landing pad. - void setExceptionSelectorRegister(unsigned R) { - ExceptionSelectorRegister = R; - } - /// Tells the code generator not to expand operations into sequences that use /// the select operations if possible. void setSelectIsExpensive(bool isExpensive = true) { @@ -1856,14 +1848,6 @@ private: /// llvm.savestack/llvm.restorestack should save and restore. unsigned StackPointerRegisterToSaveRestore; - /// If set to a physical register, this specifies the register that receives - /// the exception address on entry to a landing pad. - unsigned ExceptionPointerRegister; - - /// If set to a physical register, this specifies the register that receives - /// the exception typeid on entry to a landing pad. - unsigned ExceptionSelectorRegister; - /// This indicates the default register class to use for each ValueType the /// target supports natively. const TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE]; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 75b2960bb37..2f5e329c95b 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2184,8 +2184,9 @@ void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) { // If there aren't registers to copy the values into (e.g., during SjLj // exceptions), then don't bother to create these DAG nodes. const TargetLowering &TLI = DAG.getTargetLoweringInfo(); - if (TLI.getExceptionPointerRegister() == 0 && - TLI.getExceptionSelectorRegister() == 0) + const Constant *PersonalityFn = FuncInfo.Fn->getPersonalityFn(); + if (TLI.getExceptionPointerRegister(PersonalityFn) == 0 && + TLI.getExceptionSelectorRegister(PersonalityFn) == 0) return; SmallVector ValueVTs; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index a9113252abb..04895e7702f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -938,6 +938,7 @@ static bool hasExceptionPointerOrCodeUser(const CatchPadInst *CPI) { /// do other setup for EH landing-pad blocks. bool SelectionDAGISel::PrepareEHLandingPad() { MachineBasicBlock *MBB = FuncInfo->MBB; + const Constant *PersonalityFn = FuncInfo->Fn->getPersonalityFn(); const BasicBlock *LLVMBB = MBB->getBasicBlock(); const TargetRegisterClass *PtrRC = TLI->getRegClassFor(TLI->getPointerTy(CurDAG->getDataLayout())); @@ -948,7 +949,7 @@ bool SelectionDAGISel::PrepareEHLandingPad() { if (hasExceptionPointerOrCodeUser(CPI)) { // Get or create the virtual register to hold the pointer or code. Mark // the live in physreg and copy into the vreg. - MCPhysReg EHPhysReg = TLI->getExceptionPointerRegister(); + MCPhysReg EHPhysReg = TLI->getExceptionPointerRegister(PersonalityFn); assert(EHPhysReg && "target lacks exception pointer register"); MBB->addLiveIn(EHPhysReg); unsigned VReg = FuncInfo->getCatchPadExceptionPointerVReg(CPI, PtrRC); @@ -974,11 +975,11 @@ bool SelectionDAGISel::PrepareEHLandingPad() { .addSym(Label); // Mark exception register as live in. - if (unsigned Reg = TLI->getExceptionPointerRegister()) + if (unsigned Reg = TLI->getExceptionPointerRegister(PersonalityFn)) FuncInfo->ExceptionPointerVirtReg = MBB->addLiveIn(Reg, PtrRC); // Mark exception selector register as live in. - if (unsigned Reg = TLI->getExceptionSelectorRegister()) + if (unsigned Reg = TLI->getExceptionSelectorRegister(PersonalityFn)) FuncInfo->ExceptionSelectorVirtReg = MBB->addLiveIn(Reg, PtrRC); return true; diff --git a/lib/CodeGen/TargetLoweringBase.cpp b/lib/CodeGen/TargetLoweringBase.cpp index ece2e395c3d..24bdef3040e 100644 --- a/lib/CodeGen/TargetLoweringBase.cpp +++ b/lib/CodeGen/TargetLoweringBase.cpp @@ -765,8 +765,6 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm) : TM(tm) { EnableExtLdPromotion = false; HasFloatingPointExceptions = true; StackPointerRegisterToSaveRestore = 0; - ExceptionPointerRegister = 0; - ExceptionSelectorRegister = 0; BooleanContents = UndefinedBooleanContent; BooleanFloatContents = UndefinedBooleanContent; BooleanVectorContents = UndefinedBooleanContent; diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 428624cd894..77dfb8afe3f 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -196,11 +196,6 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM, setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand); - // Exception handling. - // FIXME: These are guesses. Has this been defined yet? - setExceptionPointerRegister(AArch64::X0); - setExceptionSelectorRegister(AArch64::X1); - // Constant pool entries setOperationAction(ISD::ConstantPool, MVT::i64, Custom); diff --git a/lib/Target/AArch64/AArch64ISelLowering.h b/lib/Target/AArch64/AArch64ISelLowering.h index 64a2934d1d5..7c10cb11669 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.h +++ b/lib/Target/AArch64/AArch64ISelLowering.h @@ -15,6 +15,7 @@ #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64ISELLOWERING_H #define LLVM_LIB_TARGET_AARCH64_AARCH64ISELLOWERING_H +#include "AArch64.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/IR/CallingConv.h" @@ -366,6 +367,22 @@ public: /// returns the address of that location. Otherwise, returns nullptr. Value *getSafeStackPointerLocation(IRBuilder<> &IRB) const override; + /// If a physical register, this returns the register that receives the + /// exception address on entry to an EH pad. + unsigned + getExceptionPointerRegister(const Constant *PersonalityFn) const override { + // FIXME: This is a guess. Has this been defined yet? + return AArch64::X0; + } + + /// If a physical register, this returns the register that receives the + /// exception typeid on entry to a landing pad. + unsigned + getExceptionSelectorRegister(const Constant *PersonalityFn) const override { + // FIXME: This is a guess. Has this been defined yet? + return AArch64::X1; + } + private: bool isExtFreeImpl(const Instruction *Ext) const override; diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 992902d6f6e..da8ecfa1102 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -813,13 +813,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); - if (!Subtarget->useSjLjEH()) { - // Platforms which do not use SjLj EH may return values in these registers - // via the personality function. - setExceptionPointerRegister(ARM::R0); - setExceptionSelectorRegister(ARM::R1); - } - if (Subtarget->getTargetTriple().isWindowsItaniumEnvironment()) setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom); else @@ -12147,3 +12140,17 @@ bool ARMTargetLowering::functionArgumentNeedsConsecutiveRegisters( bool IsIntArray = Ty->isArrayTy() && Ty->getArrayElementType()->isIntegerTy(); return IsHA || IsIntArray; } + +unsigned ARMTargetLowering::getExceptionPointerRegister( + const Constant *PersonalityFn) const { + // Platforms which do not use SjLj EH may return values in these registers + // via the personality function. + return Subtarget->useSjLjEH() ? ARM::NoRegister : ARM::R0; +} + +unsigned ARMTargetLowering::getExceptionSelectorRegister( + const Constant *PersonalityFn) const { + // Platforms which do not use SjLj EH may return values in these registers + // via the personality function. + return Subtarget->useSjLjEH() ? ARM::NoRegister : ARM::R1; +} diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 852a36b0c12..534f92b941c 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -423,6 +423,16 @@ namespace llvm { bool functionArgumentNeedsConsecutiveRegisters( Type *Ty, CallingConv::ID CallConv, bool isVarArg) const override; + /// If a physical register, this returns the register that receives the + /// exception address on entry to an EH pad. + unsigned + getExceptionPointerRegister(const Constant *PersonalityFn) const override; + + /// If a physical register, this returns the register that receives the + /// exception typeid on entry to a landing pad. + unsigned + getExceptionSelectorRegister(const Constant *PersonalityFn) const override; + Instruction *makeDMB(IRBuilder<> &Builder, ARM_MB::MemBOpt Domain) const; Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr, AtomicOrdering Ord) const override; diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp index 4ebc596b34a..564eb1fa6fa 100644 --- a/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -1286,8 +1286,6 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, setPrefFunctionAlignment(4); setMinFunctionAlignment(2); setInsertFencesForAtomic(false); - setExceptionPointerRegister(Hexagon::R0); - setExceptionSelectorRegister(Hexagon::R1); setStackPointerRegisterToSaveRestore(HRI.getStackRegister()); if (EnableHexSDNodeSched) diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h index 2987cc252e0..80ab2ce9970 100644 --- a/lib/Target/Hexagon/HexagonISelLowering.h +++ b/lib/Target/Hexagon/HexagonISelLowering.h @@ -163,6 +163,20 @@ bool isPositiveHalfWord(SDNode *N); MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const override; + /// If a physical register, this returns the register that receives the + /// exception address on entry to an EH pad. + unsigned + getExceptionPointerRegister(const Constant *PersonalityFn) const override { + return Hexagon::R0; + } + + /// If a physical register, this returns the register that receives the + /// exception typeid on entry to a landing pad. + unsigned + getExceptionSelectorRegister(const Constant *PersonalityFn) const override { + return Hexagon::R1; + } + SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; EVT getSetCCResultType(const DataLayout &, LLVMContext &C, diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 75dc2f1e0f3..66c495bc3e9 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -438,9 +438,6 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM, setStackPointerRegisterToSaveRestore(ABI.IsN64() ? Mips::SP_64 : Mips::SP); - setExceptionPointerRegister(ABI.IsN64() ? Mips::A0_64 : Mips::A0); - setExceptionSelectorRegister(ABI.IsN64() ? Mips::A1_64 : Mips::A1); - MaxStoresPerMemcpy = 16; isMicroMips = Subtarget.inMicroMipsMode(); diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 85462275edb..8e2cb0b4a6c 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -267,6 +267,20 @@ namespace llvm { unsigned getRegisterByName(const char* RegName, EVT VT, SelectionDAG &DAG) const override; + /// If a physical register, this returns the register that receives the + /// exception address on entry to an EH pad. + unsigned + getExceptionPointerRegister(const Constant *PersonalityFn) const override { + return ABI.IsN64() ? Mips::A0_64 : Mips::A0; + } + + /// If a physical register, this returns the register that receives the + /// exception typeid on entry to a landing pad. + unsigned + getExceptionSelectorRegister(const Constant *PersonalityFn) const override { + return ABI.IsN64() ? Mips::A1_64 : Mips::A1; + } + /// Returns true if a cast between SrcAS and DestAS is a noop. bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override { // Mips doesn't have any special address spaces so we just reserve diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index f4919dd9acc..8a4dd5fab3d 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -827,15 +827,7 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM, setLibcallName(RTLIB::SRA_I128, nullptr); } - if (isPPC64) { - setStackPointerRegisterToSaveRestore(PPC::X1); - setExceptionPointerRegister(PPC::X3); - setExceptionSelectorRegister(PPC::X4); - } else { - setStackPointerRegisterToSaveRestore(PPC::R1); - setExceptionPointerRegister(PPC::R3); - setExceptionSelectorRegister(PPC::R4); - } + setStackPointerRegisterToSaveRestore(isPPC64 ? PPC::X1 : PPC::R1); // We have target-specific dag combine patterns for the following nodes: setTargetDAGCombine(ISD::SINT_TO_FP); @@ -11532,6 +11524,16 @@ PPCTargetLowering::getScratchRegisters(CallingConv::ID) const { return ScratchRegs; } +unsigned PPCTargetLowering::getExceptionPointerRegister( + const Constant *PersonalityFn) const { + return Subtarget.isPPC64() ? PPC::X3 : PPC::R3; +} + +unsigned PPCTargetLowering::getExceptionSelectorRegister( + const Constant *PersonalityFn) const { + return Subtarget.isPPC64() ? PPC::X4 : PPC::R4; +} + bool PPCTargetLowering::shouldExpandBuildVectorWithShuffles( EVT VT , unsigned DefinedValues) const { diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index cbd5add8488..415c47c286e 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -655,8 +655,17 @@ namespace llvm { return Ty->isArrayTy(); } - private: + /// If a physical register, this returns the register that receives the + /// exception address on entry to an EH pad. + unsigned + getExceptionPointerRegister(const Constant *PersonalityFn) const override; + /// If a physical register, this returns the register that receives the + /// exception typeid on entry to a landing pad. + unsigned + getExceptionSelectorRegister(const Constant *PersonalityFn) const override; + + private: struct ReuseLoadInfo { SDValue Ptr; SDValue Chain; diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index 6138f54352a..c496a3c5a11 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -1674,9 +1674,6 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM, setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Custom); - setExceptionPointerRegister(SP::I0); - setExceptionSelectorRegister(SP::I1); - setStackPointerRegisterToSaveRestore(SP::O6); setOperationAction(ISD::CTPOP, MVT::i32, diff --git a/lib/Target/Sparc/SparcISelLowering.h b/lib/Target/Sparc/SparcISelLowering.h index 6786b9e3cd3..4e46709cfc0 100644 --- a/lib/Target/Sparc/SparcISelLowering.h +++ b/lib/Target/Sparc/SparcISelLowering.h @@ -89,6 +89,20 @@ namespace llvm { return MVT::i32; } + /// If a physical register, this returns the register that receives the + /// exception address on entry to an EH pad. + unsigned + getExceptionPointerRegister(const Constant *PersonalityFn) const override { + return SP::I0; + } + + /// If a physical register, this returns the register that receives the + /// exception typeid on entry to a landing pad. + unsigned + getExceptionSelectorRegister(const Constant *PersonalityFn) const override { + return SP::I1; + } + /// getSetCCResultType - Return the ISD::SETCC ValueType EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override; diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index b3e2340fee8..f598bc0189d 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -114,8 +114,6 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM, computeRegisterProperties(Subtarget.getRegisterInfo()); // Set up special registers. - setExceptionPointerRegister(SystemZ::R6D); - setExceptionSelectorRegister(SystemZ::R7D); setStackPointerRegisterToSaveRestore(SystemZ::R15D); // TODO: It may be better to default to latency-oriented scheduling, however diff --git a/lib/Target/SystemZ/SystemZISelLowering.h b/lib/Target/SystemZ/SystemZISelLowering.h index 8a2839acd24..391636e5467 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.h +++ b/lib/Target/SystemZ/SystemZISelLowering.h @@ -409,6 +409,20 @@ public: return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); } + /// If a physical register, this returns the register that receives the + /// exception address on entry to an EH pad. + unsigned + getExceptionPointerRegister(const Constant *PersonalityFn) const override { + return SystemZ::R6D; + } + + /// If a physical register, this returns the register that receives the + /// exception typeid on entry to a landing pad. + unsigned + getExceptionSelectorRegister(const Constant *PersonalityFn) const override { + return SystemZ::R7D; + } + MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const override; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 672ecc50103..f5efd58e7a3 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -25,6 +25,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Analysis/LibCallSemantics.h" #include "llvm/CodeGen/IntrinsicLowering.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -476,13 +477,6 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, setOperationAction(ISD::EH_LABEL, MVT::Other, Expand); } - if (Subtarget->isTarget64BitLP64()) { - setExceptionPointerRegister(X86::RAX); - setExceptionSelectorRegister(X86::RDX); - } else { - setExceptionPointerRegister(X86::EAX); - setExceptionSelectorRegister(X86::EDX); - } setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i32, Custom); setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i64, Custom); @@ -17246,6 +17240,21 @@ SDValue X86TargetLowering::LowerFRAME_TO_ARGS_OFFSET(SDValue Op, return DAG.getIntPtrConstant(2 * RegInfo->getSlotSize(), SDLoc(Op)); } +unsigned X86TargetLowering::getExceptionPointerRegister( + const Constant *PersonalityFn) const { + if (classifyEHPersonality(PersonalityFn) == EHPersonality::CoreCLR) + return Subtarget->isTarget64BitLP64() ? X86::RDX : X86::EDX; + + return Subtarget->isTarget64BitLP64() ? X86::RAX : X86::EAX; +} + +unsigned X86TargetLowering::getExceptionSelectorRegister( + const Constant *PersonalityFn) const { + // Funclet personalities don't use selectors (the runtime does the selection). + assert(!isFuncletEHPersonality(classifyEHPersonality(PersonalityFn))); + return Subtarget->isTarget64BitLP64() ? X86::RDX : X86::EDX; +} + SDValue X86TargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); SDValue Offset = Op.getOperand(1); diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 6bd7ef9a3b5..e7dbaa995c8 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -889,6 +889,16 @@ namespace llvm { unsigned getRegisterByName(const char* RegName, EVT VT, SelectionDAG &DAG) const override; + /// If a physical register, this returns the register that receives the + /// exception address on entry to an EH pad. + unsigned + getExceptionPointerRegister(const Constant *PersonalityFn) const override; + + /// If a physical register, this returns the register that receives the + /// exception typeid on entry to a landing pad. + unsigned + getExceptionSelectorRegister(const Constant *PersonalityFn) const override; + /// This method returns a target specific FastISel object, /// or null if the target does not support "fast" ISel. FastISel *createFastISel(FunctionLoweringInfo &funcInfo, diff --git a/lib/Target/XCore/XCoreFrameLowering.cpp b/lib/Target/XCore/XCoreFrameLowering.cpp index f7c6159e3e1..ae493de083b 100644 --- a/lib/Target/XCore/XCoreFrameLowering.cpp +++ b/lib/Target/XCore/XCoreFrameLowering.cpp @@ -160,19 +160,19 @@ static void GetSpillList(SmallVectorImpl &SpillList, /// As offsets are negative, the largest offsets will be first. static void GetEHSpillList(SmallVectorImpl &SpillList, MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, + const Constant *PersonalityFn, const TargetLowering *TL) { assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots"); - const int* EHSlot = XFI->getEHSpillSlot(); - SpillList.push_back(StackSlotInfo(EHSlot[0], - MFI->getObjectOffset(EHSlot[0]), - TL->getExceptionPointerRegister())); - SpillList.push_back(StackSlotInfo(EHSlot[0], - MFI->getObjectOffset(EHSlot[1]), - TL->getExceptionSelectorRegister())); + const int *EHSlot = XFI->getEHSpillSlot(); + SpillList.push_back( + StackSlotInfo(EHSlot[0], MFI->getObjectOffset(EHSlot[0]), + TL->getExceptionPointerRegister(PersonalityFn))); + SpillList.push_back( + StackSlotInfo(EHSlot[0], MFI->getObjectOffset(EHSlot[1]), + TL->getExceptionSelectorRegister(PersonalityFn))); std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset); } - static MachineMemOperand * getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, unsigned flags) { MachineFunction *MF = MBB.getParent(); @@ -322,8 +322,11 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF, if (XFI->hasEHSpillSlot()) { // The unwinder requires stack slot & CFI offsets for the exception info. // We do not save/spill these registers. - SmallVector SpillList; - GetEHSpillList(SpillList, MFI, XFI, + const Function *Fn = MF.getFunction(); + const Constant *PersonalityFn = + Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr; + SmallVector SpillList; + GetEHSpillList(SpillList, MFI, XFI, PersonalityFn, MF.getSubtarget().getTargetLowering()); assert(SpillList.size()==2 && "Unexpected SpillList size"); EmitCfiOffset(MBB, MBBI, dl, TII, MMI, @@ -354,8 +357,12 @@ void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, if (RetOpcode == XCore::EH_RETURN) { // 'Restore' the exception info the unwinder has placed into the stack // slots. - SmallVector SpillList; - GetEHSpillList(SpillList, MFI, XFI, MF.getSubtarget().getTargetLowering()); + const Function *Fn = MF.getFunction(); + const Constant *PersonalityFn = + Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr; + SmallVector SpillList; + GetEHSpillList(SpillList, MFI, XFI, PersonalityFn, + MF.getSubtarget().getTargetLowering()); RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList); // Return to the landing pad. diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index 28735567721..105b2cfb1be 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/lib/Target/XCore/XCoreISelLowering.cpp @@ -151,8 +151,6 @@ XCoreTargetLowering::XCoreTargetLowering(const TargetMachine &TM, // Exception handling setOperationAction(ISD::EH_RETURN, MVT::Other, Custom); - setExceptionPointerRegister(XCore::R0); - setExceptionSelectorRegister(XCore::R1); setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i32, Custom); // Atomic operations diff --git a/lib/Target/XCore/XCoreISelLowering.h b/lib/Target/XCore/XCoreISelLowering.h index ddd675c5164..b6f09ff418b 100644 --- a/lib/Target/XCore/XCoreISelLowering.h +++ b/lib/Target/XCore/XCoreISelLowering.h @@ -125,6 +125,20 @@ namespace llvm { bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS) const override; + /// If a physical register, this returns the register that receives the + /// exception address on entry to an EH pad. + unsigned + getExceptionPointerRegister(const Constant *PersonalityFn) const override { + return XCore::R0; + } + + /// If a physical register, this returns the register that receives the + /// exception typeid on entry to a landing pad. + unsigned + getExceptionSelectorRegister(const Constant *PersonalityFn) const override { + return XCore::R1; + } + private: const TargetMachine &TM; const XCoreSubtarget &Subtarget; diff --git a/test/CodeGen/WinEH/wineh-coreclr.ll b/test/CodeGen/WinEH/wineh-coreclr.ll index f5e046aa01c..923d966a5f6 100644 --- a/test/CodeGen/WinEH/wineh-coreclr.ll +++ b/test/CodeGen/WinEH/wineh-coreclr.ll @@ -2,6 +2,8 @@ declare void @ProcessCLRException() declare void @f(i32) +declare void @g(i8 addrspace(1)*) +declare i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token) ; Simplified IR for pseudo-C# like the following: ; void test1() { @@ -51,8 +53,13 @@ catch1.pad: to label %catch1.body unwind label %catch2.pad catch1.body: ; CHECK: leaq {{[0-9]+}}(%rcx), %rbp -; ^ establisher frame pointer passed in rcx +; ^ establisher frame pointer passed in rcx ; CHECK: .seh_endprologue +; CHECK: movq %rdx, %rcx +; ^ exception pointer passed in rdx +; CHECK-NEXT: callq g + %exn1 = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch1) + call void @g(i8 addrspace(1)* %exn1) ; CHECK: [[L_before_f3:.+]]: ; CHECK-NEXT: movl $3, %ecx ; CHECK-NEXT: callq f @@ -67,8 +74,13 @@ catch2.pad: to label %catch2.body unwind label %catch.end catch2.body: ; CHECK: leaq {{[0-9]+}}(%rcx), %rbp -; ^ establisher frame pointer passed in rcx +; ^ establisher frame pointer passed in rcx ; CHECK: .seh_endprologue +; CHECK: movq %rdx, %rcx +; ^ exception pointer passed in rdx +; CHECK-NEXT: callq g + %exn2 = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch2) + call void @g(i8 addrspace(1)* %exn2) ; CHECK: [[L_before_f4:.+]]: ; CHECK-NEXT: movl $4, %ecx ; CHECK-NEXT: callq f @@ -87,7 +99,7 @@ fault.pad: ; CHECK: .seh_proc [[L_fault:[^ ]+]] %fault = cleanuppad [i32 undef] ; CHECK: leaq {{[0-9]+}}(%rcx), %rbp -; ^ establisher frame pointer passed in rcx +; ^ establisher frame pointer passed in rcx ; CHECK: .seh_endprologue ; CHECK: [[L_before_f6:.+]]: ; CHECK-NEXT: movl $6, %ecx @@ -110,7 +122,7 @@ finally.pad: ; CHECK: .seh_proc [[L_finally:[^ ]+]] %finally = cleanuppad [] ; CHECK: leaq {{[0-9]+}}(%rcx), %rbp -; ^ establisher frame pointer passed in rcx +; ^ establisher frame pointer passed in rcx ; CHECK: .seh_endprologue ; CHECK: [[L_before_f7:.+]]: ; CHECK-NEXT: movl $7, %ecx diff --git a/test/CodeGen/WinEH/wineh-exceptionpointer.ll b/test/CodeGen/WinEH/wineh-exceptionpointer.ll index 05139ef1bd9..47ffc35acac 100644 --- a/test/CodeGen/WinEH/wineh-exceptionpointer.ll +++ b/test/CodeGen/WinEH/wineh-exceptionpointer.ll @@ -17,7 +17,7 @@ catch.pad: catch.body: %exn = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch) %cast_exn = bitcast i8 addrspace(1)* %exn to i32 addrspace(1)* - ; CHECK: movq %rax, %rcx + ; CHECK: movq %rdx, %rcx ; CHECK-NEXT: callq g call void @g(i32 addrspace(1)* %cast_exn) catchret %catch to label %exit