[llvm] 1353f7c - [Inliner] Fix dangling pointer in OriginallyIndirectCalls. (#191242)

via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 9 11:06:53 PDT 2026


Author: Florian Hahn
Date: 2026-04-09T19:06:48+01:00
New Revision: 1353f7cd548d3534c1e1fd4265bc030209bb4dd2

URL: https://github.com/llvm/llvm-project/commit/1353f7cd548d3534c1e1fd4265bc030209bb4dd2
DIFF: https://github.com/llvm/llvm-project/commit/1353f7cd548d3534c1e1fd4265bc030209bb4dd2.diff

LOG: [Inliner] Fix dangling pointer in OriginallyIndirectCalls. (#191242)

changeToInvokeAndSplitBasicBlock replaces an exising call instruction
with an invoke instruction. This leaves a dangling pointer in
OriginallyIndirectCalls. This means we miss !inline_history metadata on
the invokes replacing the direct calls.

It also cause non-determinism, where the inliner adds !inline_history
entries to unrelated call instructions, if we happen to re-allocate a
new call at the same address as a dangling pointer in the set.

PR: https://github.com/llvm/llvm-project/pull/191242

Added: 
    llvm/test/Transforms/Inline/inline-history-invoke.ll

Modified: 
    llvm/lib/Transforms/Utils/InlineFunction.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 7eef188bbc57a..c398a6ae4f0f9 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -560,6 +560,7 @@ static Value *getUnwindDestToken(Instruction *EHPad,
 /// nodes in that block with the values specified in InvokeDestPHIValues.
 static BasicBlock *HandleCallsInBlockInlinedThroughInvoke(
     BasicBlock *BB, BasicBlock *UnwindEdge,
+    SmallSetVector<const Value *, 4> &OriginallyIndirectCalls,
     UnwindDestMemoTy *FuncletUnwindMap = nullptr) {
   for (Instruction &I : llvm::make_early_inc_range(*BB)) {
     // We only need to check for function calls: inlined invoke
@@ -605,7 +606,10 @@ static BasicBlock *HandleCallsInBlockInlinedThroughInvoke(
 #endif // NDEBUG
     }
 
+    bool WasIndirect = OriginallyIndirectCalls.remove(CI);
     changeToInvokeAndSplitBasicBlock(CI, UnwindEdge);
+    if (WasIndirect)
+      OriginallyIndirectCalls.insert(BB->getTerminator());
     return BB;
   }
   return nullptr;
@@ -651,7 +655,8 @@ static void HandleInlinedLandingPad(InvokeInst *II, BasicBlock *FirstNewBlock,
        BB != E; ++BB) {
     if (InlinedCodeInfo.ContainsCalls)
       if (BasicBlock *NewBB = HandleCallsInBlockInlinedThroughInvoke(
-              &*BB, Invoke.getOuterResumeDest()))
+              &*BB, Invoke.getOuterResumeDest(),
+              InlinedCodeInfo.OriginallyIndirectCalls))
         // Update any PHI nodes in the exceptional block to indicate that there
         // is now a new entry in them.
         Invoke.addIncomingPHIValuesFor(NewBB);
@@ -785,7 +790,8 @@ static void HandleInlinedEHPad(InvokeInst *II, BasicBlock *FirstNewBlock,
                             E = Caller->end();
          BB != E; ++BB)
       if (BasicBlock *NewBB = HandleCallsInBlockInlinedThroughInvoke(
-              &*BB, UnwindDest, &FuncletUnwindMap))
+              &*BB, UnwindDest, InlinedCodeInfo.OriginallyIndirectCalls,
+              &FuncletUnwindMap))
         // Update any PHI nodes in the exceptional block to indicate that there
         // is now a new entry in them.
         UpdatePHINodes(NewBB);

diff  --git a/llvm/test/Transforms/Inline/inline-history-invoke.ll b/llvm/test/Transforms/Inline/inline-history-invoke.ll
new file mode 100644
index 0000000000000..1ab0b3f365b53
--- /dev/null
+++ b/llvm/test/Transforms/Inline/inline-history-invoke.ll
@@ -0,0 +1,74 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes='cgscc(inline)' -S %s | FileCheck %s
+;
+declare i32 @__gxx_personality_v0(...)
+declare void @may_throw()
+
+define internal void @callee_with_indirect(ptr %fn) {
+  call void %fn()
+  call void @may_throw()
+  ret void
+}
+
+define void @caller(ptr %fn) personality ptr @__gxx_personality_v0 {
+; CHECK-LABEL: define void @caller(
+; CHECK-SAME: ptr [[FN:%.*]]) personality ptr @__gxx_personality_v0 {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    invoke void [[FN]]()
+; CHECK-NEXT:            to [[DOTNOEXC:label %.*]] unwind label %[[LPAD:.*]], !inline_history [[META0:![0-9]+]]
+; CHECK:       [[_NOEXC:.*:]]
+; CHECK-NEXT:    invoke void @may_throw()
+; CHECK-NEXT:            to label %[[CALLEE_WITH_INDIRECT_EXIT:.*]] unwind label %[[LPAD]]
+; CHECK:       [[CALLEE_WITH_INDIRECT_EXIT]]:
+; CHECK-NEXT:    br label %[[CONT:.*]]
+; CHECK:       [[CONT]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[LPAD]]:
+; CHECK-NEXT:    [[EX:%.*]] = landingpad { ptr, i32 }
+; CHECK-NEXT:            cleanup
+; CHECK-NEXT:    resume { ptr, i32 } [[EX]]
+;
+entry:
+  invoke void @callee_with_indirect(ptr %fn)
+  to label %cont unwind label %lpad
+
+cont:
+  ret void
+
+lpad:
+  %ex = landingpad { ptr, i32 } cleanup
+  resume { ptr, i32 } %ex
+}
+
+define void @caller_ehpad(ptr %fn) personality ptr @__gxx_personality_v0 {
+; CHECK-LABEL: define void @caller_ehpad(
+; CHECK-SAME: ptr [[FN:%.*]]) personality ptr @__gxx_personality_v0 {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    invoke void [[FN]]()
+; CHECK-NEXT:            to [[DOTNOEXC:label %.*]] unwind label %[[CLEANUPBB:.*]], !inline_history [[META0]]
+; CHECK:       [[_NOEXC:.*:]]
+; CHECK-NEXT:    invoke void @may_throw()
+; CHECK-NEXT:            to label %[[CALLEE_WITH_INDIRECT_EXIT:.*]] unwind label %[[CLEANUPBB]]
+; CHECK:       [[CALLEE_WITH_INDIRECT_EXIT]]:
+; CHECK-NEXT:    br label %[[CONT:.*]]
+; CHECK:       [[CONT]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[CLEANUPBB]]:
+; CHECK-NEXT:    [[PAD:%.*]] = cleanuppad within none []
+; CHECK-NEXT:    cleanupret from [[PAD]] unwind to caller
+;
+entry:
+  invoke void @callee_with_indirect(ptr %fn)
+  to label %cont unwind label %cleanupbb
+
+cont:
+  ret void
+
+cleanupbb:
+  %pad = cleanuppad within none []
+  cleanupret from %pad unwind to caller
+}
+
+;.
+; CHECK: [[META0]] = distinct !{null}
+;.


        


More information about the llvm-commits mailing list