@@ -608,10 +608,17 @@ static int getSuccState(DenseMap<BasicBlock *, int> &InitialStates, Function &F,
608608 return CommonState;
609609}
610610
611- static bool isSehScopeBegin (const CallBase &Call) {
611+ static bool isIntrinsic (const CallBase &Call, Intrinsic::ID ID ) {
612612 const Function *CF = Call.getCalledFunction ();
613- return CF && CF->isIntrinsic () &&
614- CF->getIntrinsicID () == Intrinsic::seh_scope_begin;
613+ return CF && CF->isIntrinsic () && CF->getIntrinsicID () == ID;
614+ }
615+
616+ static bool isSehScopeEnd (const CallBase &Call) {
617+ return isIntrinsic (Call, Intrinsic::seh_scope_end);
618+ }
619+
620+ static bool isSehScopeBegin (const CallBase &Call) {
621+ return isIntrinsic (Call, Intrinsic::seh_scope_begin);
615622}
616623
617624bool WinEHStatePass::isStateStoreNeeded (EHPersonality Personality,
@@ -656,6 +663,8 @@ void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
656663 DenseMap<BasicBlock *, int > InitialStates;
657664 // FinalStates yields the state of the last call-site for a BasicBlock.
658665 DenseMap<BasicBlock *, int > FinalStates;
666+ // SEH scope end target blocks
667+ SmallPtrSet<BasicBlock *, 4 > ScopeEndBlocks;
659668 // Worklist used to revisit BasicBlocks with indeterminate
660669 // Initial/Final-States.
661670 std::deque<BasicBlock *> Worklist;
@@ -667,7 +676,15 @@ void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
667676 InitialState = FinalState = ParentBaseState;
668677 for (Instruction &I : *BB) {
669678 auto *Call = dyn_cast<CallBase>(&I);
670- if (!Call || !isStateStoreNeeded (Personality, *Call))
679+ if (!Call)
680+ continue ;
681+
682+ if (isSehScopeEnd (*Call)) {
683+ auto *Invoke = cast<InvokeInst>(Call);
684+ ScopeEndBlocks.insert (Invoke->getNormalDest ());
685+ }
686+
687+ if (!isStateStoreNeeded (Personality, *Call))
671688 continue ;
672689
673690 int State = getStateForCall (BlockColors, FuncInfo, *Call);
@@ -720,6 +737,12 @@ void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
720737 FinalStates.insert ({BB, SuccState});
721738 }
722739
740+ // Insert state restores after SEH scope ends
741+ for (BasicBlock *BB : ScopeEndBlocks) {
742+ int state = getBaseStateForBB (BlockColors, FuncInfo, BB);
743+ insertStateNumberStore (BB->getFirstNonPHI (), state);
744+ }
745+
723746 // Finally, insert state stores before call-sites which transition us to a new
724747 // state.
725748 for (BasicBlock *BB : RPOT) {
0 commit comments