[llvm] [Inline][WinEH] Fix try scopes leaking to caller on inline (PR #164170)
    Eli Friedman via llvm-commits 
    llvm-commits at lists.llvm.org
       
    Wed Oct 22 15:52:40 PDT 2025
    
    
  
================
@@ -2210,6 +2211,147 @@ inlineRetainOrClaimRVCalls(CallBase &CB, objcarc::ARCInstKind RVCallKind,
   }
 }
 
+struct SehScope {
+  llvm::InvokeInst *Begin;
+  llvm::InvokeInst *End;
+};
+
+// Determine SEH try scope begins and ends.
+static SmallVector<SehScope, 1> GetSehTryScopes(Function *Func) {
+  SmallVector<SehScope, 1> Scopes{};
+  DenseMap<llvm::BasicBlock *, llvm::InvokeInst *> ScopeEnds{};
+
+  for (auto &BB : *Func) {
+    auto *TI = BB.getTerminator();
+    if (auto *II = dyn_cast<InvokeInst>(TI)) {
+      auto *Call = cast<CallBase>(II);
+      const auto *Fn = Call->getCalledFunction();
+      if (!Fn || !Fn->isIntrinsic())
+        continue;
+
+      if (Fn->getIntrinsicID() == Intrinsic::seh_try_end) {
+        ScopeEnds[II->getUnwindDest()] = II;
+      } else if (Fn->getIntrinsicID() == Intrinsic::seh_try_begin) {
+        Scopes.push_back({II, nullptr});
+      }
+    }
+  }
+
+  // Assign scope end to begin if the unwind destination matches.
+  for (auto &Scope : Scopes) {
+    auto ScopeEndIt = ScopeEnds.find(Scope.Begin->getUnwindDest());
+    if (ScopeEndIt != ScopeEnds.end())
+      Scope.End = ScopeEndIt->second;
+  }
+
+  return Scopes;
+}
+
+// Find, if present, the outermost unterminated try scope for the input block.
+static llvm::InvokeInst *
+GetOutermostUnterminatedTryScopeBegin(llvm::BasicBlock *ReturnBlock,
+                                      SmallVector<SehScope, 1> &Scopes) {
+  llvm::InvokeInst *OutermostScope{nullptr};
+  DominatorTree DT;
+  DT.recalculate(*ReturnBlock->getParent());
+
+  for (auto &Scope : Scopes) {
----------------
efriedma-quic wrote:
This is still quadratic; it's O(number of ret instructions * number of scopes)
https://github.com/llvm/llvm-project/pull/164170
    
    
More information about the llvm-commits
mailing list