[llvm] [JumpThreading] Add fast path for single-pred blocks in redirectValuesFromPredecessorsToPhi (PR #173596)

via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 25 22:55:18 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: None (int-zjt)

<details>
<summary>Changes</summary>

This patch adds a fast path to `redirectValuesFromPredecessorsToPhi` to skip the `gatherIncomingValuesToPhi` call when possible.

Currently, `gatherIncomingValuesToPhi` populates a `SmallDenseMap` with all incoming values of the PHI node. When the PHI node has a large number of incoming values, this process triggers frequent resizing and rehashing of the map, leading to significant compile-time overhead.

However, if the block `BB` has exactly one predecessor and the incoming value used by `PN` is not defined within `BB`, we don't need to resolve any value mappings. We can simply propagate the existing value. This fast path completely avoids the O(N) map construction cost for this common scenario.


---
Full diff: https://github.com/llvm/llvm-project/pull/173596.diff


1 Files Affected:

- (modified) llvm/lib/Transforms/Utils/Local.cpp (+13) 


``````````diff
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index f7842a235b20d..9e5115d0b0795 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1077,6 +1077,19 @@ static void redirectValuesFromPredecessorsToPhi(BasicBlock *BB,
   Value *OldVal = PN->removeIncomingValue(BB, false);
   assert(OldVal && "No entry in PHI for Pred BB!");
 
+  // Fast path: If BB has a single predecessor and the incoming value is not
+  // defined in BB itself, we can directly redirect the edge.
+  //
+  // Note: We rely on TryToSimplifyUncondBranchFromEmptyBlock (the caller) to
+  // have already verified via CanPropagatePredecessorsForPHIs that merging
+  // blocks won't introduce value conflicts for any common predecessors.
+  auto *BBSinglePred = BB->getSinglePredecessor();
+  Instruction *OldInst = dyn_cast<Instruction>(OldVal);
+  if (BBSinglePred && OldInst && OldInst->getParent() != BB) {
+    PN->addIncoming(OldVal, BBSinglePred);
+    return;
+  }
+
   IncomingValueMap IncomingValues;
 
   // We are merging two blocks - BB, and the block containing PN - and

``````````

</details>


https://github.com/llvm/llvm-project/pull/173596


More information about the llvm-commits mailing list