llvm.org GIT mirror llvm / de9bf0f
[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 Joseph Tremoulet 5 years ago
25 changed file(s) with 212 addition(s) and 92 deletion(s). Raw diff Collapse all Expand all
938938 }
939939
940940 /// If a physical register, this returns the register that receives the
941 /// exception address on entry to a landing pad.
942 unsigned getExceptionPointerRegister() const {
943 return ExceptionPointerRegister;
941 /// exception address on entry to an EH pad.
942 virtual unsigned
943 getExceptionPointerRegister(const Constant *PersonalityFn) const {
944 // 0 is guaranteed to be the NoRegister value on all targets
945 return 0;
944946 }
945947
946948 /// If a physical register, this returns the register that receives the
947949 /// exception typeid on entry to a landing pad.
948 unsigned getExceptionSelectorRegister() const {
949 return ExceptionSelectorRegister;
950 virtual unsigned
951 getExceptionSelectorRegister(const Constant *PersonalityFn) const {
952 // 0 is guaranteed to be the NoRegister value on all targets
953 return 0;
950954 }
951955
952956 /// Returns the target's jmp_buf size in bytes (if never set, the default is
12271231 StackPointerRegisterToSaveRestore = R;
12281232 }
12291233
1230 /// If set to a physical register, this sets the register that receives the
1231 /// exception address on entry to a landing pad.
1232 void setExceptionPointerRegister(unsigned R) {
1233 ExceptionPointerRegister = R;
1234 }
1235
1236 /// If set to a physical register, this sets the register that receives the
1237 /// exception typeid on entry to a landing pad.
1238 void setExceptionSelectorRegister(unsigned R) {
1239 ExceptionSelectorRegister = R;
1240 }
1241
12421234 /// Tells the code generator not to expand operations into sequences that use
12431235 /// the select operations if possible.
12441236 void setSelectIsExpensive(bool isExpensive = true) {
18551847 /// llvm.savestack/llvm.restorestack should save and restore.
18561848 unsigned StackPointerRegisterToSaveRestore;
18571849
1858 /// If set to a physical register, this specifies the register that receives
1859 /// the exception address on entry to a landing pad.
1860 unsigned ExceptionPointerRegister;
1861
1862 /// If set to a physical register, this specifies the register that receives
1863 /// the exception typeid on entry to a landing pad.
1864 unsigned ExceptionSelectorRegister;
1865
18661850 /// This indicates the default register class to use for each ValueType the
18671851 /// target supports natively.
18681852 const TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE];
21832183 // If there aren't registers to copy the values into (e.g., during SjLj
21842184 // exceptions), then don't bother to create these DAG nodes.
21852185 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
2186 if (TLI.getExceptionPointerRegister() == 0 &&
2187 TLI.getExceptionSelectorRegister() == 0)
2186 const Constant *PersonalityFn = FuncInfo.Fn->getPersonalityFn();
2187 if (TLI.getExceptionPointerRegister(PersonalityFn) == 0 &&
2188 TLI.getExceptionSelectorRegister(PersonalityFn) == 0)
21882189 return;
21892190
21902191 SmallVector ValueVTs;
937937 /// do other setup for EH landing-pad blocks.
938938 bool SelectionDAGISel::PrepareEHLandingPad() {
939939 MachineBasicBlock *MBB = FuncInfo->MBB;
940 const Constant *PersonalityFn = FuncInfo->Fn->getPersonalityFn();
940941 const BasicBlock *LLVMBB = MBB->getBasicBlock();
941942 const TargetRegisterClass *PtrRC =
942943 TLI->getRegClassFor(TLI->getPointerTy(CurDAG->getDataLayout()));
947948 if (hasExceptionPointerOrCodeUser(CPI)) {
948949 // Get or create the virtual register to hold the pointer or code. Mark
949950 // the live in physreg and copy into the vreg.
950 MCPhysReg EHPhysReg = TLI->getExceptionPointerRegister();
951 MCPhysReg EHPhysReg = TLI->getExceptionPointerRegister(PersonalityFn);
951952 assert(EHPhysReg && "target lacks exception pointer register");
952953 MBB->addLiveIn(EHPhysReg);
953954 unsigned VReg = FuncInfo->getCatchPadExceptionPointerVReg(CPI, PtrRC);
973974 .addSym(Label);
974975
975976 // Mark exception register as live in.
976 if (unsigned Reg = TLI->getExceptionPointerRegister())
977 if (unsigned Reg = TLI->getExceptionPointerRegister(PersonalityFn))
977978 FuncInfo->ExceptionPointerVirtReg = MBB->addLiveIn(Reg, PtrRC);
978979
979980 // Mark exception selector register as live in.
980 if (unsigned Reg = TLI->getExceptionSelectorRegister())
981 if (unsigned Reg = TLI->getExceptionSelectorRegister(PersonalityFn))
981982 FuncInfo->ExceptionSelectorVirtReg = MBB->addLiveIn(Reg, PtrRC);
982983
983984 return true;
764764 EnableExtLdPromotion = false;
765765 HasFloatingPointExceptions = true;
766766 StackPointerRegisterToSaveRestore = 0;
767 ExceptionPointerRegister = 0;
768 ExceptionSelectorRegister = 0;
769767 BooleanContents = UndefinedBooleanContent;
770768 BooleanFloatContents = UndefinedBooleanContent;
771769 BooleanVectorContents = UndefinedBooleanContent;
194194 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
195195 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
196196 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand);
197
198 // Exception handling.
199 // FIXME: These are guesses. Has this been defined yet?
200 setExceptionPointerRegister(AArch64::X0);
201 setExceptionSelectorRegister(AArch64::X1);
202197
203198 // Constant pool entries
204199 setOperationAction(ISD::ConstantPool, MVT::i64, Custom);
1414 #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64ISELLOWERING_H
1515 #define LLVM_LIB_TARGET_AARCH64_AARCH64ISELLOWERING_H
1616
17 #include "AArch64.h"
1718 #include "llvm/CodeGen/CallingConvLower.h"
1819 #include "llvm/CodeGen/SelectionDAG.h"
1920 #include "llvm/IR/CallingConv.h"
364365 /// If the target has a standard location for the unsafe stack pointer,
365366 /// returns the address of that location. Otherwise, returns nullptr.
366367 Value *getSafeStackPointerLocation(IRBuilder<> &IRB) const override;
368
369 /// If a physical register, this returns the register that receives the
370 /// exception address on entry to an EH pad.
371 unsigned
372 getExceptionPointerRegister(const Constant *PersonalityFn) const override {
373 // FIXME: This is a guess. Has this been defined yet?
374 return AArch64::X0;
375 }
376
377 /// If a physical register, this returns the register that receives the
378 /// exception typeid on entry to a landing pad.
379 unsigned
380 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
381 // FIXME: This is a guess. Has this been defined yet?
382 return AArch64::X1;
383 }
367384
368385 private:
369386 bool isExtFreeImpl(const Instruction *Ext) const override;
811811 setOperationAction(ISD::VAEND, MVT::Other, Expand);
812812 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
813813 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
814
815 if (!Subtarget->useSjLjEH()) {
816 // Platforms which do not use SjLj EH may return values in these registers
817 // via the personality function.
818 setExceptionPointerRegister(ARM::R0);
819 setExceptionSelectorRegister(ARM::R1);
820 }
821814
822815 if (Subtarget->getTargetTriple().isWindowsItaniumEnvironment())
823816 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);
1214612139 bool IsIntArray = Ty->isArrayTy() && Ty->getArrayElementType()->isIntegerTy();
1214712140 return IsHA || IsIntArray;
1214812141 }
12142
12143 unsigned ARMTargetLowering::getExceptionPointerRegister(
12144 const Constant *PersonalityFn) const {
12145 // Platforms which do not use SjLj EH may return values in these registers
12146 // via the personality function.
12147 return Subtarget->useSjLjEH() ? ARM::NoRegister : ARM::R0;
12148 }
12149
12150 unsigned ARMTargetLowering::getExceptionSelectorRegister(
12151 const Constant *PersonalityFn) const {
12152 // Platforms which do not use SjLj EH may return values in these registers
12153 // via the personality function.
12154 return Subtarget->useSjLjEH() ? ARM::NoRegister : ARM::R1;
12155 }
421421 /// contiguous block of registers in calling convention CallConv.
422422 bool functionArgumentNeedsConsecutiveRegisters(
423423 Type *Ty, CallingConv::ID CallConv, bool isVarArg) const override;
424
425 /// If a physical register, this returns the register that receives the
426 /// exception address on entry to an EH pad.
427 unsigned
428 getExceptionPointerRegister(const Constant *PersonalityFn) const override;
429
430 /// If a physical register, this returns the register that receives the
431 /// exception typeid on entry to a landing pad.
432 unsigned
433 getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
424434
425435 Instruction *makeDMB(IRBuilder<> &Builder, ARM_MB::MemBOpt Domain) const;
426436 Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
12851285 setPrefFunctionAlignment(4);
12861286 setMinFunctionAlignment(2);
12871287 setInsertFencesForAtomic(false);
1288 setExceptionPointerRegister(Hexagon::R0);
1289 setExceptionSelectorRegister(Hexagon::R1);
12901288 setStackPointerRegisterToSaveRestore(HRI.getStackRegister());
12911289
12921290 if (EnableHexSDNodeSched)
162162 MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI,
163163 MachineBasicBlock *BB) const override;
164164
165 /// If a physical register, this returns the register that receives the
166 /// exception address on entry to an EH pad.
167 unsigned
168 getExceptionPointerRegister(const Constant *PersonalityFn) const override {
169 return Hexagon::R0;
170 }
171
172 /// If a physical register, this returns the register that receives the
173 /// exception typeid on entry to a landing pad.
174 unsigned
175 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
176 return Hexagon::R1;
177 }
178
165179 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
166180 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
167181 EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
437437
438438 setStackPointerRegisterToSaveRestore(ABI.IsN64() ? Mips::SP_64 : Mips::SP);
439439
440 setExceptionPointerRegister(ABI.IsN64() ? Mips::A0_64 : Mips::A0);
441 setExceptionSelectorRegister(ABI.IsN64() ? Mips::A1_64 : Mips::A1);
442
443440 MaxStoresPerMemcpy = 16;
444441
445442 isMicroMips = Subtarget.inMicroMipsMode();
265265
266266 unsigned getRegisterByName(const char* RegName, EVT VT,
267267 SelectionDAG &DAG) const override;
268
269 /// If a physical register, this returns the register that receives the
270 /// exception address on entry to an EH pad.
271 unsigned
272 getExceptionPointerRegister(const Constant *PersonalityFn) const override {
273 return ABI.IsN64() ? Mips::A0_64 : Mips::A0;
274 }
275
276 /// If a physical register, this returns the register that receives the
277 /// exception typeid on entry to a landing pad.
278 unsigned
279 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
280 return ABI.IsN64() ? Mips::A1_64 : Mips::A1;
281 }
268282
269283 /// Returns true if a cast between SrcAS and DestAS is a noop.
270284 bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override {
826826 setLibcallName(RTLIB::SRA_I128, nullptr);
827827 }
828828
829 if (isPPC64) {
830 setStackPointerRegisterToSaveRestore(PPC::X1);
831 setExceptionPointerRegister(PPC::X3);
832 setExceptionSelectorRegister(PPC::X4);
833 } else {
834 setStackPointerRegisterToSaveRestore(PPC::R1);
835 setExceptionPointerRegister(PPC::R3);
836 setExceptionSelectorRegister(PPC::R4);
837 }
829 setStackPointerRegisterToSaveRestore(isPPC64 ? PPC::X1 : PPC::R1);
838830
839831 // We have target-specific dag combine patterns for the following nodes:
840832 setTargetDAGCombine(ISD::SINT_TO_FP);
1153111523 return ScratchRegs;
1153211524 }
1153311525
11526 unsigned PPCTargetLowering::getExceptionPointerRegister(
11527 const Constant *PersonalityFn) const {
11528 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
11529 }
11530
11531 unsigned PPCTargetLowering::getExceptionSelectorRegister(
11532 const Constant *PersonalityFn) const {
11533 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
11534 }
11535
1153411536 bool
1153511537 PPCTargetLowering::shouldExpandBuildVectorWithShuffles(
1153611538 EVT VT , unsigned DefinedValues) const {
654654 return Ty->isArrayTy();
655655 }
656656
657 /// If a physical register, this returns the register that receives the
658 /// exception address on entry to an EH pad.
659 unsigned
660 getExceptionPointerRegister(const Constant *PersonalityFn) const override;
661
662 /// If a physical register, this returns the register that receives the
663 /// exception typeid on entry to a landing pad.
664 unsigned
665 getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
666
657667 private:
658
659668 struct ReuseLoadInfo {
660669 SDValue Ptr;
661670 SDValue Chain;
16721672 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
16731673 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
16741674 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Custom);
1675
1676 setExceptionPointerRegister(SP::I0);
1677 setExceptionSelectorRegister(SP::I1);
16781675
16791676 setStackPointerRegisterToSaveRestore(SP::O6);
16801677
8686 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
8787 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
8888 return MVT::i32;
89 }
90
91 /// If a physical register, this returns the register that receives the
92 /// exception address on entry to an EH pad.
93 unsigned
94 getExceptionPointerRegister(const Constant *PersonalityFn) const override {
95 return SP::I0;
96 }
97
98 /// If a physical register, this returns the register that receives the
99 /// exception typeid on entry to a landing pad.
100 unsigned
101 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
102 return SP::I1;
89103 }
90104
91105 /// getSetCCResultType - Return the ISD::SETCC ValueType
113113 computeRegisterProperties(Subtarget.getRegisterInfo());
114114
115115 // Set up special registers.
116 setExceptionPointerRegister(SystemZ::R6D);
117 setExceptionSelectorRegister(SystemZ::R7D);
118116 setStackPointerRegisterToSaveRestore(SystemZ::R15D);
119117
120118 // TODO: It may be better to default to latency-oriented scheduling, however
408408 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
409409 }
410410
411 /// If a physical register, this returns the register that receives the
412 /// exception address on entry to an EH pad.
413 unsigned
414 getExceptionPointerRegister(const Constant *PersonalityFn) const override {
415 return SystemZ::R6D;
416 }
417
418 /// If a physical register, this returns the register that receives the
419 /// exception typeid on entry to a landing pad.
420 unsigned
421 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
422 return SystemZ::R7D;
423 }
424
411425 MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
412426 MachineBasicBlock *BB) const
413427 override;
2424 #include "llvm/ADT/Statistic.h"
2525 #include "llvm/ADT/StringExtras.h"
2626 #include "llvm/ADT/StringSwitch.h"
27 #include "llvm/Analysis/LibCallSemantics.h"
2728 #include "llvm/CodeGen/IntrinsicLowering.h"
2829 #include "llvm/CodeGen/MachineFrameInfo.h"
2930 #include "llvm/CodeGen/MachineFunction.h"
475476 setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
476477 }
477478
478 if (Subtarget->isTarget64BitLP64()) {
479 setExceptionPointerRegister(X86::RAX);
480 setExceptionSelectorRegister(X86::RDX);
481 } else {
482 setExceptionPointerRegister(X86::EAX);
483 setExceptionSelectorRegister(X86::EDX);
484 }
485479 setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i32, Custom);
486480 setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i64, Custom);
487481
1724317237 SelectionDAG &DAG) const {
1724417238 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
1724517239 return DAG.getIntPtrConstant(2 * RegInfo->getSlotSize(), SDLoc(Op));
17240 }
17241
17242 unsigned X86TargetLowering::getExceptionPointerRegister(
17243 const Constant *PersonalityFn) const {
17244 if (classifyEHPersonality(PersonalityFn) == EHPersonality::CoreCLR)
17245 return Subtarget->isTarget64BitLP64() ? X86::RDX : X86::EDX;
17246
17247 return Subtarget->isTarget64BitLP64() ? X86::RAX : X86::EAX;
17248 }
17249
17250 unsigned X86TargetLowering::getExceptionSelectorRegister(
17251 const Constant *PersonalityFn) const {
17252 // Funclet personalities don't use selectors (the runtime does the selection).
17253 assert(!isFuncletEHPersonality(classifyEHPersonality(PersonalityFn)));
17254 return Subtarget->isTarget64BitLP64() ? X86::RDX : X86::EDX;
1724617255 }
1724717256
1724817257 SDValue X86TargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
888888 unsigned getRegisterByName(const char* RegName, EVT VT,
889889 SelectionDAG &DAG) const override;
890890
891 /// If a physical register, this returns the register that receives the
892 /// exception address on entry to an EH pad.
893 unsigned
894 getExceptionPointerRegister(const Constant *PersonalityFn) const override;
895
896 /// If a physical register, this returns the register that receives the
897 /// exception typeid on entry to a landing pad.
898 unsigned
899 getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
900
891901 /// This method returns a target specific FastISel object,
892902 /// or null if the target does not support "fast" ISel.
893903 FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
159159 /// As offsets are negative, the largest offsets will be first.
160160 static void GetEHSpillList(SmallVectorImpl &SpillList,
161161 MachineFrameInfo *MFI, XCoreFunctionInfo *XFI,
162 const Constant *PersonalityFn,
162163 const TargetLowering *TL) {
163164 assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots");
164 const int* EHSlot = XFI->getEHSpillSlot();
165 SpillList.push_back(StackSlotInfo(EHSlot[0],
166 MFI->getObjectOffset(EHSlot[0]),
167 TL->getExceptionPointerRegister()));
168 SpillList.push_back(StackSlotInfo(EHSlot[0],
169 MFI->getObjectOffset(EHSlot[1]),
170 TL->getExceptionSelectorRegister()));
165 const int *EHSlot = XFI->getEHSpillSlot();
166 SpillList.push_back(
167 StackSlotInfo(EHSlot[0], MFI->getObjectOffset(EHSlot[0]),
168 TL->getExceptionPointerRegister(PersonalityFn)));
169 SpillList.push_back(
170 StackSlotInfo(EHSlot[0], MFI->getObjectOffset(EHSlot[1]),
171 TL->getExceptionSelectorRegister(PersonalityFn)));
171172 std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset);
172173 }
173
174174
175175 static MachineMemOperand *
176176 getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, unsigned flags) {
321321 if (XFI->hasEHSpillSlot()) {
322322 // The unwinder requires stack slot & CFI offsets for the exception info.
323323 // We do not save/spill these registers.
324 SmallVector SpillList;
325 GetEHSpillList(SpillList, MFI, XFI,
324 const Function *Fn = MF.getFunction();
325 const Constant *PersonalityFn =
326 Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
327 SmallVector SpillList;
328 GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
326329 MF.getSubtarget().getTargetLowering());
327330 assert(SpillList.size()==2 && "Unexpected SpillList size");
328331 EmitCfiOffset(MBB, MBBI, dl, TII, MMI,
353356 if (RetOpcode == XCore::EH_RETURN) {
354357 // 'Restore' the exception info the unwinder has placed into the stack
355358 // slots.
356 SmallVector SpillList;
357 GetEHSpillList(SpillList, MFI, XFI, MF.getSubtarget().getTargetLowering());
359 const Function *Fn = MF.getFunction();
360 const Constant *PersonalityFn =
361 Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
362 SmallVector SpillList;
363 GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
364 MF.getSubtarget().getTargetLowering());
358365 RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
359366
360367 // Return to the landing pad.
150150
151151 // Exception handling
152152 setOperationAction(ISD::EH_RETURN, MVT::Other, Custom);
153 setExceptionPointerRegister(XCore::R0);
154 setExceptionSelectorRegister(XCore::R1);
155153 setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i32, Custom);
156154
157155 // Atomic operations
123123
124124 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
125125 Type *Ty, unsigned AS) const override;
126
127 /// If a physical register, this returns the register that receives the
128 /// exception address on entry to an EH pad.
129 unsigned
130 getExceptionPointerRegister(const Constant *PersonalityFn) const override {
131 return XCore::R0;
132 }
133
134 /// If a physical register, this returns the register that receives the
135 /// exception typeid on entry to a landing pad.
136 unsigned
137 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
138 return XCore::R1;
139 }
126140
127141 private:
128142 const TargetMachine &TM;
11
22 declare void @ProcessCLRException()
33 declare void @f(i32)
4 declare void @g(i8 addrspace(1)*)
5 declare i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token)
46
57 ; Simplified IR for pseudo-C# like the following:
68 ; void test1() {
5052 to label %catch1.body unwind label %catch2.pad
5153 catch1.body:
5254 ; CHECK: leaq {{[0-9]+}}(%rcx), %rbp
53 ; ^ establisher frame pointer passed in rcx
54 ; CHECK: .seh_endprologue
55 ; ^ establisher frame pointer passed in rcx
56 ; CHECK: .seh_endprologue
57 ; CHECK: movq %rdx, %rcx
58 ; ^ exception pointer passed in rdx
59 ; CHECK-NEXT: callq g
60 %exn1 = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch1)
61 call void @g(i8 addrspace(1)* %exn1)
5562 ; CHECK: [[L_before_f3:.+]]:
5663 ; CHECK-NEXT: movl $3, %ecx
5764 ; CHECK-NEXT: callq f
6673 to label %catch2.body unwind label %catch.end
6774 catch2.body:
6875 ; CHECK: leaq {{[0-9]+}}(%rcx), %rbp
69 ; ^ establisher frame pointer passed in rcx
70 ; CHECK: .seh_endprologue
76 ; ^ establisher frame pointer passed in rcx
77 ; CHECK: .seh_endprologue
78 ; CHECK: movq %rdx, %rcx
79 ; ^ exception pointer passed in rdx
80 ; CHECK-NEXT: callq g
81 %exn2 = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch2)
82 call void @g(i8 addrspace(1)* %exn2)
7183 ; CHECK: [[L_before_f4:.+]]:
7284 ; CHECK-NEXT: movl $4, %ecx
7385 ; CHECK-NEXT: callq f
8698 ; CHECK: .seh_proc [[L_fault:[^ ]+]]
8799 %fault = cleanuppad [i32 undef]
88100 ; CHECK: leaq {{[0-9]+}}(%rcx), %rbp
89 ; ^ establisher frame pointer passed in rcx
101 ; ^ establisher frame pointer passed in rcx
90102 ; CHECK: .seh_endprologue
91103 ; CHECK: [[L_before_f6:.+]]:
92104 ; CHECK-NEXT: movl $6, %ecx
109121 ; CHECK: .seh_proc [[L_finally:[^ ]+]]
110122 %finally = cleanuppad []
111123 ; CHECK: leaq {{[0-9]+}}(%rcx), %rbp
112 ; ^ establisher frame pointer passed in rcx
124 ; ^ establisher frame pointer passed in rcx
113125 ; CHECK: .seh_endprologue
114126 ; CHECK: [[L_before_f7:.+]]:
115127 ; CHECK-NEXT: movl $7, %ecx
1616 catch.body:
1717 %exn = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch)
1818 %cast_exn = bitcast i8 addrspace(1)* %exn to i32 addrspace(1)*
19 ; CHECK: movq %rax, %rcx
19 ; CHECK: movq %rdx, %rcx
2020 ; CHECK-NEXT: callq g
2121 call void @g(i32 addrspace(1)* %cast_exn)
2222 catchret %catch to label %exit