llvm.org GIT mirror llvm / d0f4ffa
[WinEH] C++ EH state numbering fixes Differential Revision: http://reviews.llvm.org/D9787 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237854 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Kaylor 5 years ago
9 changed file(s) with 433 addition(s) and 174 deletion(s). Raw diff Collapse all Expand all
130130 };
131131
132132 struct WinEHFuncInfo {
133 DenseMap RootLPad;
134 DenseMap LastInvoke;
135 DenseMap HandlerEnclosedState;
136 DenseMap LastInvokeVisited;
133137 DenseMap LandingPadStateMap;
134138 DenseMap CatchHandlerParentFrameObjIdx;
135139 DenseMap CatchHandlerParentFrameObjOffset;
100100 ArrayRef Handlers);
101101 void processCallSite(MutableArrayRef> Actions,
102102 ImmutableCallSite CS);
103 void popUnmatchedActions(int FirstMismatch);
103104 void calculateStateNumbers(const Function &F);
105 void findActionRootLPads(const Function &F);
104106 };
105107 }
106108
296298 EHInfo = &MMI.getWinEHFuncInfo(WinEHParentFn);
297299 if (EHInfo->LandingPadStateMap.empty()) {
298300 WinEHNumbering Num(*EHInfo);
301 Num.findActionRootLPads(*WinEHParentFn);
302 // The VisitedHandlers list is used by both findActionRootLPads and
303 // calculateStateNumbers, but both functions need to visit all handlers.
304 Num.VisitedHandlers.clear();
299305 Num.calculateStateNumbers(*WinEHParentFn);
300306 // Pop everything on the handler stack.
301 Num.processCallSite(None, ImmutableCallSite());
307 // It may be necessary to call this more than once because a handler can
308 // be pushed on the stack as a result of clearing the stack.
309 while (!Num.HandlerStack.empty())
310 Num.processCallSite(None, ImmutableCallSite());
302311 }
303312
304313 // Copy the state numbers to LandingPadInfo for the current function, which
360369
361370 void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh,
362371 ArrayRef Handlers) {
372 // See if we already have an entry for this set of handlers.
373 // This is using iterators rather than a range-based for loop because
374 // if we find the entry we're looking for we'll need the iterator to erase it.
375 int NumHandlers = Handlers.size();
376 auto I = FuncInfo.TryBlockMap.begin();
377 auto E = FuncInfo.TryBlockMap.end();
378 for ( ; I != E; ++I) {
379 auto &Entry = *I;
380 if (Entry.HandlerArray.size() != NumHandlers)
381 continue;
382 int N;
383 for (N = 0; N < NumHandlers; ++N) {
384 if (Entry.HandlerArray[N].Handler != Handlers[N]->getHandlerBlockOrFunc())
385 break; // breaks out of inner loop
386 }
387 // If all the handlers match, this is what we were looking for.
388 if (N == NumHandlers) {
389 break;
390 }
391 }
392
393 // If we found an existing entry for this set of handlers, extend the range
394 // but move the entry to the end of the map vector. The order of entries
395 // in the map is critical to the way that the runtime finds handlers.
396 // FIXME: Depending on what has happened with block ordering, this may
397 // incorrectly combine entries that should remain separate.
398 if (I != E) {
399 // Copy the existing entry.
400 WinEHTryBlockMapEntry Entry = *I;
401 Entry.TryLow = std::min(TryLow, Entry.TryLow);
402 Entry.TryHigh = std::max(TryHigh, Entry.TryHigh);
403 assert(Entry.TryLow <= Entry.TryHigh);
404 // Erase the old entry and add this one to the back.
405 FuncInfo.TryBlockMap.erase(I);
406 FuncInfo.TryBlockMap.push_back(Entry);
407 return;
408 }
409
410 // If we didn't find an entry, create a new one.
363411 WinEHTryBlockMapEntry TBME;
364412 TBME.TryLow = TryLow;
365413 TBME.TryHigh = TryHigh;
428476 break;
429477 }
430478
479 // Remove unmatched actions from the stack and process their EH states.
480 popUnmatchedActions(FirstMismatch);
481
482 DEBUG(dbgs() << "Pushing actions for CallSite: ");
483 print_name(CS ? CS.getCalledValue() : nullptr);
484 DEBUG(dbgs() << '\n');
485
486 bool LastActionWasCatch = false;
487 const LandingPadInst *LastRootLPad = nullptr;
488 for (size_t I = FirstMismatch; I != Actions.size(); ++I) {
489 // We can reuse eh states when pushing two catches for the same invoke.
490 bool CurrActionIsCatch = isa(Actions[I].get());
491 auto *Handler = cast(Actions[I]->getHandlerBlockOrFunc());
492 // Various conditions can lead to a handler being popped from the
493 // stack and re-pushed later. That shouldn't create a new state.
494 // FIXME: Can code optimization lead to re-used handlers?
495 if (FuncInfo.HandlerEnclosedState.count(Handler)) {
496 // If we already assigned the state enclosed by this handler re-use it.
497 Actions[I]->setEHState(FuncInfo.HandlerEnclosedState[Handler]);
498 continue;
499 }
500 const LandingPadInst* RootLPad = FuncInfo.RootLPad[Handler];
501 if (CurrActionIsCatch && LastActionWasCatch && RootLPad == LastRootLPad) {
502 DEBUG(dbgs() << "setEHState for handler to " << currentEHNumber() << "\n");
503 Actions[I]->setEHState(currentEHNumber());
504 } else {
505 DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() << ", ");
506 print_name(Actions[I]->getHandlerBlockOrFunc());
507 DEBUG(dbgs() << ") with EH state " << NextState << "\n");
508 createUnwindMapEntry(currentEHNumber(), Actions[I].get());
509 DEBUG(dbgs() << "setEHState for handler to " << NextState << "\n");
510 Actions[I]->setEHState(NextState);
511 NextState++;
512 }
513 HandlerStack.push_back(std::move(Actions[I]));
514 LastActionWasCatch = CurrActionIsCatch;
515 LastRootLPad = RootLPad;
516 }
517
518 // This is used to defer numbering states for a handler until after the
519 // last time it appears in an invoke action list.
520 if (CS.isInvoke()) {
521 for (int I = 0, E = HandlerStack.size(); I < E; ++I) {
522 auto *Handler = cast(HandlerStack[I]->getHandlerBlockOrFunc());
523 if (FuncInfo.LastInvoke[Handler] != cast(CS.getInstruction()))
524 continue;
525 FuncInfo.LastInvokeVisited[Handler] = true;
526 DEBUG(dbgs() << "Last invoke of ");
527 print_name(Handler);
528 DEBUG(dbgs() << " has been visited.\n");
529 }
530 }
531
532 DEBUG(dbgs() << "In EHState " << currentEHNumber() << " for CallSite: ");
533 print_name(CS ? CS.getCalledValue() : nullptr);
534 DEBUG(dbgs() << '\n');
535 }
536
537 void WinEHNumbering::popUnmatchedActions(int FirstMismatch) {
431538 // Don't recurse while we are looping over the handler stack. Instead, defer
432539 // the numbering of the catch handlers until we are done popping.
433540 SmallVector PoppedCatches;
459566
460567 for (CatchHandler *CH : PoppedCatches) {
461568 if (auto *F = dyn_cast(CH->getHandlerBlockOrFunc())) {
462 DEBUG(dbgs() << "Assigning base state " << NextState << " to ");
463 print_name(F);
464 DEBUG(dbgs() << '\n');
465 FuncInfo.HandlerBaseState[F] = NextState;
466 DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber()
467 << ", null)\n");
468 createUnwindMapEntry(currentEHNumber(), nullptr);
469 ++NextState;
470 calculateStateNumbers(*F);
569 if (FuncInfo.LastInvokeVisited[F]) {
570 DEBUG(dbgs() << "Assigning base state " << NextState << " to ");
571 print_name(F);
572 DEBUG(dbgs() << '\n');
573 FuncInfo.HandlerBaseState[F] = NextState;
574 DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber()
575 << ", null)\n");
576 createUnwindMapEntry(currentEHNumber(), nullptr);
577 ++NextState;
578 calculateStateNumbers(*F);
579 }
580 else {
581 DEBUG(dbgs() << "Deferring handling of ");
582 print_name(F);
583 DEBUG(dbgs() << " until last invoke visited.\n");
584 }
471585 }
472586 delete CH;
473587 }
474
475 // The handler functions may have pushed actions onto the handler stack
476 // that we expected to push here. Compare the handler stack to our
477 // actions again to check for that possibility.
478 if (HandlerStack.size() > (size_t)FirstMismatch) {
479 for (int E = std::min(HandlerStack.size(), Actions.size());
480 FirstMismatch < E; ++FirstMismatch) {
481 if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
482 Actions[FirstMismatch]->getHandlerBlockOrFunc())
483 break;
484 }
485 }
486
487 DEBUG(dbgs() << "Pushing actions for CallSite: ");
488 print_name(CS ? CS.getCalledValue() : nullptr);
489 DEBUG(dbgs() << '\n');
490
491 bool LastActionWasCatch = false;
492 for (size_t I = FirstMismatch; I != Actions.size(); ++I) {
493 // We can reuse eh states when pushing two catches for the same invoke.
494 bool CurrActionIsCatch = isa(Actions[I].get());
495 // FIXME: Reenable this optimization!
496 if (CurrActionIsCatch && LastActionWasCatch && false) {
497 DEBUG(dbgs() << "setEHState for handler to " << currentEHNumber()
498 << "\n");
499 Actions[I]->setEHState(currentEHNumber());
500 } else {
501 DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() << ", ");
502 print_name(Actions[I]->getHandlerBlockOrFunc());
503 DEBUG(dbgs() << ")\n");
504 createUnwindMapEntry(currentEHNumber(), Actions[I].get());
505 DEBUG(dbgs() << "setEHState for handler to " << NextState << "\n");
506 Actions[I]->setEHState(NextState);
507 NextState++;
508 }
509 HandlerStack.push_back(std::move(Actions[I]));
510 LastActionWasCatch = CurrActionIsCatch;
511 }
512
513 DEBUG(dbgs() << "In EHState " << currentEHNumber() << " for CallSite: ");
514 print_name(CS ? CS.getCalledValue() : nullptr);
515 DEBUG(dbgs() << '\n');
516588 }
517589
518590 void WinEHNumbering::calculateStateNumbers(const Function &F) {
524596 if (FuncInfo.HandlerBaseState.count(&F)) {
525597 CurrentBaseState = FuncInfo.HandlerBaseState[&F];
526598 }
599
600 size_t SavedHandlerStackSize = HandlerStack.size();
527601
528602 DEBUG(dbgs() << "Calculating state numbers for: " << F.getName() << '\n');
529603 SmallVector, 4> ActionList;
553627 << '\n');
554628 }
555629
630 // Pop any actions that were pushed on the stack for this function.
631 popUnmatchedActions(SavedHandlerStackSize);
632
633 DEBUG(dbgs() << "Assigning max state " << NextState - 1
634 << " to " << F.getName() << '\n');
556635 FuncInfo.CatchHandlerMaxState[&F] = NextState - 1;
557636
558637 CurrentBaseState = OldBaseState;
638 }
639
640 // This function follows the same basic traversal as calculateStateNumbers
641 // but it is necessary to identify the root landing pad associated
642 // with each action before we start assigning state numbers.
643 void WinEHNumbering::findActionRootLPads(const Function &F) {
644 auto I = VisitedHandlers.insert(&F);
645 if (!I.second)
646 return; // We've already visited this handler, don't revisit it.
647
648 SmallVector, 4> ActionList;
649 for (const BasicBlock &BB : F) {
650 const auto *II = dyn_cast(BB.getTerminator());
651 if (!II)
652 continue;
653 const LandingPadInst *LPI = II->getLandingPadInst();
654 auto *ActionsCall = dyn_cast(LPI->getNextNode());
655 if (!ActionsCall)
656 continue;
657
658 assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions);
659 parseEHActions(ActionsCall, ActionList);
660 if (ActionList.empty())
661 continue;
662 for (int I = 0, E = ActionList.size(); I < E; ++I) {
663 if (auto *Handler
664 = dyn_cast(ActionList[I]->getHandlerBlockOrFunc())) {
665 FuncInfo.LastInvoke[Handler] = II;
666 // Don't replace the root landing pad if we previously saw this
667 // handler in a different function.
668 if (FuncInfo.RootLPad.count(Handler) &&
669 FuncInfo.RootLPad[Handler]->getParent()->getParent() != &F)
670 continue;
671 DEBUG(dbgs() << "Setting root lpad for ");
672 print_name(Handler);
673 DEBUG(dbgs() << " to " << LPI->getParent()->getName() << '\n');
674 FuncInfo.RootLPad[Handler] = LPI;
675 }
676 }
677 // Walk the actions again and look for nested handlers. This has to
678 // happen after all of the actions have been processed in the current
679 // function.
680 for (int I = 0, E = ActionList.size(); I < E; ++I)
681 if (auto *Handler
682 = dyn_cast(ActionList[I]->getHandlerBlockOrFunc()))
683 findActionRootLPads(*Handler);
684 ActionList.clear();
685 }
559686 }
560687
561688 /// clear - Clear out all the function-specific state. This returns this
9090 private:
9191 bool prepareExceptionHandlers(Function &F,
9292 SmallVectorImpl &LPads);
93 void identifyEHBlocks(Function &F, SmallVectorImpl &LPads);
9394 void promoteLandingPadValues(LandingPadInst *LPad);
9495 void demoteValuesLiveAcrossHandlers(Function &F,
9596 SmallVectorImpl &LPads);
126127 CatchHandlerMapTy CatchHandlerMap;
127128 CleanupHandlerMapTy CleanupHandlerMap;
128129 DenseMap LPadMaps;
130 SmallPtrSet NormalBlocks;
131 SmallPtrSet EHBlocks;
132 SetVector EHReturnBlocks;
129133
130134 // This maps landing pad instructions found in outlined handlers to
131135 // the landing pad instruction in the parent function from which they
213217 virtual CloningAction handleTypeIdFor(ValueToValueMapTy &VMap,
214218 const Instruction *Inst,
215219 BasicBlock *NewBB) = 0;
220 virtual CloningAction handleIndirectBr(ValueToValueMapTy &VMap,
221 const IndirectBrInst *IBr,
222 BasicBlock *NewBB) = 0;
216223 virtual CloningAction handleInvoke(ValueToValueMapTy &VMap,
217224 const InvokeInst *Invoke,
218225 BasicBlock *NewBB) = 0;
243250 WinEHCatchDirector(
244251 Function *CatchFn, Value *ParentFP, Value *Selector,
245252 FrameVarInfoMap &VarInfo, LandingPadMap &LPadMap,
246 DenseMap &NestedLPads)
253 DenseMap &NestedLPads,
254 DominatorTree *DT, SmallPtrSetImpl &EHBlocks)
247255 : WinEHCloningDirectorBase(CatchFn, ParentFP, VarInfo, LPadMap),
248256 CurrentSelector(Selector->stripPointerCasts()),
249 ExceptionObjectVar(nullptr), NestedLPtoOriginalLP(NestedLPads) {}
257 ExceptionObjectVar(nullptr), NestedLPtoOriginalLP(NestedLPads),
258 DT(DT), EHBlocks(EHBlocks) {}
250259
251260 CloningAction handleBeginCatch(ValueToValueMapTy &VMap,
252261 const Instruction *Inst,
256265 CloningAction handleTypeIdFor(ValueToValueMapTy &VMap,
257266 const Instruction *Inst,
258267 BasicBlock *NewBB) override;
268 CloningAction handleIndirectBr(ValueToValueMapTy &VMap,
269 const IndirectBrInst *IBr,
270 BasicBlock *NewBB) override;
259271 CloningAction handleInvoke(ValueToValueMapTy &VMap, const InvokeInst *Invoke,
260272 BasicBlock *NewBB) override;
261273 CloningAction handleResume(ValueToValueMapTy &VMap, const ResumeInst *Resume,
278290 // This will be a reference to the field of the same name in the WinEHPrepare
279291 // object which instantiates this WinEHCatchDirector object.
280292 DenseMap &NestedLPtoOriginalLP;
293 DominatorTree *DT;
294 SmallPtrSetImpl &EHBlocks;
281295 };
282296
283297 class WinEHCleanupDirector : public WinEHCloningDirectorBase {
295309 CloningAction handleTypeIdFor(ValueToValueMapTy &VMap,
296310 const Instruction *Inst,
297311 BasicBlock *NewBB) override;
312 CloningAction handleIndirectBr(ValueToValueMapTy &VMap,
313 const IndirectBrInst *IBr,
314 BasicBlock *NewBB) override;
298315 CloningAction handleInvoke(ValueToValueMapTy &VMap, const InvokeInst *Invoke,
299316 BasicBlock *NewBB) override;
300317 CloningAction handleResume(ValueToValueMapTy &VMap, const ResumeInst *Resume,
524541 }
525542 }
526543
527 /// Ensure that all values live into and out of exception handlers are stored
528 /// in memory.
529 /// FIXME: This falls down when values are defined in one handler and live into
530 /// another handler. For example, a cleanup defines a value used only by a
531 /// catch handler.
532 void WinEHPrepare::demoteValuesLiveAcrossHandlers(
533 Function &F, SmallVectorImpl &LPads) {
544 void WinEHPrepare::identifyEHBlocks(Function &F,
545 SmallVectorImpl &LPads) {
534546 DEBUG(dbgs() << "Demoting values live across exception handlers in function "
535547 << F.getName() << '\n');
536548
540552 // - Exceptional blocks are blocks reachable from landingpads. Analysis does
541553 // not follow llvm.eh.endcatch blocks, which mark a transition from
542554 // exceptional to normal control.
543 SmallPtrSet NormalBlocks;
544 SmallPtrSet EHBlocks;
545 SetVector EHReturnBlocks;
546 SetVector Worklist;
547555
548556 if (Personality == EHPersonality::MSVC_CXX)
549557 findCXXEHReturnPoints(F, EHReturnBlocks);
566574
567575 // Normal blocks are the blocks reachable from the entry block and all EH
568576 // return points.
577 SetVector Worklist;
569578 Worklist = EHReturnBlocks;
570579 Worklist.insert(&F.getEntryBlock());
571580 findReachableBlocks(NormalBlocks, Worklist, nullptr);
586595 for (BasicBlock *BB : EHBlocks)
587596 dbgs() << " " << BB->getName() << '\n';
588597 });
598
599 }
600
601 /// Ensure that all values live into and out of exception handlers are stored
602 /// in memory.
603 /// FIXME: This falls down when values are defined in one handler and live into
604 /// another handler. For example, a cleanup defines a value used only by a
605 /// catch handler.
606 void WinEHPrepare::demoteValuesLiveAcrossHandlers(
607 Function &F, SmallVectorImpl &LPads) {
608 DEBUG(dbgs() << "Demoting values live across exception handlers in function "
609 << F.getName() << '\n');
610
611 // identifyEHBlocks() should have been called before this function.
612 assert(!NormalBlocks.empty());
589613
590614 SetVector ArgsToDemote;
591615 SetVector InstrsToDemote;
677701 return false;
678702 }
679703
704 identifyEHBlocks(F, LPads);
680705 demoteValuesLiveAcrossHandlers(F, LPads);
681706
682707 // These containers are used to re-map frame variables that are used in
700725 new AllocaInst(Int8PtrType, nullptr, "seh_exception_code",
701726 F.getEntryBlock().getFirstInsertionPt());
702727 }
728
729 // In order to handle the case where one outlined catch handler returns
730 // to a block within another outlined catch handler that would otherwise
731 // be unreachable, we need to outline the nested landing pad before we
732 // outline the landing pad which encloses it.
733 if (!isAsynchronousEHPersonality(Personality))
734 std::sort(LPads.begin(), LPads.end(),
735 [this](LandingPadInst* &L, LandingPadInst* &R) {
736 return DT->dominates(R->getParent(), L->getParent());
737 });
703738
704739 // This container stores the llvm.eh.recover and IndirectBr instructions
705740 // that make up the body of each landing pad after it has been outlined.
828863 CallInst *Recover =
829864 CallInst::Create(ActionIntrin, ActionArgs, "recover", LPadBB);
830865
831 if (isAsynchronousEHPersonality(Personality)) {
832 // SEH can create the target list directly, since catch handlers
833 // are not outlined.
834 SetVector ReturnTargets;
835 for (ActionHandler *Action : Actions) {
836 if (auto *CatchAction = dyn_cast(Action)) {
837 const auto &CatchTargets = CatchAction->getReturnTargets();
838 ReturnTargets.insert(CatchTargets.begin(), CatchTargets.end());
839 }
840 }
841 IndirectBrInst *Branch =
842 IndirectBrInst::Create(Recover, ReturnTargets.size(), LPadBB);
843 for (BasicBlock *Target : ReturnTargets)
844 Branch->addDestination(Target);
845 } else {
846 // C++ EH must defer populating the targets to handle the case of
866 SetVector ReturnTargets;
867 for (ActionHandler *Action : Actions) {
868 if (auto *CatchAction = dyn_cast(Action)) {
869 const auto &CatchTargets = CatchAction->getReturnTargets();
870 ReturnTargets.insert(CatchTargets.begin(), CatchTargets.end());
871 }
872 }
873 IndirectBrInst *Branch =
874 IndirectBrInst::Create(Recover, ReturnTargets.size(), LPadBB);
875 for (BasicBlock *Target : ReturnTargets)
876 Branch->addDestination(Target);
877
878 if (!isAsynchronousEHPersonality(Personality)) {
879 // C++ EH must repopulate the targets later to handle the case of
847880 // targets that are reached indirectly through nested landing pads.
848 IndirectBrInst *Branch =
849 IndirectBrInst::Create(Recover, 0, LPadBB);
850
851881 LPadImpls.push_back(std::make_pair(Recover, Branch));
852882 }
883
853884 } // End for each landingpad
854885
855886 // If nothing got outlined, there is no more processing to be done.
863894 completeNestedLandingPad(&F, LPadPair.first, LPadPair.second, FrameVarInfo);
864895 NestedLPtoOriginalLP.clear();
865896
866 // Populate the indirectbr instructions' target lists if we deferred
867 // doing so above.
897 // Update the indirectbr instructions' target lists if necessary.
868898 SetVector CheckedTargets;
869899 SmallVector, 4> ActionList;
870900 for (auto &LPadImplPair : LPadImpls) {
883913 }
884914 }
885915 ActionList.clear();
916 // Clear any targets we already knew about.
917 for (unsigned int I = 0, E = Branch->getNumDestinations(); I < E; ++I) {
918 BasicBlock *KnownTarget = Branch->getDestination(I);
919 if (ReturnTargets.count(KnownTarget))
920 ReturnTargets.remove(KnownTarget);
921 }
886922 for (BasicBlock *Target : ReturnTargets) {
887923 Branch->addDestination(Target);
888924 // The target may be a block that we excepted to get pruned.
9931029 HandlerToParentFP.clear();
9941030 DT = nullptr;
9951031 SEHExceptionCodeSlot = nullptr;
1032 EHBlocks.clear();
1033 NormalBlocks.clear();
1034 EHReturnBlocks.clear();
9961035
9971036 return HandlersOutlined;
9981037 }
10781117 // temporarily inserted as its terminator.
10791118 LLVMContext &Context = ParentFn->getContext();
10801119 BasicBlock *OutlinedBB = OutlinedLPad->getParent();
1081 assert(isa(OutlinedBB->getTerminator()));
1082 OutlinedBB->getTerminator()->eraseFromParent();
1083 // That should leave OutlinedLPad as the last instruction in its block.
1084 assert(&OutlinedBB->back() == OutlinedLPad);
1120 // If the nested landing pad was outlined before the landing pad that enclosed
1121 // it, it will already be in outlined form. In that case, we just need to see
1122 // if the returns and the enclosing branch instruction need to be updated.
1123 IndirectBrInst *Branch =
1124 dyn_cast(OutlinedBB->getTerminator());
1125 if (!Branch) {
1126 // If the landing pad wasn't in outlined form, it should be a stub with
1127 // an unreachable terminator.
1128 assert(isa(OutlinedBB->getTerminator()));
1129 OutlinedBB->getTerminator()->eraseFromParent();
1130 // That should leave OutlinedLPad as the last instruction in its block.
1131 assert(&OutlinedBB->back() == OutlinedLPad);
1132 }
10851133
10861134 // The original landing pad will have already had its action intrinsic
10871135 // built by the outlining loop. We need to clone that into the outlined
10951143 // The instruction after the landing pad should now be a call to eh.actions.
10961144 const Instruction *Recover = II;
10971145 assert(match(Recover, m_Intrinsic()));
1098 IntrinsicInst *EHActions = cast(Recover->clone());
1099
1100 // Remap the exception variables into the outlined function.
1146 const IntrinsicInst *EHActions = cast(Recover);
1147
1148 // Remap the return target in the nested handler.
11011149 SmallVector ActionTargets;
11021150 SmallVector, 4> ActionList;
11031151 parseEHActions(EHActions, ActionList);
11241172 // should be a block that was outlined into OutlinedHandlerFn.
11251173 assert(BA->getFunction() == ParentFn);
11261174
1127 // Ignore targets that aren't part of OutlinedHandlerFn.
1175 // Ignore targets that aren't part of an outlined handler function.
11281176 if (!LPadTargetBlocks.count(BA->getBasicBlock()))
11291177 continue;
11301178
11411189 }
11421190 }
11431191 ActionList.clear();
1144 OutlinedBB->getInstList().push_back(EHActions);
1145
1146 // Insert an indirect branch into the outlined landing pad BB.
1147 IndirectBrInst *IBr = IndirectBrInst::Create(EHActions, 0, OutlinedBB);
1148 // Add the previously collected action targets.
1149 for (auto *Target : ActionTargets)
1150 IBr->addDestination(Target->getBasicBlock());
1192
1193 if (Branch) {
1194 // If the landing pad was already in outlined form, just update its targets.
1195 for (unsigned int I = Branch->getNumDestinations(); I > 0; --I)
1196 Branch->removeDestination(I);
1197 // Add the previously collected action targets.
1198 for (auto *Target : ActionTargets)
1199 Branch->addDestination(Target->getBasicBlock());
1200 } else {
1201 // If the landing pad was previously stubbed out, fill in its outlined form.
1202 IntrinsicInst *NewEHActions = cast(EHActions->clone());
1203 OutlinedBB->getInstList().push_back(NewEHActions);
1204
1205 // Insert an indirect branch into the outlined landing pad BB.
1206 IndirectBrInst *IBr = IndirectBrInst::Create(NewEHActions, 0, OutlinedBB);
1207 // Add the previously collected action targets.
1208 for (auto *Target : ActionTargets)
1209 IBr->addDestination(Target->getBasicBlock());
1210 }
11511211 }
11521212
11531213 // This function examines a block to determine whether the block ends with a
13251385 LPadMap.mapLandingPad(LPad);
13261386 if (auto *CatchAction = dyn_cast(Action)) {
13271387 Constant *Sel = CatchAction->getSelector();
1328 Director.reset(new WinEHCatchDirector(Handler, ParentFP, Sel,
1329 VarInfo, LPadMap,
1330 NestedLPtoOriginalLP));
1388 Director.reset(new WinEHCatchDirector(Handler, ParentFP, Sel, VarInfo,
1389 LPadMap, NestedLPtoOriginalLP, DT,
1390 EHBlocks));
13311391 LPadMap.remapEHValues(VMap, UndefValue::get(Int8PtrType),
13321392 ConstantInt::get(Type::getInt32Ty(Context), 1));
13331393 } else {
15311591 if (LPadMap.isLandingPadSpecificInst(Inst))
15321592 return CloningDirector::SkipInstruction;
15331593
1534 // Nested landing pads will be cloned as stubs, with just the
1535 // landingpad instruction and an unreachable instruction. When
1536 // all landingpads have been outlined, we'll replace this with the
1537 // llvm.eh.actions call and indirect branch created when the
1538 // landing pad was outlined.
1594 // Nested landing pads that have not already been outlined will be cloned as
1595 // stubs, with just the landingpad instruction and an unreachable instruction.
1596 // When all landingpads have been outlined, we'll replace this with the
1597 // llvm.eh.actions call and indirect branch created when the landing pad was
1598 // outlined.
15391599 if (auto *LPad = dyn_cast(Inst)) {
15401600 return handleLandingPad(VMap, LPad, NewBB);
1601 }
1602
1603 // Nested landing pads that have already been outlined will be cloned in their
1604 // outlined form, but we need to intercept the ibr instruction to filter out
1605 // targets that do not return to the handler we are outlining.
1606 if (auto *IBr = dyn_cast(Inst)) {
1607 return handleIndirectBr(VMap, IBr, NewBB);
15411608 }
15421609
15431610 if (auto *Invoke = dyn_cast(Inst))
15691636
15701637 CloningDirector::CloningAction WinEHCatchDirector::handleLandingPad(
15711638 ValueToValueMapTy &VMap, const LandingPadInst *LPad, BasicBlock *NewBB) {
1639 // If the instruction after the landing pad is a call to llvm.eh.actions
1640 // the landing pad has already been outlined. In this case, we should
1641 // clone it because it may return to a block in the handler we are
1642 // outlining now that would otherwise be unreachable. The landing pads
1643 // are sorted before outlining begins to enable this case to work
1644 // properly.
1645 const Instruction *NextI = LPad->getNextNode();
1646 if (match(NextI, m_Intrinsic()))
1647 return CloningDirector::CloneInstruction;
1648
1649 // If the landing pad hasn't been outlined yet, the landing pad we are
1650 // outlining now does not dominate it and so it cannot return to a block
1651 // in this handler. In that case, we can just insert a stub landing
1652 // pad now and patch it up later.
15721653 Instruction *NewInst = LPad->clone();
15731654 if (LPad->hasName())
15741655 NewInst->setName(LPad->getName());
16601741 return CloningDirector::SkipInstruction;
16611742 }
16621743
1744 CloningDirector::CloningAction WinEHCatchDirector::handleIndirectBr(
1745 ValueToValueMapTy &VMap,
1746 const IndirectBrInst *IBr,
1747 BasicBlock *NewBB) {
1748 // If this indirect branch is not part of a landing pad block, just clone it.
1749 const BasicBlock *ParentBB = IBr->getParent();
1750 if (!ParentBB->isLandingPad())
1751 return CloningDirector::CloneInstruction;
1752
1753 // If it is part of a landing pad, we want to filter out target blocks
1754 // that are not part of the handler we are outlining.
1755 const LandingPadInst *LPad = ParentBB->getLandingPadInst();
1756
1757 // Save this correlation for later processing.
1758 NestedLPtoOriginalLP[cast(VMap[LPad])] = LPad;
1759
1760 // We should only get here for landing pads that have already been outlined.
1761 assert(match(LPad->getNextNode(), m_Intrinsic()));
1762
1763 // Copy the indirectbr, but only include targets that were previously
1764 // identified as EH blocks and are dominated by the nested landing pad.
1765 SetVector ReturnTargets;
1766 for (int I = 0, E = IBr->getNumDestinations(); I < E; ++I) {
1767 auto *TargetBB = IBr->getDestination(I);
1768 if (EHBlocks.count(const_cast(TargetBB)) &&
1769 DT->dominates(ParentBB, TargetBB)) {
1770 DEBUG(dbgs() << " Adding destination " << TargetBB->getName() << "\n");
1771 ReturnTargets.insert(TargetBB);
1772 }
1773 }
1774 IndirectBrInst *NewBranch =
1775 IndirectBrInst::Create(const_cast(IBr->getAddress()),
1776 ReturnTargets.size(), NewBB);
1777 for (auto *Target : ReturnTargets)
1778 NewBranch->addDestination(const_cast(Target));
1779
1780 // The operands and targets of the branch instruction are remapped later
1781 // because it is a terminator. Tell the cloning code to clone the
1782 // blocks we just added to the target list.
1783 return CloningDirector::CloneSuccessors;
1784 }
1785
16631786 CloningDirector::CloningAction
16641787 WinEHCatchDirector::handleInvoke(ValueToValueMapTy &VMap,
16651788 const InvokeInst *Invoke, BasicBlock *NewBB) {
17471870 // If eg.typeid.for is called for any other reason, it can be ignored.
17481871 VMap[Inst] = ConstantInt::get(SelectorIDType, 0);
17491872 return CloningDirector::SkipInstruction;
1873 }
1874
1875 CloningDirector::CloningAction WinEHCleanupDirector::handleIndirectBr(
1876 ValueToValueMapTy &VMap,
1877 const IndirectBrInst *IBr,
1878 BasicBlock *NewBB) {
1879 // No special handling is required for cleanup cloning.
1880 return CloningDirector::CloneInstruction;
17501881 }
17511882
17521883 CloningDirector::CloningAction WinEHCleanupDirector::handleInvoke(
3333 ; CHECK: entry:
3434 ; CHECK: %i = alloca i32, align 4
3535 ; CHECK: %f = alloca float, align 4
36 ; CHECK: call void (...) @llvm.frameescape(i32* %i, float* %f)
36 ; CHECK: call void (...) @llvm.frameescape(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
5454 ; CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
5555 ; CHECK: catch i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*)
5656 ; CHECK: catch i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*)
57 ; CHECK: [[RECOVER:\%.+]] = call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*), i32 0, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch", i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*), i32 1, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch.1")
58 ; CHECK: indirectbr i8* [[RECOVER]], [label %try.cont10, label %try.cont]
57 ; CHECK: [[RECOVER:\%.+]] = call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*), i32 1, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch.1", i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*), i32 0, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch")
58 ; CHECK: indirectbr i8* [[RECOVER]], [label %try.cont, label %try.cont10]
5959
6060 lpad: ; preds = %entry
6161 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
135135
136136 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*)
137137 ; CHECK: entry:
138 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
138 ; CHECK: [[RECOVER_F1:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
139 ; CHECK: [[F_PTR1:\%.+]] = bitcast i8* [[RECOVER_F1]] to float*
140 ; CHECK: [[TMP2:\%.+]] = load float, float* [[F_PTR1]], align 4
141 ; CHECK: call void @"\01?handle_float@@YAXM@Z"(float [[TMP2]])
142 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %try.cont10)
143 ; CHECK: }
144
145 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch.1"(i8*, i8*)
146 ; CHECK: entry:
147 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
139148 ; CHECK: [[I_PTR:\%.+]] = bitcast i8* [[RECOVER_I]] to i32*
140149 ; CHECK: [[TMP1:\%.+]] = load i32, i32* [[I_PTR]], align 4
141150 ; CHECK: invoke void @"\01?handle_int@@YAXH@Z"(i32 [[TMP1]])
147156 ; CHECK: [[LPAD1_LABEL]]:{{[ ]+}}; preds = %entry
148157 ; CHECK: [[LPAD1_VAL:\%.+]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
149158 ; CHECK: catch i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*)
150 ; CHECK: [[RECOVER1:\%.+]] = call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*), i32 1, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch.1")
159 ; CHECK: [[RECOVER1:\%.+]] = call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*), i32 0, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch")
151160 ; CHECK: indirectbr i8* [[RECOVER1]], []
152161 ;
153 ; CHECK: }
154
155 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch.1"(i8*, i8*)
156 ; CHECK: entry:
157 ; CHECK: [[RECOVER_F1:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
158 ; CHECK: [[F_PTR1:\%.+]] = bitcast i8* [[RECOVER_F1]] to float*
159 ; CHECK: [[TMP2:\%.+]] = load float, float* [[F_PTR1]], align 4
160 ; CHECK: call void @"\01?handle_float@@YAXM@Z"(float [[TMP2]])
161 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %try.cont10)
162162 ; CHECK: }
163163
164164
113113 ; CHECK-SAME: i32 1, i8* bitcast (i8** @_ZTIi to i8*), i32 1, i8* (i8*, i8*)* @_Z4testv.catch.1,
114114 ; CHECK-SAME: i32 0, void (i8*, i8*)* @_Z4testv.cleanup,
115115 ; CHECK-SAME: i32 1, i8* bitcast (i8** @_ZTIf to i8*), i32 0, i8* (i8*, i8*)* @_Z4testv.catch)
116 ; CHECK-NEXT: indirectbr i8* [[RECOVER1]], [label %try.cont19, label %try.cont]
116 ; CHECK-NEXT: indirectbr i8* [[RECOVER1]], [label %try.cont, label %try.cont19]
117117
118118 lpad1: ; preds = %invoke.cont4, %invoke.cont
119119 %tmp3 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
136136 ; CHECK-SAME: i32 1, i8* bitcast (i8** @_ZTIi to i8*), i32 1, i8* (i8*, i8*)* @_Z4testv.catch.1,
137137 ; CHECK-SAME: i32 0, void (i8*, i8*)* @_Z4testv.cleanup,
138138 ; CHECK-SAME: i32 1, i8* bitcast (i8** @_ZTIf to i8*), i32 0, i8* (i8*, i8*)* @_Z4testv.catch)
139 ; CHECK-NEXT: indirectbr i8* [[RECOVER3]], [label %try.cont19, label %try.cont]
139 ; CHECK-NEXT: indirectbr i8* [[RECOVER3]], [label %try.cont, label %try.cont19]
140140
141141 lpad3: ; preds = %invoke.cont2
142142 %tmp6 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
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* %i, float* %f, i32* %j)
43 ; CHECK: call void (...) @llvm.frameescape(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
6262 ; CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
6363 ; CHECK: catch i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*)
6464 ; CHECK: catch i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*)
65 ; CHECK: [[RECOVER:\%.+]] = call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*), i32 0, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch", i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*), i32 1, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch.1")
66 ; CHECK: indirectbr i8* [[RECOVER]], [label %try.cont19, label %try.cont10]
65 ; CHECK: [[RECOVER:\%.+]] = call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*), i32 1, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch.2", i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*), i32 2, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch.1")
66 ; CHECK: indirectbr i8* [[RECOVER]], [label %try.cont10, label %try.cont19]
6767
6868 lpad: ; preds = %entry
6969 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
180180
181181 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*)
182182 ; CHECK: entry:
183 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
183 ; CHECK: [[RECOVER_J:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
184 ; 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)
186 ; CHECK: [[I_PTR1:\%.+]] = bitcast i8* [[RECOVER_I1]] to i32*
187 ; CHECK: [[TMP3:\%.+]] = load i32, i32* [[J_PTR]], align 4
188 ; CHECK: store i32 [[TMP3]], i32* [[I_PTR1]]
189 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ.catch.2", %invoke.cont2)
190 ; CHECK: }
191
192 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch.1"(i8*, i8*)
193 ; CHECK: entry:
194 ; CHECK: [[RECOVER_F:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
195 ; CHECK: [[F_PTR:\%.+]] = bitcast i8* [[RECOVER_F]] to float*
196 ; CHECK: [[TMP2:\%.+]] = load float, float* [[F_PTR]], align 4
197 ; CHECK: call void @"\01?handle_float@@YAXM@Z"(float [[TMP2]])
198 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %try.cont19)
199 ; CHECK: }
200
201 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch.2"(i8*, i8*)
202 ; CHECK: entry:
203 ; CHECK: [[RECOVER_I:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
184204 ; CHECK: [[I_PTR:\%.+]] = bitcast i8* [[RECOVER_I]] to i32*
185205 ; CHECK: invoke void @"\01?may_throw@@YAXXZ"()
186206 ; CHECK: to label %invoke.cont2 unwind label %[[LPAD1_LABEL:lpad[0-9]*]]
194214 ; CHECK: [[LPAD1_VAL:\%.+]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
195215 ; CHECK: catch i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*)
196216 ; CHECK: catch i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*)
197 ; CHECK: [[RECOVER1:\%.+]] = call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*), i32 2, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch.2", i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*), i32 1, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch.1")
217 ; CHECK: [[RECOVER1:\%.+]] = call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*), i32 0, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch", i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*), i32 2, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch.1")
198218 ; CHECK: indirectbr i8* [[RECOVER1]], [label %invoke.cont2]
199219 ;
200220 ; CHECK: invoke.cont9:
203223 ; CHECK: [[LPAD8_LABEL]]:{{[ ]+}}; preds = %invoke.cont2
204224 ; CHECK: [[LPAD8_VAL:\%.+]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
205225 ; CHECK: catch i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*)
206 ; CHECK: [[RECOVER2:\%.+]] = call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*), i32 1, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch.1")
226 ; CHECK: [[RECOVER2:\%.+]] = call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0M@8" to i8*), i32 2, i8* (i8*, i8*)* @"\01?test@@YAXXZ.catch.1")
207227 ; CHECK: indirectbr i8* [[RECOVER2]], []
208228 ;
209229 ; CHECK: }
210
211 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch.1"(i8*, i8*)
212 ; CHECK: entry:
213 ; CHECK: [[RECOVER_F:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
214 ; CHECK: [[F_PTR:\%.+]] = bitcast i8* [[RECOVER_F]] to float*
215 ; CHECK: [[TMP2:\%.+]] = load float, float* [[F_PTR]], align 4
216 ; CHECK: call void @"\01?handle_float@@YAXM@Z"(float [[TMP2]])
217 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ", %try.cont19)
218 ; CHECK: }
219
220 ; CHECK: define internal i8* @"\01?test@@YAXXZ.catch.2"(i8*, i8*)
221 ; CHECK: entry:
222 ; CHECK: [[RECOVER_J:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
223 ; CHECK: [[J_PTR:\%.+]] = bitcast i8* [[RECOVER_J]] to i32*
224 ; CHECK: [[RECOVER_I1:\%.+]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
225 ; CHECK: [[I_PTR1:\%.+]] = bitcast i8* [[RECOVER_I1]] to i32*
226 ; CHECK: [[TMP3:\%.+]] = load i32, i32* [[J_PTR]], align 4
227 ; CHECK: store i32 [[TMP3]], i32* [[I_PTR1]]
228 ; CHECK: ret i8* blockaddress(@"\01?test@@YAXXZ.catch", %invoke.cont2)
229 ; CHECK: }
230
231230
232231 declare void @"\01?may_throw@@YAXXZ"() #1
233232
179179 ; CHECK: }
180180 }
181181
182 ; The outlined test1.catch handler should not contain a return instruction.
182 ; The outlined test1.catch handler should return to a valid block address.
183183 ; CHECK-LABEL: define internal i8* @"\01?test1@@YAXXZ.catch"(i8*, i8*)
184 ; CHECK-NOT: ret i8* inttoptr (i32 1 to i8*)
185 ; CHECK: }
186
187 ; The outlined test1.catch1 handler should not contain a return instruction.
188 ; CHECK-LABEL: define internal i8* @"\01?test1@@YAXXZ.catch.1"(i8*, i8*)
184189 ; CHECK-NOT: ret
185190 ; CHECK: }
186191
187 ; The outlined test1.catch1 handler should return to a valid block address.
188 ; CHECK-LABEL: define internal i8* @"\01?test1@@YAXXZ.catch.1"(i8*, i8*)
189 ; WILL-CHECK: ret i8* inttoptr (
192 ; The outlined test2.catch handler should return to a valid block address.
193 ; CHECK-LABEL: define internal i8* @"\01?test2@@YAXXZ.catch"(i8*, i8*)
190194 ; CHECK-NOT: ret i8* inttoptr (i32 1 to i8*)
191195 ; CHECK: }
192196
193 ; The outlined test2.catch handler should not contain a return instruction.
194 ; CHECK-LABEL: define internal i8* @"\01?test2@@YAXXZ.catch"(i8*, i8*)
197 ; The outlined test2.catch2 handler should not contain a return instruction.
198 ; CHECK-LABEL: define internal i8* @"\01?test2@@YAXXZ.catch.2"(i8*, i8*)
195199 ; CHECK-NOT: ret
196 ; CHECK: }
197
198 ; The outlined test2.catch1 handler should return to a valid block address.
199 ; CHECK-LABEL: define internal i8* @"\01?test2@@YAXXZ.catch.2"(i8*, i8*)
200 ; WILL-CHECK: ret i8* inttoptr (
201 ; CHECK-NOT: ret i8* inttoptr (i32 1 to i8*)
202200 ; CHECK: }
203201
204202
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(i8* [[C_PTR:\%.+]], i32* [[X_PTR:\%.+]], i8* [[C2_PTR:\%.+]], i32* [[X2_PTR:\%.+]], i8* [[C3_PTR:\%.+]])
88 ; CHECK: call void (...) @llvm.frameescape(i32* [[X_PTR:\%.+]], i32* [[X2_PTR:\%.+]], i8* [[C2_PTR:\%.+]], i8* [[C3_PTR:\%.+]], i8* [[C_PTR:\%.+]])
8989 ; CHECK: invoke void @_CxxThrowException
9090 ; CHECK: }
9191
273273 ; CHECK-NEXT: .long .Lfunc_begin0@IMGREL
274274 ; CHECK-NEXT: .long -1
275275 ; CHECK-NEXT: .long .Ltmp0@IMGREL
276 ; CHECK-NEXT: .long 2
277 ; CHECK-NEXT: .long .Ltmp3@IMGREL
278 ; CHECK-NEXT: .long 1
279 ; CHECK-NEXT: .long .Ltmp6@IMGREL
280 ; CHECK-NEXT: .long 0
281 ; CHECK-NEXT: .long .Lfunc_begin1@IMGREL
276282 ; CHECK-NEXT: .long 3
277 ; CHECK-NEXT: .long .Ltmp3@IMGREL
278 ; CHECK-NEXT: .long 2
279 ; CHECK-NEXT: .long .Ltmp6@IMGREL
280 ; CHECK-NEXT: .long 1
281 ; CHECK-NEXT: .long .Lfunc_begin1@IMGREL
283 ; CHECK-NEXT: .long .Lfunc_begin2@IMGREL
282284 ; CHECK-NEXT: .long 4
283 ; CHECK-NEXT: .long .Lfunc_begin2@IMGREL
285 ; CHECK-NEXT: .long .Lfunc_begin3@IMGREL
284286 ; CHECK-NEXT: .long 5
285 ; CHECK-NEXT: .long .Lfunc_begin3@IMGREL
287 ; CHECK-NEXT: .long .Lfunc_begin4@IMGREL
286288 ; CHECK-NEXT: .long 6
287 ; CHECK-NEXT: .long .Lfunc_begin4@IMGREL
288 ; CHECK-NEXT: .long 7