llvm.org GIT mirror llvm / 8f32e5f
Rename llvm.frameescape and llvm.framerecover to localescape and localrecover Summary: Initially, these intrinsics seemed like part of a family of "frame" related intrinsics, but now I think that's more confusing than helpful. Initially, the LangRef specified that this would create a new kind of allocation that would be allocated at a fixed offset from the frame pointer (EBP/RBP). We ended up dropping that design, and leaving the stack frame layout alone. These intrinsics are really about sharing local stack allocations, not frame pointers. I intend to go further and add an `llvm.localaddress()` intrinsic that returns whatever register (EBP, ESI, ESP, RBX) is being used to address locals, which should not be confused with the frame pointer. Naming suggestions at this point are welcome, I'm happy to re-run sed. Reviewers: majnemer, nicholas Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D11011 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241633 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 4 years ago
52 changed file(s) with 230 addition(s) and 229 deletion(s). Raw diff Collapse all Expand all
338338
339339 Catch handlers are called with a pointer to the handler itself as the first
340340 argument and a pointer to the parent function's stack frame as the second
341 argument. The catch handler uses the `llvm.recoverframe
342 `_ to get a
341 argument. The catch handler uses the `llvm.localrecover
342 `_ to get a
343343 pointer to a frame allocation block that is created in the parent frame using
344 the `llvm.allocateframe
345 `_ intrinsic.
344 the `llvm.localescape
345 `_ intrinsic.
346346 The ``WinEHPrepare`` pass will have created a structure definition for the
347347 contents of this block. The first two members of the structure will always be
348348 (1) a 32-bit integer that the runtime uses to track the exception state of the
519519 A code of ``i32 1`` indicates a catch action, which expects three additional
520520 arguments. Different EH schemes give different meanings to the three arguments,
521521 but the first argument indicates whether the catch should fire, the second is
522 the frameescape index of the exception object, and the third is the code to run
522 the localescape index of the exception object, and the third is the code to run
523523 to catch the exception.
524524
525525 For Windows C++ exception handling, the first argument for a catch handler is a
526526 pointer to the RTTI type descriptor for the object to catch. The second
527 argument is an index into the argument list of the ``llvm.frameescape`` call in
527 argument is an index into the argument list of the ``llvm.localescape`` call in
528528 the main function. The exception object will be copied into the provided stack
529529 object. If the exception object is not required, this argument should be -1.
530530 The third argument is a pointer to a function implementing the catch. This
77797779 other aggressive transformations, so the value returned may not be that
77807780 of the obvious source-language caller.
77817781
7782 '``llvm.frameescape``' and '``llvm.framerecover``' Intrinsics
7782 '``llvm.localescape``' and '``llvm.localrecover``' Intrinsics
77837783 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
77847784
77857785 Syntax:
77877787
77887788 ::
77897789
7790 declare void @llvm.frameescape(...)
7791 declare i8* @llvm.framerecover(i8* %func, i8* %fp, i32 %idx)
7792
7793 Overview:
7794 """""""""
7795
7796 The '``llvm.frameescape``' intrinsic escapes offsets of a collection of static
7797 allocas, and the '``llvm.framerecover``' intrinsic applies those offsets to a
7790 declare void @llvm.localescape(...)
7791 declare i8* @llvm.localrecover(i8* %func, i8* %fp, i32 %idx)
7792
7793 Overview:
7794 """""""""
7795
7796 The '``llvm.localescape``' intrinsic escapes offsets of a collection of static
7797 allocas, and the '``llvm.localrecover``' intrinsic applies those offsets to a
77987798 live frame pointer to recover the address of the allocation. The offset is
7799 computed during frame layout of the caller of ``llvm.frameescape``.
7800
7801 Arguments:
7802 """"""""""
7803
7804 All arguments to '``llvm.frameescape``' must be pointers to static allocas or
7805 casts of static allocas. Each function can only call '``llvm.frameescape``'
7799 computed during frame layout of the caller of ``llvm.localescape``.
7800
7801 Arguments:
7802 """"""""""
7803
7804 All arguments to '``llvm.localescape``' must be pointers to static allocas or
7805 casts of static allocas. Each function can only call '``llvm.localescape``'
78067806 once, and it can only do so from the entry block.
78077807
7808 The ``func`` argument to '``llvm.framerecover``' must be a constant
7808 The ``func`` argument to '``llvm.localrecover``' must be a constant
78097809 bitcasted pointer to a function defined in the current module. The code
78107810 generator cannot determine the frame allocation offset of functions defined in
78117811 other modules.
78127812
7813 The ``fp`` argument to '``llvm.framerecover``' must be a frame
7813 The ``fp`` argument to '``llvm.localrecover``' must be a frame
78147814 pointer of a call frame that is currently live. The return value of
78157815 '``llvm.frameaddress``' is one way to produce such a value, but most platforms
78167816 also expose the frame pointer through stack unwinding mechanisms.
78177817
7818 The ``idx`` argument to '``llvm.framerecover``' indicates which alloca passed to
7819 '``llvm.frameescape``' to recover. It is zero-indexed.
7820
7821 Semantics:
7822 """"""""""
7823
7824 These intrinsics allow a group of functions to access one stack memory
7825 allocation in an ancestor stack frame. The memory returned from
7826 '``llvm.frameallocate``' may be allocated prior to stack realignment, so the
7827 memory is only aligned to the ABI-required stack alignment. Each function may
7828 only call '``llvm.frameallocate``' one or zero times from the function entry
7829 block. The frame allocation intrinsic inhibits inlining, as any frame
7830 allocations in the inlined function frame are likely to be at a different
7831 offset from the one used by '``llvm.framerecover``' called with the
7832 uninlined function.
7818 The ``idx`` argument to '``llvm.localrecover``' indicates which alloca passed to
7819 '``llvm.localescape``' to recover. It is zero-indexed.
7820
7821 Semantics:
7822 """"""""""
7823
7824 These intrinsics allow a group of functions to share access to a set of local
7825 stack allocations of a one parent function. The parent function may call the
7826 '``llvm.localescape``' intrinsic once from the function entry block, and the
7827 child functions can use '``llvm.localrecover``' to access the escaped allocas.
7828 The '``llvm.localescape``' intrinsic blocks inlining, as inlining changes where
7829 the escaped allocas are allocated, which would break attempts to use
7830 '``llvm.localrecover``'.
78337831
78347832 .. _int_read_register:
78357833 .. _int_write_register:
7171 /// the parent's frame or return address, and so on.
7272 FRAMEADDR, RETURNADDR,
7373
74 /// FRAME_ALLOC_RECOVER - Represents the llvm.framerecover
75 /// intrinsic. Materializes the offset from the frame pointer of another
76 /// function to the result of llvm.frameallocate.
77 FRAME_ALLOC_RECOVER,
74 /// LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
75 /// Materializes the offset from the local object pointer of another
76 /// function to a particular local object passed to llvm.localescape. The
77 /// operand is the MCSymbol label used to represent this offset, since
78 /// typically the offset is not known until after code generation of the
79 /// parent.
80 LOCAL_RECOVER,
7881
7982 /// READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on
8083 /// the DAG, which implements the named register global variables extension.
9090 // When the parseEHActions function is called to populate a vector of
9191 // instances of this class, the ExceptionObjectVar field will be nullptr
9292 // and the ExceptionObjectIndex will be the index of the exception object in
93 // the parent function's frameescape block.
93 // the parent function's localescape block.
9494 const Value *ExceptionObjectVar;
9595 int ExceptionObjectIndex;
9696 TinyPtrVector ReturnTargets;
147147 int UnwindHelpFrameOffset = -1;
148148 unsigned NumIPToStateFuncsVisited = 0;
149149
150 /// frameescape index of the 32-bit EH registration node. Set by
150 /// localescape index of the 32-bit EH registration node. Set by
151151 /// WinEHStatePass and used indirectly by SEH filter functions of the parent.
152152 int EHRegNodeEscapeIndex = INT_MAX;
153153
267267 //
268268 def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
269269 def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
270 def int_frameescape : Intrinsic<[], [llvm_vararg_ty]>;
271 def int_framerecover : Intrinsic<[llvm_ptr_ty],
270 def int_localescape : Intrinsic<[], [llvm_vararg_ty]>;
271 def int_localrecover : Intrinsic<[llvm_ptr_ty],
272272 [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
273273 [IntrNoMem]>;
274274 def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
2727 def int_x86_seh_restoreframe : Intrinsic<[], [], []>;
2828
2929 // Given a pointer to the end of an EH registration object, returns the true
30 // parent frame address that can be used with llvm.framerecover.
30 // parent frame address that can be used with llvm.localrecover.
3131 def int_x86_seh_recoverfp : Intrinsic<[llvm_ptr_ty],
3232 [llvm_ptr_ty, llvm_ptr_ty],
3333 [IntrNoMem]>;
272272 /// Gets a symbol that will be defined to the final stack offset of a local
273273 /// variable after codegen.
274274 ///
275 /// \param Idx - The index of a local variable passed to @llvm.frameescape.
275 /// \param Idx - The index of a local variable passed to @llvm.localescape.
276276 MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx);
277277
278278 MCSymbol *getOrCreateParentFrameOffsetSymbol(StringRef FuncName);
871871 let hasSideEffects = 0;
872872 bit isPseudo = 1;
873873 }
874 def FRAME_ALLOC : Instruction {
874 def LOCAL_ESCAPE : Instruction {
875875 // This instruction is really just a label. It has to be part of the chain so
876876 // that it doesn't get dropped from the DAG, but it produces nothing and has
877877 // no side effects.
117117 /// collectors and deoptimizations in either the callee or caller.
118118 STATEPOINT = 20,
119119
120 /// Instruction that records the offset of a function's frame allocation in a
121 /// label. Created by the llvm.frameallocate intrinsic. It has two arguments:
122 /// the symbol for the label and the frame index of the stack allocation.
123 FRAME_ALLOC = 21,
120 /// Instruction that records the offset of a local stack allocation passed to
121 /// llvm.localescape. It has two arguments: the symbol for the label and the
122 /// frame index of the local stack allocation.
123 LOCAL_ESCAPE = 21,
124124
125125 /// Loading instruction that may page fault, bundled with associated
126126 /// information on how to handle such a page fault. It is intended to support
782782 case Intrinsic::memmove:
783783 // SROA can usually chew through these intrinsics, but they aren't free.
784784 return false;
785 case Intrinsic::frameescape:
785 case Intrinsic::localescape:
786786 HasFrameEscape = true;
787787 return false;
788788 }
14231423 cast(CS.getInstruction())->canReturnTwice())
14241424 return false;
14251425
1426 // Disallow inlining functions that call @llvm.frameescape. Doing this
1426 // Disallow inlining functions that call @llvm.localescape. Doing this
14271427 // correctly would require major changes to the inliner.
14281428 if (CS.getCalledFunction() &&
14291429 CS.getCalledFunction()->getIntrinsicID() ==
1430 llvm::Intrinsic::frameescape)
1430 llvm::Intrinsic::localescape)
14311431 return false;
14321432 }
14331433 }
818818 emitCFIInstruction(MI);
819819 break;
820820
821 case TargetOpcode::FRAME_ALLOC:
821 case TargetOpcode::LOCAL_ESCAPE:
822822 emitFrameAlloc(MI);
823823 break;
824824
554554 // we've code generated the parent, we can emit the label assignment that
555555 // those helpers use to get the offset of the registration node.
556556 assert(FuncInfo.EHRegNodeEscapeIndex != INT_MAX &&
557 "no EH reg node frameescape index");
557 "no EH reg node localescape index");
558558 MCSymbol *ParentFrameOffset =
559559 Asm->OutContext.getOrCreateParentFrameOffsetSymbol(FLinkageName);
560560 MCSymbol *RegistrationOffsetSym = Asm->OutContext.getOrCreateFrameAllocSymbol(
5959 return false;
6060
6161 // Don't delete frame allocation labels.
62 if (MI->getOpcode() == TargetOpcode::FRAME_ALLOC)
62 if (MI->getOpcode() == TargetOpcode::LOCAL_ESCAPE)
6363 return false;
6464
6565 // Don't delete instructions with side effects.
49334933 case Intrinsic::instrprof_increment:
49344934 llvm_unreachable("instrprof failed to lower an increment");
49354935
4936 case Intrinsic::frameescape: {
4936 case Intrinsic::localescape: {
49374937 MachineFunction &MF = DAG.getMachineFunction();
49384938 const TargetInstrInfo *TII = DAG.getSubtarget().getInstrInfo();
49394939
4940 // Directly emit some FRAME_ALLOC machine instrs. Label assignment emission
4940 // Directly emit some LOCAL_ESCAPE machine instrs. Label assignment emission
49414941 // is the same on all targets.
49424942 for (unsigned Idx = 0, E = I.getNumArgOperands(); Idx < E; ++Idx) {
49434943 Value *Arg = I.getArgOperand(Idx)->stripPointerCasts();
49514951 MF.getMMI().getContext().getOrCreateFrameAllocSymbol(
49524952 GlobalValue::getRealLinkageName(MF.getName()), Idx);
49534953 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, dl,
4954 TII->get(TargetOpcode::FRAME_ALLOC))
4954 TII->get(TargetOpcode::LOCAL_ESCAPE))
49554955 .addSym(FrameAllocSym)
49564956 .addFrameIndex(FI);
49574957 }
49594959 return nullptr;
49604960 }
49614961
4962 case Intrinsic::framerecover: {
4963 // i8* @llvm.framerecover(i8* %fn, i8* %fp, i32 %idx)
4962 case Intrinsic::localrecover: {
4963 // i8* @llvm.localrecover(i8* %fn, i8* %fp, i32 %idx)
49644964 MachineFunction &MF = DAG.getMachineFunction();
49654965 MVT PtrVT = TLI.getPointerTy(0);
49664966
49764976 // that would make this PC relative.
49774977 SDValue OffsetSym = DAG.getMCSymbol(FrameAllocSym, PtrVT);
49784978 SDValue OffsetVal =
4979 DAG.getNode(ISD::FRAME_ALLOC_RECOVER, sdl, PtrVT, OffsetSym);
4979 DAG.getNode(ISD::LOCAL_RECOVER, sdl, PtrVT, OffsetSym);
49804980
49814981 // Add the offset to the FP.
49824982 Value *FP = I.getArgOperand(1);
9494 case ISD::GLOBAL_OFFSET_TABLE: return "GLOBAL_OFFSET_TABLE";
9595 case ISD::RETURNADDR: return "RETURNADDR";
9696 case ISD::FRAMEADDR: return "FRAMEADDR";
97 case ISD::FRAME_ALLOC_RECOVER: return "FRAME_ALLOC_RECOVER";
97 case ISD::LOCAL_RECOVER: return "LOCAL_RECOVER";
9898 case ISD::READ_REGISTER: return "READ_REGISTER";
9999 case ISD::WRITE_REGISTER: return "WRITE_REGISTER";
100100 case ISD::FRAME_TO_ARGS_OFFSET: return "FRAME_TO_ARGS_OFFSET";
952952 Builder.SetInsertPoint(Entry->getFirstInsertionPt());
953953
954954 Function *FrameEscapeFn =
955 Intrinsic::getDeclaration(M, Intrinsic::frameescape);
955 Intrinsic::getDeclaration(M, Intrinsic::localescape);
956956 Function *RecoverFrameFn =
957 Intrinsic::getDeclaration(M, Intrinsic::framerecover);
957 Intrinsic::getDeclaration(M, Intrinsic::localrecover);
958958 SmallVector AllocasToEscape;
959959
960 // Scan the entry block for an existing call to llvm.frameescape. We need to
960 // Scan the entry block for an existing call to llvm.localescape. We need to
961961 // keep escaping those objects.
962962 for (Instruction &I : F.front()) {
963963 auto *II = dyn_cast(&I);
964 if (II && II->getIntrinsicID() == Intrinsic::frameescape) {
964 if (II && II->getIntrinsicID() == Intrinsic::localescape) {
965965 auto Args = II->arg_operands();
966966 AllocasToEscape.append(Args.begin(), Args.end());
967967 II->eraseFromParent();
970970 }
971971
972972 // Finally, replace all of the temporary allocas for frame variables used in
973 // the outlined handlers with calls to llvm.framerecover.
973 // the outlined handlers with calls to llvm.localrecover.
974974 for (auto &VarInfoEntry : FrameVarInfo) {
975975 Value *ParentVal = VarInfoEntry.first;
976976 TinyPtrVector &Allocas = VarInfoEntry.second;
991991 llvm::Value *FP = HandlerToParentFP[HandlerFn];
992992 assert(FP);
993993
994 // FIXME: Sink this framerecover into the blocks where it is used.
994 // FIXME: Sink this localrecover into the blocks where it is used.
995995 Builder.SetInsertPoint(TempAlloca);
996996 Builder.SetCurrentDebugLocation(TempAlloca->getDebugLoc());
997997 Value *RecoverArgs[] = {
10131013 }
10141014 } // End for each FrameVarInfo entry.
10151015
1016 // Insert 'call void (...)* @llvm.frameescape(...)' at the end of the entry
1016 // Insert 'call void (...)* @llvm.localescape(...)' at the end of the entry
10171017 // block.
10181018 Builder.SetInsertPoint(&F.getEntryBlock().back());
10191019 Builder.CreateCall(FrameEscapeFn, AllocasToEscape);
19601960 // If we're asked to materialize a static alloca, we temporarily create an
19611961 // alloca in the outlined function and add this to the FrameVarInfo map. When
19621962 // all the outlining is complete, we'll replace these temporary allocas with
1963 // calls to llvm.framerecover.
1963 // calls to llvm.localrecover.
19641964 if (auto *AV = dyn_cast(V)) {
19651965 assert(AV->isStaticAlloca() &&
19661966 "cannot materialize un-demoted dynamic alloca");
19901990 // of a catch parameter, add a sentinel to the multimap to indicate that it's
19911991 // used from another handler. This will prevent us from trying to sink the
19921992 // alloca into the handler and ensure that the catch parameter is present in
1993 // the call to llvm.frameescape.
1993 // the call to llvm.localescape.
19941994 FrameVarInfo[V].push_back(getCatchObjectSentinel());
19951995 }
19961996
183183 /// \brief Track unresolved string-based type references.
184184 SmallDenseMap UnresolvedTypeRefs;
185185
186 /// \brief Whether we've seen a call to @llvm.frameescape in this function
186 /// \brief Whether we've seen a call to @llvm.localescape in this function
187187 /// already.
188188 bool SawFrameEscape;
189189
190 /// Stores the count of how many objects were passed to llvm.frameescape for a
191 /// given function and the largest index passed to llvm.framerecover.
190 /// Stores the count of how many objects were passed to llvm.localescape for a
191 /// given function and the largest index passed to llvm.localrecover.
192192 DenseMap> FrameEscapeInfo;
193193
194194 public:
16681668 unsigned EscapedObjectCount = Counts.second.first;
16691669 unsigned MaxRecoveredIndex = Counts.second.second;
16701670 Assert(MaxRecoveredIndex <= EscapedObjectCount,
1671 "all indices passed to llvm.framerecover must be less than the "
1672 "number of arguments passed ot llvm.frameescape in the parent "
1671 "all indices passed to llvm.localrecover must be less than the "
1672 "number of arguments passed ot llvm.localescape in the parent "
16731673 "function",
16741674 F);
16751675 }
32783278 "llvm.invariant.end parameter #2 must be a constant integer", CS);
32793279 break;
32803280
3281 case Intrinsic::frameescape: {
3281 case Intrinsic::localescape: {
32823282 BasicBlock *BB = CS.getParent();
32833283 Assert(BB == &BB->getParent()->front(),
3284 "llvm.frameescape used outside of entry block", CS);
3284 "llvm.localescape used outside of entry block", CS);
32853285 Assert(!SawFrameEscape,
3286 "multiple calls to llvm.frameescape in one function", CS);
3286 "multiple calls to llvm.localescape in one function", CS);
32873287 for (Value *Arg : CS.args()) {
32883288 if (isa(Arg))
32893289 continue; // Null values are allowed as placeholders.
32903290 auto *AI = dyn_cast(Arg->stripPointerCasts());
32913291 Assert(AI && AI->isStaticAlloca(),
3292 "llvm.frameescape only accepts static allocas", CS);
3292 "llvm.localescape only accepts static allocas", CS);
32933293 }
32943294 FrameEscapeInfo[BB->getParent()].first = CS.getNumArgOperands();
32953295 SawFrameEscape = true;
32963296 break;
32973297 }
3298 case Intrinsic::framerecover: {
3298 case Intrinsic::localrecover: {
32993299 Value *FnArg = CS.getArgOperand(0)->stripPointerCasts();
33003300 Function *Fn = dyn_cast(FnArg);
33013301 Assert(Fn && !Fn->isDeclaration(),
3302 "llvm.framerecover first "
3302 "llvm.localrecover first "
33033303 "argument must be function defined in this module",
33043304 CS);
33053305 auto *IdxArg = dyn_cast(CS.getArgOperand(2));
3306 Assert(IdxArg, "idx argument of llvm.framerecover must be a constant int",
3306 Assert(IdxArg, "idx argument of llvm.localrecover must be a constant int",
33073307 CS);
33083308 auto &Entry = FrameEscapeInfo[Fn];
33093309 Entry.second = unsigned(
10241024
10251025 switch (N.getOpcode()) {
10261026 default: break;
1027 case ISD::FRAME_ALLOC_RECOVER: {
1027 case ISD::LOCAL_RECOVER: {
10281028 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
10291029 if (const auto *ESNode = dyn_cast(N.getOperand(0))) {
10301030 // Use the symbol and don't prefix it.
1526815268 GlobalValue::getRealLinkageName(Fn->getName()));
1526915269 SDValue OffsetSymVal = DAG.getMCSymbol(OffsetSym, PtrVT);
1527015270 SDValue RegNodeFrameOffset =
15271 DAG.getNode(ISD::FRAME_ALLOC_RECOVER, dl, PtrVT, OffsetSymVal);
15271 DAG.getNode(ISD::LOCAL_RECOVER, dl, PtrVT, OffsetSymVal);
1527215272
1527315273 // RegNodeBase = EntryEBP - RegNodeSize
1527415274 // ParentFP = RegNodeBase - RegNodeFrameOffset
193193 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
194194 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
195195
196 def X86RecoverFrameAlloc : SDNode<"ISD::FRAME_ALLOC_RECOVER",
196 def X86RecoverFrameAlloc : SDNode<"ISD::LOCAL_RECOVER",
197197 SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
198198 SDTCisInt<1>]>>;
199199
518518 else
519519 BasePtr = (TFI->hasFP(MF) ? FramePtr : StackPtr);
520520
521 // FRAME_ALLOC uses a single offset, with no register. It only works in the
521 // LOCAL_ESCAPE uses a single offset, with no register. It only works in the
522522 // simple FP case, and doesn't work with stack realignment. On 32-bit, the
523523 // offset is from the traditional base pointer location. On 64-bit, the
524524 // offset is from the SP at the end of the prologue, not the FP location. This
525525 // matches the behavior of llvm.frameaddress.
526 if (Opc == TargetOpcode::FRAME_ALLOC) {
526 if (Opc == TargetOpcode::LOCAL_ESCAPE) {
527527 MachineOperand &FI = MI.getOperand(FIOperandNum);
528528 bool IsWinEH = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
529529 int Offset;
112112
113113 bool WinEHStatePass::doInitialization(Module &M) {
114114 TheModule = &M;
115 FrameEscape = Intrinsic::getDeclaration(TheModule, Intrinsic::frameescape);
116 FrameRecover = Intrinsic::getDeclaration(TheModule, Intrinsic::framerecover);
115 FrameEscape = Intrinsic::getDeclaration(TheModule, Intrinsic::localescape);
116 FrameRecover = Intrinsic::getDeclaration(TheModule, Intrinsic::localrecover);
117117 FrameAddress = Intrinsic::getDeclaration(TheModule, Intrinsic::frameaddress);
118118 return false;
119119 }
132132
133133 void WinEHStatePass::getAnalysisUsage(AnalysisUsage &AU) const {
134134 // This pass should only insert a stack allocation, memory accesses, and
135 // framerecovers.
135 // localrecovers.
136136 AU.setPreservesCFG();
137137 }
138138
418418 }
419419
420420 /// Escape RegNode so that we can access it from child handlers. Find the call
421 /// to frameescape, if any, in the entry block and append RegNode to the list
421 /// to localescape, if any, in the entry block and append RegNode to the list
422422 /// of arguments.
423423 int WinEHStatePass::escapeRegNode(Function &F) {
424 // Find the call to frameescape and extract its arguments.
424 // Find the call to localescape and extract its arguments.
425425 IntrinsicInst *EscapeCall = nullptr;
426426 for (Instruction &I : F.getEntryBlock()) {
427427 IntrinsicInst *II = dyn_cast(&I);
428 if (II && II->getIntrinsicID() == Intrinsic::frameescape) {
428 if (II && II->getIntrinsicID() == Intrinsic::localescape) {
429429 EscapeCall = II;
430430 break;
431431 }
398398 // at least if they do, are leaf functions that cause only finite stack
399399 // growth. In particular, the optimizer likes to form things like memsets
400400 // out of stores in the original IR. Another important example is
401 // llvm.frameescape which must occur in the entry block. Inserting a
402 // safepoint before it is not legal since it could push the frameescape
401 // llvm.localescape which must occur in the entry block. Inserting a
402 // safepoint before it is not legal since it could push the localescape
403403 // out of the entry block.
404404 return true;
405405 }
8080 }
8181
8282 ; CHECK-LABEL: define void @sink_alloca_to_catch()
83 ; CHECK: call void (...) @llvm.frameescape(i32* %only_used_in_catch)
83 ; CHECK: call void (...) @llvm.localescape(i32* %only_used_in_catch)
8484
8585 declare void @use_catch_var(i32*) #1
8686
161161 }
162162
163163 ; CHECK-LABEL: define void @dont_sink_alloca_to_catch(i32 %n)
164 ; CHECK: call void (...) @llvm.frameescape(i32* %live_in_out_catch)
164 ; CHECK: call void (...) @llvm.localescape(i32* %live_in_out_catch)
165165
166166 ; CHECK-LABEL: define internal i8* @sink_alloca_to_catch.catch(i8*, i8*)
167 ; CHECK: %only_used_in_catch.i8 = call i8* @llvm.framerecover({{.*}}, i32 0)
167 ; CHECK: %only_used_in_catch.i8 = call i8* @llvm.localrecover({{.*}}, i32 0)
168168 ; CHECK: %only_used_in_catch = bitcast
169169
170170 ; CHECK-LABEL: define internal i8* @dont_sink_alloca_to_catch.catch(i8*, i8*)
171 ; CHECK: %live_in_out_catch.i8 = call i8* @llvm.framerecover({{.*}}, i32 0)
171 ; CHECK: %live_in_out_catch.i8 = call i8* @llvm.localrecover({{.*}}, i32 0)
172172 ; CHECK: %live_in_out_catch = bitcast
173173
174174
4444 ; This is just a minimal check to verify that main was handled by WinEHPrepare.
4545 ; CHECK: define void @"\01?test@@YAXXZ"()
4646 ; CHECK: entry:
47 ; CHECK: call void (...) @llvm.frameescape
47 ; CHECK: call void (...) @llvm.localescape
4848 ; CHECK: invoke void @_CxxThrowException
4949 ; CHECK: }
5050
104104 ;
105105 ; CHECK-LABEL: define internal void @"\01?test@@YAXXZ.cleanup"(i8*, i8*)
106106 ; CHECK: entry:
107 ; CHECK: call i8* @llvm.framerecover
107 ; CHECK: call i8* @llvm.localrecover
108108 ; CHECK: call void @"\01??1Obj@@QEAA@XZ"
109109 ; CHECK: invoke void @llvm.donothing()
110110 ; CHECK: to label %[[SPLIT_LABEL:.+]] unwind label %[[LPAD_LABEL:.+]]
2323 ; CHECK: define void @_Z4testv()
2424 ; CHECK: entry:
2525 ; CHECK: [[I_PTR:\%.+]] = alloca i32, align 4
26 ; CHECK: call void (...) @llvm.frameescape(i32* [[I_PTR]])
26 ; CHECK: call void (...) @llvm.localescape(i32* [[I_PTR]])
2727 ; CHECK: invoke void @_Z9may_throwv()
2828 ; CHECK: to label %invoke.cont unwind label %[[LPAD_LABEL:lpad[0-9]*]]
2929
9595
9696 ; CHECK: define internal i8* @_Z4testv.catch(i8*, i8*)
9797 ; CHECK: entry:
98 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 0)
98 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 0)
9999 ; CHECK: [[I_PTR1:\%.+]] = bitcast i8* [[RECOVER_I]] to i32*
100100 ; CHECK: [[TMP:\%.+]] = load i32, i32* [[I_PTR1]], align 4
101101 ; CHECK: call void @_Z10handle_inti(i32 [[TMP]])
3535 ; CHECK: [[OBJ_PTR:\%.+]] = alloca %class.SomeClass
3636 ; CHECK: [[TMP0:\%.+]] = alloca i32, align 4
3737 ; CHECK: [[TMP1:\%.+]] = alloca i32, align 4
38 ; CHECK: call void (...) @llvm.frameescape(i32* [[TMP1]], %class.SomeClass* [[OBJ_PTR]], i32* [[TMP0]])
38 ; CHECK: call void (...) @llvm.localescape(i32* [[TMP1]], %class.SomeClass* [[OBJ_PTR]], i32* [[TMP0]])
3939 ; CHECK: %call = invoke %class.SomeClass* @"\01??0SomeClass@@QEAA@XZ"(%class.SomeClass* %obj)
4040 ; CHECK: to label %invoke.cont unwind label %[[LPAD_LABEL:lpad[0-9]*]]
4141
176176
177177 ; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*)
178178 ; CHECK: entry:
179 ; CHECK: [[RECOVER_TMP1:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
179 ; CHECK: [[RECOVER_TMP1:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
180180 ; CHECK: [[TMP1_PTR:\%.+]] = bitcast i8* [[RECOVER_TMP1]] to i32*
181181 ; CHECK: call void @"\01?handle_exception@@YAXXZ"()
182182 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %try.cont15)
184184
185185 ; CHECK-LABEL: define internal void @"\01?test@@YAXXZ.cleanup"(i8*, i8*)
186186 ; CHECK: entry:
187 ; CHECK: [[RECOVER_OBJ:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
187 ; CHECK: [[RECOVER_OBJ:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
188188 ; CHECK: [[OBJ_PTR:\%.+]] = bitcast i8* %obj.i8 to %class.SomeClass*
189189 ; CHECK: call void @"\01??1SomeClass@@QEAA@XZ"(%class.SomeClass* [[OBJ_PTR]])
190190 ; CHECK: ret void
192192
193193 ; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch.1"(i8*, i8*)
194194 ; CHECK: entry:
195 ; CHECK: [[RECOVER_TMP0:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
195 ; CHECK: [[RECOVER_TMP0:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
196196 ; CHECK: [[TMP0_PTR:\%.+]] = bitcast i8* [[RECOVER_TMP0]] to i32*
197197 ; CHECK: invoke void @"\01?handle_exception@@YAXXZ"()
198198 ; CHECK: to label %invoke.cont6 unwind label %[[LPAD5_LABEL:lpad[0-9]+]]
5757 ; CHECK: [[TMP:\%.+]] = bitcast %struct.SomeData* [[DATA_PTR]] to i8*
5858 ; CHECK: call void @llvm.memset(i8* [[TMP]], i8 0, i64 8, i32 4, i1 false)
5959 ; CHECK: store i32 0, i32* [[I_PTR]], align 4
60 ; CHECK: call void (...) @llvm.frameescape(i32* [[E_PTR]], i32* [[NUMEXCEPTIONS_PTR]], [10 x i32]* [[EXCEPTIONVAL_PTR]], i32* [[I_PTR]], %struct.SomeData* [[DATA_PTR]])
60 ; CHECK: call void (...) @llvm.localescape(i32* [[E_PTR]], i32* [[NUMEXCEPTIONS_PTR]], [10 x i32]* [[EXCEPTIONVAL_PTR]], i32* [[I_PTR]], %struct.SomeData* [[DATA_PTR]])
6161 ; CHECK: br label %for.cond
6262
6363 ; Function Attrs: uwtable
197197 ; The following catch handler should be outlined.
198198 ; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*)
199199 ; CHECK: entry:
200 ; CHECK: [[RECOVER_E:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
200 ; CHECK: [[RECOVER_E:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
201201 ; CHECK: [[E_PTR1:\%.+]] = bitcast i8* [[RECOVER_E]] to i32*
202 ; CHECK: [[RECOVER_NUMEXCEPTIONS:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
202 ; CHECK: [[RECOVER_NUMEXCEPTIONS:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
203203 ; CHECK: [[NUMEXCEPTIONS_PTR1:\%.+]] = bitcast i8* [[RECOVER_NUMEXCEPTIONS]] to i32*
204 ; CHECK: [[RECOVER_EXCEPTIONVAL:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
204 ; CHECK: [[RECOVER_EXCEPTIONVAL:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
205205 ; CHECK: [[EXCEPTIONVAL_PTR1:\%.+]] = bitcast i8* [[RECOVER_EXCEPTIONVAL]] to [10 x i32]*
206 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 3)
206 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 3)
207207 ; CHECK: [[I_PTR1:\%.+]] = bitcast i8* [[RECOVER_I]] to i32*
208 ; CHECK: [[RECOVER_DATA:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 4)
208 ; CHECK: [[RECOVER_DATA:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 4)
209209 ; CHECK: [[DATA_PTR1:\%.+]] = bitcast i8* [[RECOVER_DATA]] to %struct.SomeData*
210210 ; CHECK: [[TMP:\%.+]] = load i32, i32* [[E_PTR1]], align 4
211211 ; CHECK: [[TMP1:\%.+]] = load i32, i32* [[NUMEXCEPTIONS_PTR]], align 4
4040 ; CHECK: [[RETVAL:\%.+]] = alloca i32, align 4
4141 ; CHECK: [[E_PTR:\%.+]] = alloca i32, align 4
4242 ; CHECK: [[CLEANUP_SLOT:\%.+]] = alloca i32
43 ; CHECK: call void (...) @llvm.frameescape(i32* %e, <{ %struct.A }>** [[TMP_REGMEM]], i32* [[RETVAL]], i32* [[CLEANUP_SLOT]])
43 ; CHECK: call void (...) @llvm.localescape(i32* %e, <{ %struct.A }>** [[TMP_REGMEM]], i32* [[RETVAL]], i32* [[CLEANUP_SLOT]])
4444 ; CHECK: invoke void @"\01?may_throw@@YAXXZ"()
4545 ; CHECK: to label %invoke.cont unwind label %[[LPAD_LABEL:lpad[0-9]*]]
4646
138138 ; The following catch handler should be outlined.
139139 ; CHECK: define internal i8* @"\01?test@@YAHUA@@@Z.catch"(i8*, i8*)
140140 ; CHECK: entry:
141 ; CHECK: [[RECOVER_E:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 0)
141 ; CHECK: [[RECOVER_E:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 0)
142142 ; CHECK: [[E_PTR:\%.+]] = bitcast i8* [[RECOVER_E]] to i32*
143 ; CHECK: [[RECOVER_EH_TEMP:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 1)
143 ; CHECK: [[RECOVER_EH_TEMP:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 1)
144144 ; CHECK: [[EH_TEMP:\%.+]] = bitcast i8* [[RECOVER_EH_TEMP]] to <{ %struct.A }>**
145 ; CHECK: [[RECOVER_RETVAL:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 2)
145 ; CHECK: [[RECOVER_RETVAL:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 2)
146146 ; CHECK: [[RETVAL1:\%.+]] = bitcast i8* [[RECOVER_RETVAL]] to i32*
147 ; CHECK: [[RECOVER_CLEANUPSLOT:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 3)
147 ; CHECK: [[RECOVER_CLEANUPSLOT:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 3)
148148 ; CHECK: [[CLEANUPSLOT1:\%.+]] = bitcast i8* [[RECOVER_CLEANUPSLOT]] to i32*
149149 ; CHECK: [[E_I8PTR:\%.+]] = bitcast i32* [[E_PTR]] to i8*
150150 ; CHECK: [[TMP_RELOAD:\%.+]] = load <{ %struct.A }>*, <{ %struct.A }>** [[EH_TEMP]]
161161 ; The following cleanup handler should be outlined.
162162 ; CHECK: define internal void @"\01?test@@YAHUA@@@Z.cleanup"(i8*, i8*)
163163 ; CHECK: entry:
164 ; CHECK: [[RECOVER_EH_TEMP1:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 1)
164 ; CHECK: [[RECOVER_EH_TEMP1:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 1)
165165 ; CHECK: [[EH_TEMP1:\%.+]] = bitcast i8* [[RECOVER_EH_TEMP]] to <{ %struct.A }>**
166166 ; CHECK: [[TMP_RELOAD1:\%.+]] = load <{ %struct.A }>*, <{ %struct.A }>** [[EH_TEMP1]]
167167 ; CHECK: [[A3:\%.+]] = getelementptr inbounds <{ %struct.A }>, <{ %struct.A }>* [[TMP_RELOAD1]], i32 0, i32 0
2424 ; CHECK: entry:
2525 ; CHECK: [[OBJ_PTR:\%.+]] = alloca %class.SomeClass, align 4
2626 ; CHECK: call void @_ZN9SomeClassC1Ev(%class.SomeClass* [[OBJ_PTR]])
27 ; CHECK: call void (...) @llvm.frameescape(%class.SomeClass* [[OBJ_PTR]])
27 ; CHECK: call void (...) @llvm.localescape(%class.SomeClass* [[OBJ_PTR]])
2828 ; CHECK: invoke void @_Z9may_throwv()
2929 ; CHECK: to label %invoke.cont unwind label %[[LPAD_LABEL:lpad[0-9]*]]
3030
7373 ; This cleanup handler should be outlined.
7474 ; CHECK: define internal void @_Z4testv.cleanup(i8*, i8*)
7575 ; CHECK: entry:
76 ; CHECK: [[RECOVER_OBJ:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 0)
76 ; CHECK: [[RECOVER_OBJ:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 0)
7777 ; CHECK: [[OBJ_PTR1:\%.+]] = bitcast i8* [[RECOVER_OBJ]] to %class.SomeClass*
7878 ; CHECK: call void @_ZN9SomeClassD1Ev(%class.SomeClass* [[OBJ_PTR1]])
7979 ; CHECK: ret void
3030 ;
3131 ; CHECK-LABEL: define void @"\01?test@@YAXXZ"()
3232 ; CHECK: entry:
33 ; CHECK: call void (...) @llvm.frameescape
33 ; CHECK: call void (...) @llvm.localescape
3434 ; CHECK: }
3535
3636 ; Function Attrs: nounwind uwtable
6666 ; Verify that a cleanup handler was created and that it calls ~Obj().
6767 ; CHECK-LABEL: define internal void @"\01?test@@YAXXZ.cleanup"(i8*, i8*)
6868 ; CHECK: entry:
69 ; CHECK: @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
69 ; CHECK: @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
7070 ; CHECK: call void @"\01??1Obj@@QEAA@XZ"
7171 ; CHECK: ret void
7272 ; CHECK: }
4949 ; CHECK: [[OBJ_PTR:\%.+]] = alloca %class.SomeClass*, align 8
5050 ; CHECK: [[LL_PTR:\%.+]] = alloca i64, align 8
5151 ; CHECK: [[I_PTR:\%.+]] = alloca i32, align 4
52 ; CHECK: call void (...) @llvm.frameescape(i32* [[I_PTR]], i64* [[LL_PTR]], %class.SomeClass** [[OBJ_PTR]])
52 ; CHECK: call void (...) @llvm.localescape(i32* [[I_PTR]], i64* [[LL_PTR]], %class.SomeClass** [[OBJ_PTR]])
5353 ; CHECK: invoke void @"\01?may_throw@@YAXXZ"()
5454 ; CHECK: to label %invoke.cont unwind label %[[LPAD_LABEL:lpad[0-9]*]]
5555
160160
161161 ; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*)
162162 ; CHECK: entry:
163 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
163 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
164164 ; CHECK: [[I_PTR:\%.+]] = bitcast i8* [[RECOVER_I]] to i32*
165165 ; CHECK: [[TMP1:\%.+]] = load i32, i32* [[I_PTR]], align 4
166166 ; CHECK: call void @"\01?handle_int@@YAXH@Z"(i32 [[TMP1]])
169169
170170 ; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch.1"(i8*, i8*)
171171 ; CHECK: entry:
172 ; CHECK: [[RECOVER_LL:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
172 ; CHECK: [[RECOVER_LL:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
173173 ; CHECK: [[LL_PTR:\%.+]] = bitcast i8* [[RECOVER_LL]] to i64*
174174 ; CHECK: [[TMP2:\%.+]] = load i64, i64* [[LL_PTR]], align 8
175175 ; CHECK: call void @"\01?handle_long_long@@YAX_J@Z"(i64 [[TMP2]])
178178
179179 ; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch.2"(i8*, i8*)
180180 ; CHECK: entry:
181 ; CHECK: [[RECOVER_OBJ:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
181 ; CHECK: [[RECOVER_OBJ:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
182182 ; CHECK: [[OBJ_PTR:\%.+]] = bitcast i8* [[RECOVER_OBJ]] to %class.SomeClass**
183183 ; CHECK: [[TMP3:\%.+]] = load %class.SomeClass*, %class.SomeClass** [[OBJ_PTR]], align 8
184184 ; CHECK: call void @"\01?handle_obj@@YAXPEAVSomeClass@@@Z"(%class.SomeClass* [[TMP3]])
3333 ; CHECK: entry:
3434 ; CHECK: %i = alloca i32, align 4
3535 ; CHECK: %f = alloca float, align 4
36 ; CHECK: call void (...) @llvm.frameescape(float* %f, i32* %i)
36 ; CHECK: call void (...) @llvm.localescape(float* %f, i32* %i)
3737 ; CHECK: invoke void @"\01?may_throw@@YAXXZ"()
3838 ; CHECK: to label %invoke.cont unwind label %[[LPAD_LABEL:lpad[0-9]*]]
3939
135135
136136 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*)
137137 ; CHECK: entry:
138 ; CHECK: [[RECOVER_F1:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
138 ; CHECK: [[RECOVER_F1:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
139139 ; CHECK: [[F_PTR1:\%.+]] = bitcast i8* [[RECOVER_F1]] to float*
140140 ; CHECK: [[TMP2:\%.+]] = load float, float* [[F_PTR1]], align 4
141141 ; CHECK: call void @"\01?handle_float@@YAXM@Z"(float [[TMP2]])
144144
145145 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch.1"(i8*, i8*)
146146 ; CHECK: entry:
147 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
147 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
148148 ; CHECK: [[I_PTR:\%.+]] = bitcast i8* [[RECOVER_I]] to i32*
149149 ; CHECK: [[TMP1:\%.+]] = load i32, i32* [[I_PTR]], align 4
150150 ; CHECK: invoke void @"\01?handle_int@@YAXH@Z"(i32 [[TMP1]])
4343 ; CHECK: %inner = alloca %class.Inner, align 1
4444 ; CHECK: %i = alloca i32, align 4
4545 ; CHECK: %f = alloca float, align 4
46 ; CHECK: call void (...) @llvm.frameescape(float* %f, i32* %i, %class.Outer* %outer, %class.Inner* %inner)
46 ; CHECK: call void (...) @llvm.localescape(float* %f, i32* %i, %class.Outer* %outer, %class.Inner* %inner)
4747 ; CHECK: invoke void @_ZN5OuterC1Ev(%class.Outer* %outer)
4848 ; CHECK: to label %invoke.cont unwind label %[[LPAD_LABEL:lpad[0-9]*]]
4949
242242 ; This catch handler should be outlined.
243243 ; CHECK: define internal i8* @_Z4testv.catch(i8*, i8*)
244244 ; CHECK: entry:
245 ; CHECK: [[RECOVER_F:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 0)
245 ; CHECK: [[RECOVER_F:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 0)
246246 ; CHECK: [[F_PTR:\%.+]] = bitcast i8* [[RECOVER_F]] to float*
247247 ; CHECK: [[TMP:\%.+]] = load float, float* [[F_PTR]], align 4
248248 ; CHECK: call void @_Z12handle_floatf(float [[TMP]])
252252 ; This catch handler should be outlined.
253253 ; CHECK: define internal i8* @_Z4testv.catch.1(i8*, i8*)
254254 ; CHECK: entry:
255 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 1)
255 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 1)
256256 ; CHECK: [[I_PTR:\%.+]] = bitcast i8* [[RECOVER_I]] to i32*
257257 ; CHECK: [[TMP1:\%.+]] = load i32, i32* [[I_PTR]], align 4
258258 ; CHECK: invoke void @_Z10handle_inti(i32 [[TMP1]])
269269 ; This cleanup handler should be outlined.
270270 ; CHECK: define internal void @_Z4testv.cleanup(i8*, i8*)
271271 ; CHECK: entry:
272 ; CHECK: [[RECOVER_OUTER:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 2)
272 ; CHECK: [[RECOVER_OUTER:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 2)
273273 ; CHECK: [[OUTER_PTR:\%.+]] = bitcast i8* [[RECOVER_OUTER]] to %class.Outer*
274274 ; CHECK: call void @_ZN5OuterD1Ev(%class.Outer* [[OUTER_PTR]])
275275 ; CHECK: ret void
278278 ; This cleanup handler should be outlined.
279279 ; CHECK: define internal void @_Z4testv.cleanup.2(i8*, i8*)
280280 ; CHECK: entry:
281 ; CHECK: [[RECOVER_INNER:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 3)
281 ; CHECK: [[RECOVER_INNER:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 3)
282282 ; CHECK: [[INNER_PTR:\%.+]] = bitcast i8* [[RECOVER_INNER]] to %class.Inner*
283283 ; CHECK: call void @_ZN5InnerD1Ev(%class.Inner* [[INNER_PTR]])
284284 ; CHECK: ret void
4040 ; CHECK: %i = alloca i32, align 4
4141 ; CHECK: %j = alloca i32, align 4
4242 ; CHECK: %f = alloca float, align 4
43 ; CHECK: call void (...) @llvm.frameescape(i32* %j, i32* %i, float* %f)
43 ; CHECK: call void (...) @llvm.localescape(i32* %j, i32* %i, float* %f)
4444 ; CHECK: invoke void @"\01?may_throw@@YAXXZ"()
4545 ; CHECK: to label %invoke.cont unwind label %[[LPAD_LABEL:lpad[0-9]*]]
4646
180180
181181 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*)
182182 ; CHECK: entry:
183 ; CHECK: [[RECOVER_J:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
183 ; CHECK: [[RECOVER_J:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
184184 ; CHECK: [[J_PTR:\%.+]] = bitcast i8* [[RECOVER_J]] to i32*
185 ; CHECK: [[RECOVER_I1:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
185 ; CHECK: [[RECOVER_I1:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
186186 ; CHECK: [[I_PTR1:\%.+]] = bitcast i8* [[RECOVER_I1]] to i32*
187187 ; CHECK: [[TMP3:\%.+]] = load i32, i32* [[J_PTR]], align 4
188188 ; CHECK: store i32 [[TMP3]], i32* [[I_PTR1]]
191191
192192 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch.1"(i8*, i8*)
193193 ; CHECK: entry:
194 ; CHECK: [[RECOVER_F:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
194 ; CHECK: [[RECOVER_F:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
195195 ; CHECK: [[F_PTR:\%.+]] = bitcast i8* [[RECOVER_F]] to float*
196196 ; CHECK: [[TMP2:\%.+]] = load float, float* [[F_PTR]], align 4
197197 ; CHECK: call void @"\01?handle_float@@YAXM@Z"(float [[TMP2]])
200200
201201 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch.2"(i8*, i8*)
202202 ; CHECK: entry:
203 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
203 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
204204 ; CHECK: [[I_PTR:\%.+]] = bitcast i8* [[RECOVER_I]] to i32*
205205 ; CHECK: invoke void @"\01?may_throw@@YAXXZ"()
206206 ; CHECK: to label %invoke.cont2 unwind label %[[LPAD1_LABEL:lpad[0-9]*]]
5252
5353 ; CHECK-LABEL: define void @"\01?test1@@YAXXZ"()
5454 ; CHECK: entry:
55 ; CHECK: call void (...) @llvm.frameescape
55 ; CHECK: call void (...) @llvm.localescape
5656
5757 ; Function Attrs: nounwind uwtable
5858 define void @"\01?test1@@YAXXZ"() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
120120
121121 ; CHECK-LABEL: define void @"\01?test2@@YAXXZ"()
122122 ; CHECK: entry:
123 ; CHECK: call void (...) @llvm.frameescape
123 ; CHECK: call void (...) @llvm.localescape
124124
125125 ; Function Attrs: nounwind uwtable
126126 define void @"\01?test2@@YAXXZ"() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
6767 ; CHECK: store i32* [[A_PTR]], i32** [[A_REGMEM]]
6868 ; CHECK: [[B_PTR:\%.+]] = getelementptr inbounds %struct.SomeData, %struct.SomeData* [[TMPCAST]], i64 0, i32 1
6969 ; CHECK: store i32* [[B_PTR]], i32** [[B_REGMEM]]
70 ; CHECK: call void (...) @llvm.frameescape(i32* %e, i32* %NumExceptions.020.reg2mem, [10 x i32]* [[EXCEPTIONVAL]], i32* %inc.reg2mem, i32* [[I_REGMEM]], i32** [[A_REGMEM]], i32** [[B_REGMEM]])
70 ; CHECK: call void (...) @llvm.localescape(i32* %e, i32* %NumExceptions.020.reg2mem, [10 x i32]* [[EXCEPTIONVAL]], i32* %inc.reg2mem, i32* [[I_REGMEM]], i32** [[A_REGMEM]], i32** [[B_REGMEM]])
7171 ; CHECK: br label %for.body
7272
7373 ; Function Attrs: uwtable
191191 ; The following catch handler should be outlined.
192192 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*)
193193 ; CHECK: entry:
194 ; CHECK: [[RECOVER_E:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
194 ; CHECK: [[RECOVER_E:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
195195 ; CHECK: [[E_PTR:\%.+]] = bitcast i8* [[RECOVER_E]] to i32*
196 ; CHECK: [[RECOVER_NUMEXCEPTIONS:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
196 ; CHECK: [[RECOVER_NUMEXCEPTIONS:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
197197 ; CHECK: [[NUMEXCEPTIONS_REGMEM:\%.+]] = bitcast i8* [[RECOVER_NUMEXCEPTIONS]] to i32*
198 ; CHECK: [[RECOVER_EXCEPTIONVAL:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
198 ; CHECK: [[RECOVER_EXCEPTIONVAL:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
199199 ; CHECK: [[EXCEPTIONVAL:\%.+]] = bitcast i8* [[RECOVER_EXCEPTIONVAL]] to [10 x i32]*
200 ; CHECK: [[RECOVER_INC:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 3)
200 ; CHECK: [[RECOVER_INC:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 3)
201201 ; CHECK: [[INC_REGMEM:\%.+]] = bitcast i8* [[RECOVER_INC]] to i32*
202 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 4)
202 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 4)
203203 ; CHECK: [[I_REGMEM:\%.+]] = bitcast i8* [[RECOVER_I]] to i32*
204 ; CHECK: [[RECOVER_A:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 5)
204 ; CHECK: [[RECOVER_A:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 5)
205205 ; CHECK: [[A_REGMEM:\%.+]] = bitcast i8* [[RECOVER_A]] to i32**
206 ; CHECK: [[RECOVER_B:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 6)
206 ; CHECK: [[RECOVER_B:\%.+]] = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 6)
207207 ; CHECK: [[B_REGMEM:\%.+]] = bitcast i8* [[RECOVER_B]] to i32**
208208 ; CHECK: [[E_I8PTR:\%.+]] = bitcast i32* [[E_PTR]] to i8*
209209 ; CHECK: [[TMP:\%.+]] = load i32, i32* [[E_PTR]], align 4
4848 %e = alloca i32, align 4
4949 %0 = bitcast i32* %tmp.i to i8*
5050 store i32 42, i32* %tmp.i, align 4, !tbaa !2
51 call void (...) @llvm.frameescape(i32* %e)
51 call void (...) @llvm.localescape(i32* %e)
5252 invoke void @_CxxThrowException(i8* %0, %eh.ThrowInfo* @_TI1H) #6
5353 to label %.noexc unwind label %lpad1
5454
9191
9292 define internal i8* @main.catch(i8*, i8*) #5 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
9393 entry:
94 %e.i8 = call i8* @llvm.framerecover(i8* bitcast (i32 ()* @main to i8*), i8* %1, i32 0)
94 %e.i8 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @main to i8*), i8* %1, i32 0)
9595 %e = bitcast i8* %e.i8 to i32*
9696 %2 = bitcast i32* %e to i8*
9797 %3 = load i32, i32* %e, align 4, !tbaa !2
138138 declare void @llvm.donothing() #2
139139
140140 ; Function Attrs: nounwind
141 declare void @llvm.frameescape(...) #3
141 declare void @llvm.localescape(...) #3
142142
143143 ; Function Attrs: nounwind readnone
144 declare i8* @llvm.framerecover(i8*, i8*, i32) #2
144 declare i8* @llvm.localrecover(i8*, i8*, i32) #2
145145
146146 attributes #0 = { noreturn uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "unsafe-fp-math"="false" "use-soft-float"="false" }
147147 attributes #1 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "unsafe-fp-math"="false" "use-soft-float"="false" "wineh-parent"="main" }
3131
3232 define internal i8* @"\01?f@@YAXXZ.catch"(i8*, i8*) #4 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
3333 entry:
34 %.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?f@@YAXXZ" to i8*), i8* %1, i32 0)
34 %.i8 = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?f@@YAXXZ" to i8*), i8* %1, i32 0)
3535 %bc2 = bitcast i8* %.i8 to i32**
3636 %bc3 = bitcast i32** %bc2 to i8*
3737 invoke void @"\01?may_throw@@YAXXZ"()
5757
5858 define internal i8* @"\01?f@@YAXXZ.catch1"(i8*, i8*) #4 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
5959 entry:
60 %.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?f@@YAXXZ" to i8*), i8* %1, i32 1)
60 %.i8 = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?f@@YAXXZ" to i8*), i8* %1, i32 1)
6161 %2 = bitcast i8* %.i8 to double*
6262 %3 = bitcast double* %2 to i8*
6363 invoke void () @llvm.donothing()
8787 %ehselector.slot = alloca i32
8888 %0 = alloca i32*, align 8
8989 %1 = alloca double, align 8
90 call void (...) @llvm.frameescape(i32** %0, double* %1)
90 call void (...) @llvm.localescape(i32** %0, double* %1)
9191 invoke void @"\01?may_throw@@YAXXZ"()
9292 to label %invoke.cont unwind label %lpad2
9393
195195 declare i8* @llvm.eh.actions(...) #3
196196
197197 ; Function Attrs: nounwind
198 declare void @llvm.frameescape(...) #3
198 declare void @llvm.localescape(...) #3
199199
200200 ; Function Attrs: nounwind readnone
201 declare i8* @llvm.framerecover(i8*, i8*, i32) #2
201 declare i8* @llvm.localrecover(i8*, i8*, i32) #2
202202
203203 declare void @llvm.donothing()
204204
5757 %ehselector.slot = alloca i32
5858 store i32 0, i32* %tmp
5959 %0 = bitcast i32* %tmp to i8*
60 call void (...) @llvm.frameescape()
60 call void (...) @llvm.localescape()
6161 store volatile i64 -2, i64* %unwindhelp
6262 %1 = bitcast i64* %unwindhelp to i8*
6363 call void @llvm.eh.unwindhelp(i8* %1)
125125 %s1 = alloca %struct.S, align 1
126126 %frombool = zext i1 %b to i8
127127 store i8 %frombool, i8* %b.addr, align 1
128 call void (...) @llvm.frameescape(%struct.S* %s, %struct.S* %s1)
128 call void (...) @llvm.localescape(%struct.S* %s, %struct.S* %s1)
129129 call void @"\01?may_throw@@YAXXZ"()
130130 invoke void @"\01?may_throw@@YAXXZ"()
131131 to label %invoke.cont unwind label %lpad1
187187 }
188188
189189 ; Function Attrs: nounwind
190 declare void @llvm.frameescape(...) #4
190 declare void @llvm.localescape(...) #4
191191
192192 ; Function Attrs: nounwind readnone
193 declare i8* @llvm.framerecover(i8*, i8*, i32) #6
193 declare i8* @llvm.localrecover(i8*, i8*, i32) #6
194194
195195 ; Function Attrs: nounwind
196196 declare void @llvm.eh.unwindhelp(i8*) #4
197197
198198 define internal void @"\01?test2@@YAX_N@Z.cleanup"(i8*, i8*) #7 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
199199 entry:
200 %s.i8 = call i8* @llvm.framerecover(i8* bitcast (void (i1)* @"\01?test2@@YAX_N@Z" to i8*), i8* %1, i32 0)
200 %s.i8 = call i8* @llvm.localrecover(i8* bitcast (void (i1)* @"\01?test2@@YAX_N@Z" to i8*), i8* %1, i32 0)
201201 %s = bitcast i8* %s.i8 to %struct.S*
202202 call void @"\01??_DS@@QEAA@XZ"(%struct.S* %s) #4
203203 invoke void @llvm.donothing()
214214
215215 define internal void @"\01?test2@@YAX_N@Z.cleanup1"(i8*, i8*) #7 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
216216 entry:
217 %s1.i8 = call i8* @llvm.framerecover(i8* bitcast (void (i1)* @"\01?test2@@YAX_N@Z" to i8*), i8* %1, i32 1)
217 %s1.i8 = call i8* @llvm.localrecover(i8* bitcast (void (i1)* @"\01?test2@@YAX_N@Z" to i8*), i8* %1, i32 1)
218218 %s1 = bitcast i8* %s1.i8 to %struct.S*
219219 call void @"\01??_DS@@QEAA@XZ"(%struct.S* %s1) #4
220220 invoke void @llvm.donothing()
2929
3030 ; CHECK-LABEL: define void @"\01?f@@YAXXZ"()
3131 ; CHECK: entry:
32 ; CHECK: call void (...) @llvm.frameescape()
32 ; CHECK: call void (...) @llvm.localescape()
3333 ; CHECK: invoke void @"\01?g@@YAXXZ"()
3434
3535 ; Function Attrs: nounwind
8585 ; This is just a minimal check to verify that main was handled by WinEHPrepare.
8686 ; CHECK: define i32 @main()
8787 ; CHECK: entry:
88 ; CHECK: call void (...) @llvm.frameescape(i32* [[X_PTR:\%.+]], i32* [[X2_PTR:\%.+]], i8* [[C2_PTR:\%.+]], i8* [[C3_PTR:\%.+]], i8* [[C_PTR:\%.+]])
88 ; CHECK: call void (...) @llvm.localescape(i32* [[X_PTR:\%.+]], i32* [[X2_PTR:\%.+]], i8* [[C2_PTR:\%.+]], i8* [[C3_PTR:\%.+]], i8* [[C_PTR:\%.+]])
8989 ; CHECK: invoke void @_CxxThrowException
9090 ; CHECK: }
9191
7878 call void @"\01?two@@YAXXZ"() #3
7979 store i32 2, i32* %tmp
8080 %0 = bitcast i32* %tmp to i8*
81 call void (...) @llvm.frameescape(i32* %x, i8* %c, i32* %x21)
81 call void (...) @llvm.localescape(i32* %x, i8* %c, i32* %x21)
8282 invoke void @_CxxThrowException(i8* %0, %eh.ThrowInfo* @_TI1H) #5
8383 to label %unreachable unwind label %lpad
8484
165165
166166 define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*) #4 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
167167 entry:
168 %x.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
168 %x.i8 = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
169169 %x = bitcast i8* %x.i8 to i32*
170170 %2 = bitcast i32* %x to i8*
171171 call void @"\01?catch_two@@YAXXZ"() #3
203203
204204 define internal i8* @"\01?test@@YAXXZ.catch2"(i8*, i8*) #4 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
205205 entry:
206 %x21.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
206 %x21.i8 = call i8* @llvm.localrecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
207207 %x21 = bitcast i8* %x21.i8 to i32*
208208 %2 = bitcast i32* %x21 to i8*
209209 call void @"\01?catch_one@@YAXXZ"() #3
237237 }
238238
239239 ; Function Attrs: nounwind
240 declare void @llvm.frameescape(...) #3
240 declare void @llvm.localescape(...) #3
241241
242242 ; Function Attrs: nounwind readnone
243 declare i8* @llvm.framerecover(i8*, i8*, i32) #2
243 declare i8* @llvm.localrecover(i8*, i8*, i32) #2
244244
245245 attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" "wineh-parent"="?test@@YAXXZ" }
246246 attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
1212 declare i32 @puts(i8*)
1313 declare void @may_crash()
1414 declare i32 @__C_specific_handler(...)
15 declare i8* @llvm.framerecover(i8*, i8*, i32) #1
15 declare i8* @llvm.localrecover(i8*, i8*, i32) #1
1616 declare i8* @llvm.frameaddress(i32)
17 declare void @llvm.frameescape(...)
17 declare void @llvm.localescape(...)
1818 declare dllimport void @EnterCriticalSection(%struct._RTL_CRITICAL_SECTION*)
1919 declare dllimport void @LeaveCriticalSection(%struct._RTL_CRITICAL_SECTION*)
2020
4646 define i32 @call_may_crash_locked() personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
4747 entry:
4848 %p = alloca %struct._RTL_CRITICAL_SECTION, align 8
49 call void (...) @llvm.frameescape(%struct._RTL_CRITICAL_SECTION* %p)
49 call void (...) @llvm.localescape(%struct._RTL_CRITICAL_SECTION* %p)
5050 call void @EnterCriticalSection(%struct._RTL_CRITICAL_SECTION* %p)
5151 invoke void @may_crash()
5252 to label %invoke.cont unwind label %lpad
5353
5454 invoke.cont: ; preds = %entry
5555 %tmp2 = call i8* @llvm.frameaddress(i32 0)
56 %tmp3 = call i8* @llvm.framerecover(i8* bitcast (i32 ()* @call_may_crash_locked to i8*), i8* %tmp2, i32 0) #2
56 %tmp3 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @call_may_crash_locked to i8*), i8* %tmp2, i32 0) #2
5757 %tmp6 = bitcast i8* %tmp3 to %struct._RTL_CRITICAL_SECTION*
5858 call void @LeaveCriticalSection(%struct._RTL_CRITICAL_SECTION* %tmp6)
5959 ret i32 42
6262 %tmp7 = landingpad { i8*, i32 }
6363 cleanup
6464 %tmp8 = call i8* @llvm.frameaddress(i32 0)
65 %tmp9 = call i8* @llvm.framerecover(i8* bitcast (i32 ()* @call_may_crash_locked to i8*), i8* %tmp8, i32 0)
65 %tmp9 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @call_may_crash_locked to i8*), i8* %tmp8, i32 0)
6666 %tmp12 = bitcast i8* %tmp9 to %struct._RTL_CRITICAL_SECTION*
6767 call void @LeaveCriticalSection(%struct._RTL_CRITICAL_SECTION* %tmp12)
6868 resume { i8*, i32 } %tmp7
7777 ; CHECK-NEXT: indirectbr i8* %recover, []
7878
7979 ; CHECK-LABEL: define internal void @call_may_crash_locked.cleanup(i8*, i8*)
80 ; CHECK: %tmp9 = call i8* @llvm.framerecover(i8* bitcast (i32 ()* @call_may_crash_locked to i8*), i8* %1, i32 0)
80 ; CHECK: %tmp9 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @call_may_crash_locked to i8*), i8* %1, i32 0)
8181 ; CHECK: %tmp12 = bitcast i8* %tmp9 to %struct._RTL_CRITICAL_SECTION*
8282 ; CHECK: call void @LeaveCriticalSection(%struct._RTL_CRITICAL_SECTION* %tmp12)
1616 ; Function Attrs: uwtable
1717 define void @do_except() #0 personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
1818 entry:
19 call void (...) @llvm.frameescape()
19 call void (...) @llvm.localescape()
2020 invoke void @g() #5
2121 to label %__try.cont unwind label %lpad1
2222
6363 declare i8* @llvm.eh.actions(...) #4
6464
6565 ; Function Attrs: nounwind
66 declare void @llvm.frameescape(...) #4
66 declare void @llvm.localescape(...) #4
6767
6868 ; Function Attrs: nounwind readnone
69 declare i8* @llvm.framerecover(i8*, i8*, i32) #3
69 declare i8* @llvm.localrecover(i8*, i8*, i32) #3
7070
7171 attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "unsafe-fp-math"="false" "use-soft-float"="false" "wineh-parent"="do_except" }
7272 attributes #1 = { noinline nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "unsafe-fp-math"="false" "use-soft-float"="false" }
195195 ; X64-LABEL: define internal void @lpad_phi.cleanup(i8*, i8*)
196196 ; X86-LABEL: define internal void @lpad_phi.cleanup()
197197 ; X86: call i8* @llvm.frameaddress(i32 1)
198 ; CHECK: call i8* @llvm.framerecover({{.*}})
198 ; CHECK: call i8* @llvm.localrecover({{.*}})
199199 ; CHECK: load i32
200200 ; CHECK: store i32 %{{.*}}, i32*
0 ; RUN: llc -mtriple=i686-windows-msvc < %s | FileCheck %s --check-prefix=X86
11 ; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s --check-prefix=X64
22
3 declare void @llvm.frameescape(...)
3 declare void @llvm.localescape(...)
44 declare i8* @llvm.frameaddress(i32)
5 declare i8* @llvm.framerecover(i8*, i8*, i32)
5 declare i8* @llvm.localrecover(i8*, i8*, i32)
66 declare i32 @printf(i8*, ...)
77
88 @str = internal constant [10 x i8] c"asdf: %d\0A\00"
99
1010 define void @print_framealloc_from_fp(i8* %fp) {
11 %a.i8 = call i8* @llvm.framerecover(i8* bitcast (void()* @alloc_func to i8*), i8* %fp, i32 0)
11 %a.i8 = call i8* @llvm.localrecover(i8* bitcast (void()* @alloc_func to i8*), i8* %fp, i32 0)
1212 %a = bitcast i8* %a.i8 to i32*
1313 %a.val = load i32, i32* %a
1414 call i32 (i8*, ...) @printf(i8* getelementptr ([10 x i8], [10 x i8]* @str, i32 0, i32 0), i32 %a.val)
15 %b.i8 = call i8* @llvm.framerecover(i8* bitcast (void()* @alloc_func to i8*), i8* %fp, i32 1)
15 %b.i8 = call i8* @llvm.localrecover(i8* bitcast (void()* @alloc_func to i8*), i8* %fp, i32 1)
1616 %b = bitcast i8* %b.i8 to i32*
1717 %b.val = load i32, i32* %b
1818 call i32 (i8*, ...) @printf(i8* getelementptr ([10 x i8], [10 x i8]* @str, i32 0, i32 0), i32 %b.val)
6060 define void @alloc_func() {
6161 %a = alloca i32
6262 %b = alloca i32, i32 2
63 call void (...) @llvm.frameescape(i32* %a, i32* %b)
63 call void (...) @llvm.localescape(i32* %a, i32* %b)
6464 store i32 42, i32* %a
6565 store i32 13, i32* %b
6666 %fp = call i8* @llvm.frameaddress(i32 0)
104104 define void @alloc_func_no_frameaddr() {
105105 %a = alloca i32
106106 %b = alloca i32
107 call void (...) @llvm.frameescape(i32* %a, i32* %b)
107 call void (...) @llvm.localescape(i32* %a, i32* %b)
108108 store i32 42, i32* %a
109109 store i32 13, i32* %b
110110 call void @print_framealloc_from_fp(i8* null)
99 declare i32 @printf(i8* nocapture readonly, ...) nounwind
1010 declare i32 @llvm.eh.typeid.for(i8*)
1111 declare i8* @llvm.frameaddress(i32)
12 declare i8* @llvm.framerecover(i8*, i8*, i32)
13 declare void @llvm.frameescape(...)
12 declare i8* @llvm.localrecover(i8*, i8*, i32)
13 declare void @llvm.localescape(...)
1414 declare i8* @llvm.x86.seh.recoverfp(i8*, i8*)
1515
1616 define i32 @main() personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) {
1717 entry:
1818 %__exceptioncode = alloca i32, align 4
19 call void (...) @llvm.frameescape(i32* %__exceptioncode)
19 call void (...) @llvm.localescape(i32* %__exceptioncode)
2020 invoke void @crash() #5
2121 to label %__try.cont unwind label %lpad
2222
4444 entry:
4545 %ebp = tail call i8* @llvm.frameaddress(i32 1)
4646 %parentfp = tail call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @main to i8*), i8* %ebp)
47 %code.i8 = tail call i8* @llvm.framerecover(i8* bitcast (i32 ()* @main to i8*), i8* %parentfp, i32 0)
47 %code.i8 = tail call i8* @llvm.localrecover(i8* bitcast (i32 ()* @main to i8*), i8* %parentfp, i32 0)
4848 %__exceptioncode = bitcast i8* %code.i8 to i32*
4949 %info.addr = getelementptr inbounds i8, i8* %ebp, i32 -20
5050 %0 = bitcast i8* %info.addr to i32***
0 ; RUN: opt -inline -S < %s | FileCheck %s
11
2 ; PR23216: We can't inline functions using llvm.frameescape.
2 ; PR23216: We can't inline functions using llvm.localescape.
33
4 declare void @llvm.frameescape(...)
4 declare void @llvm.localescape(...)
55 declare i8* @llvm.frameaddress(i32)
6 declare i8* @llvm.framerecover(i8*, i8*, i32)
6 declare i8* @llvm.localrecover(i8*, i8*, i32)
77
88 define internal void @foo(i8* %fp) {
9 %a.i8 = call i8* @llvm.framerecover(i8* bitcast (i32 ()* @bar to i8*), i8* %fp, i32 0)
9 %a.i8 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @bar to i8*), i8* %fp, i32 0)
1010 %a = bitcast i8* %a.i8 to i32*
1111 store i32 42, i32* %a
1212 ret void
1515 define internal i32 @bar() {
1616 entry:
1717 %a = alloca i32
18 call void (...) @llvm.frameescape(i32* %a)
18 call void (...) @llvm.localescape(i32* %a)
1919 %fp = call i8* @llvm.frameaddress(i32 0)
2020 tail call void @foo(i8* %fp)
2121 %r = load i32, i32* %a
2626 define internal i32 @bar_alwaysinline() alwaysinline {
2727 entry:
2828 %a = alloca i32
29 call void (...) @llvm.frameescape(i32* %a)
29 call void (...) @llvm.localescape(i32* %a)
3030 tail call void @foo(i8* null)
3131 ret i32 0
3232 }
0 ; RUN: opt %s -S -place-safepoints | FileCheck %s
11
2 declare void @llvm.frameescape(...)
2 declare void @llvm.localescape(...)
33
4 ; Do we insert the entry safepoint after the frameescape intrinsic?
4 ; Do we insert the entry safepoint after the localescape intrinsic?
55 define void @parent() gc "statepoint-example" {
66 ; CHECK-LABEL: @parent
77 entry:
88 ; CHECK-LABEL: entry
99 ; CHECK-NEXT: alloca
10 ; CHECK-NEXT: frameescape
10 ; CHECK-NEXT: localescape
1111 ; CHECK-NEXT: statepoint
1212 %ptr = alloca i32
13 call void (...) @llvm.frameescape(i32* %ptr)
13 call void (...) @llvm.localescape(i32* %ptr)
1414 ret void
1515 }
1616
0 ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
11
2 declare void @llvm.frameescape(...)
3 declare i8* @llvm.framerecover(i8*, i8*, i32)
2 declare void @llvm.localescape(...)
3 declare i8* @llvm.localrecover(i8*, i8*, i32)
44
55 define internal void @f() {
66 %a = alloca i8
7 call void (...) @llvm.frameescape(i8* %a)
8 call void (...) @llvm.frameescape(i8* %a)
7 call void (...) @llvm.localescape(i8* %a)
8 call void (...) @llvm.localescape(i8* %a)
99 ret void
1010 }
11 ; CHECK: multiple calls to llvm.frameescape in one function
11 ; CHECK: multiple calls to llvm.localescape in one function
1212
1313 define internal void @g() {
1414 entry:
1515 %a = alloca i8
1616 br label %not_entry
1717 not_entry:
18 call void (...) @llvm.frameescape(i8* %a)
18 call void (...) @llvm.localescape(i8* %a)
1919 ret void
2020 }
21 ; CHECK: llvm.frameescape used outside of entry block
21 ; CHECK: llvm.localescape used outside of entry block
2222
2323 define internal void @h() {
24 call i8* @llvm.framerecover(i8* null, i8* null, i32 0)
24 call i8* @llvm.localrecover(i8* null, i8* null, i32 0)
2525 ret void
2626 }
27 ; CHECK: llvm.framerecover first argument must be function defined in this module
27 ; CHECK: llvm.localrecover first argument must be function defined in this module
2828
2929 @global = constant i8 0
3030
3131 declare void @declaration()
3232
3333 define internal void @i() {
34 call i8* @llvm.framerecover(i8* @global, i8* null, i32 0)
34 call i8* @llvm.localrecover(i8* @global, i8* null, i32 0)
3535 ret void
3636 }
37 ; CHECK: llvm.framerecover first argument must be function defined in this module
37 ; CHECK: llvm.localrecover first argument must be function defined in this module
3838
3939 define internal void @j() {
40 call i8* @llvm.framerecover(i8* bitcast(void()* @declaration to i8*), i8* null, i32 0)
40 call i8* @llvm.localrecover(i8* bitcast(void()* @declaration to i8*), i8* null, i32 0)
4141 ret void
4242 }
43 ; CHECK: llvm.framerecover first argument must be function defined in this module
43 ; CHECK: llvm.localrecover first argument must be function defined in this module
4444
4545 define internal void @k(i32 %n) {
46 call i8* @llvm.framerecover(i8* bitcast(void()* @f to i8*), i8* null, i32 %n)
46 call i8* @llvm.localrecover(i8* bitcast(void()* @f to i8*), i8* null, i32 %n)
4747 ret void
4848 }
49 ; CHECK: idx argument of llvm.framerecover must be a constant int
49 ; CHECK: idx argument of llvm.localrecover must be a constant int
5050
5151 define internal void @l(i8* %b) {
5252 %a = alloca i8
53 call void (...) @llvm.frameescape(i8* %a, i8* %b)
53 call void (...) @llvm.localescape(i8* %a, i8* %b)
5454 ret void
5555 }
56 ; CHECK: llvm.frameescape only accepts static allocas
56 ; CHECK: llvm.localescape only accepts static allocas
5757
5858 define internal void @m() {
5959 %a = alloca i8
60 call void (...) @llvm.frameescape(i8* %a)
60 call void (...) @llvm.localescape(i8* %a)
6161 ret void
6262 }
6363
6464 define internal void @n(i8* %fp) {
65 call i8* @llvm.framerecover(i8* bitcast(void ()* @m to i8*), i8* %fp, i32 1)
65 call i8* @llvm.localrecover(i8* bitcast(void ()* @m to i8*), i8* %fp, i32 1)
6666 ret void
6767 }
68 ; CHECK: all indices passed to llvm.framerecover must be less than the number of arguments passed ot llvm.frameescape in the parent function
68 ; CHECK: all indices passed to llvm.localrecover must be less than the number of arguments passed ot llvm.localescape in the parent function
296296 "IMPLICIT_DEF", "SUBREG_TO_REG", "COPY_TO_REGCLASS", "DBG_VALUE",
297297 "REG_SEQUENCE", "COPY", "BUNDLE", "LIFETIME_START",
298298 "LIFETIME_END", "STACKMAP", "PATCHPOINT", "LOAD_STACK_GUARD",
299 "STATEPOINT", "FRAME_ALLOC", "FAULTING_LOAD_OP",
299 "STATEPOINT", "LOCAL_ESCAPE", "FAULTING_LOAD_OP",
300300 nullptr};
301301 const auto &Insts = getInstructions();
302302 for (const char *const *p = FixedInstrs; *p; ++p) {