[llvm] [Attributor] Only seed live internal callees during deduction (PR #222226)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 8 22:46:55 PDT 2026


https://github.com/int-zjt updated https://github.com/llvm/llvm-project/pull/222226

>From 95c56d032bb4d36d3573bcc38808c587162665eb Mon Sep 17 00:00:00 2001
From: "zhangjiatong.0" <zhangjiatong.0 at bytedance.com>
Date: Wed, 9 Sep 2026 11:40:27 +0800
Subject: [PATCH 1/2] [Attributor] Only seed live internal callees during
 deduction

---
 llvm/include/llvm/Transforms/IPO/Attributor.h |  9 +++-
 .../Transforms/IPO/AttributorAttributes.cpp   |  3 ++
 .../Transforms/IPO/AttributorTest.cpp         | 48 +++++++++++++++++++
 3 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 00b20eee4d5df..4cce13397a882 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -1705,7 +1705,7 @@ struct Attributor {
     AAPtr = &AA;
 
     // Register AA with the synthetic root only before the manifest stage.
-    if (Phase == AttributorPhase::SEEDING || Phase == AttributorPhase::UPDATE)
+    if (isDuringDeduction())
       DG.SyntheticRoot.Deps.insert(
           AADepGraphNode::DepTy(&AA, unsigned(DepClassTy::REQUIRED)));
 
@@ -1745,7 +1745,7 @@ struct Attributor {
   template <typename AAType> bool shouldUpdateAA(const IRPosition &IRP) {
     // If this is queried in the manifest stage, we force the AA to indicate
     // pessimistic fixpoint immediately.
-    if (Phase == AttributorPhase::MANIFEST || Phase == AttributorPhase::CLEANUP)
+    if (!isDuringDeduction())
       return false;
 
     Function *AssociatedFn = IRP.getAssociatedFunction();
@@ -1821,6 +1821,11 @@ struct Attributor {
            (Configuration.IPOAmendableCB && Configuration.IPOAmendableCB(F));
   }
 
+  /// Return whether attributes can participate in fixed-point deduction.
+  bool isDuringDeduction() const {
+    return Phase == AttributorPhase::SEEDING || Phase == AttributorPhase::UPDATE;
+  }
+
   /// Mark the internal function \p F as live.
   ///
   /// This will trigger the identification and initialization of attributes for
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 22af6f7741544..ac4268f78143d 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -4673,6 +4673,9 @@ struct AAIsDeadFunction : public AAIsDead {
     if (!AssumedLiveBlocks.insert(&BB).second)
       return false;
 
+    if (!A.isDuringDeduction())
+      return true;
+
     // We assume that all of BB is (probably) live now and if there are calls to
     // internal functions we will assume that those are now live as well. This
     // is a performance optimization for blocks with calls to a lot of internal
diff --git a/llvm/unittests/Transforms/IPO/AttributorTest.cpp b/llvm/unittests/Transforms/IPO/AttributorTest.cpp
index 8d90b308f840c..9d3d64f75a458 100644
--- a/llvm/unittests/Transforms/IPO/AttributorTest.cpp
+++ b/llvm/unittests/Transforms/IPO/AttributorTest.cpp
@@ -212,4 +212,52 @@ TEST_F(AttributorTestBase, AAReachabilityTest) {
   ASSERT_FALSE(F9AA.instructionCanReach(A, F9FirstInst, F4));
 }
 
+TEST_F(AttributorTestBase, CleanupDoesNotSeedLiveCallees) {
+  for (bool SeedCaller : {false, true}) {
+    SCOPED_TRACE(SeedCaller);
+    Module &M = parseModule(R"(
+      define internal void @leaf() { ret void }
+      define internal void @sibling() { ret void }
+      define void @caller() {
+        call void @leaf()
+        call void @sibling()
+        ret void
+      }
+    )");
+    SetVector<Function *> Functions;
+    for (Function &F : M)
+      Functions.insert(&F);
+    AnalysisGetter AG;
+    CallGraphUpdater CGUpdater;
+    BumpPtrAllocator Allocator;
+    InformationCache InfoCache(M, AG, Allocator, nullptr);
+    AttributorConfig AC(CGUpdater);
+    AC.DefaultInitializeLiveInternals = false;
+    unsigned NumInitializations = 0;
+    // This callback observes markLiveInternalFunction without seeding other
+    // AAs.
+    AC.InitializationCallback = [&](Attributor &, const Function &) {
+      ++NumInitializations;
+    };
+    Attributor A(Functions, InfoCache, AC);
+    auto CallerPos = IRPosition::function(*M.getFunction("caller"));
+    EXPECT_EQ(A.lookupAAFor<AAIsDead>(CallerPos, nullptr, DepClassTy::NONE,
+                                      /*AllowInvalidState=*/true),
+              nullptr);
+    if (SeedCaller) {
+      // Control: discovering a live block during seeding still seeds callees.
+      A.getOrCreateAAFor<AAIsDead>(CallerPos);
+      EXPECT_EQ(NumInitializations, 2u);
+    }
+
+    // Without an initial AA, cleanup's dead-function check creates caller's
+    // liveness AA. Its initializer must not seed leaf or sibling.
+    EXPECT_EQ(A.run(), ChangeStatus::UNCHANGED);
+    EXPECT_NE(A.lookupAAFor<AAIsDead>(CallerPos, nullptr, DepClassTy::NONE,
+                                      /*AllowInvalidState=*/true),
+              nullptr);
+    EXPECT_EQ(NumInitializations, SeedCaller ? 2u : 0u);
+  }
+}
+
 } // namespace llvm

>From 9e090d13512b376ea01a8397905d5cb3b52ae4c9 Mon Sep 17 00:00:00 2001
From: "zhangjiatong.0" <zhangjiatong.0 at bytedance.com>
Date: Wed, 9 Sep 2026 13:46:22 +0800
Subject: [PATCH 2/2] clang format

---
 llvm/include/llvm/Transforms/IPO/Attributor.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 4cce13397a882..066883afafb95 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -1823,7 +1823,8 @@ struct Attributor {
 
   /// Return whether attributes can participate in fixed-point deduction.
   bool isDuringDeduction() const {
-    return Phase == AttributorPhase::SEEDING || Phase == AttributorPhase::UPDATE;
+    return Phase == AttributorPhase::SEEDING ||
+           Phase == AttributorPhase::UPDATE;
   }
 
   /// Mark the internal function \p F as live.



More information about the llvm-commits mailing list