[llvm] [AMDGPU] Promote allocas used by phi/select (PR #221870)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 10 02:22:17 PDT 2026


================
@@ -280,6 +314,51 @@ bool AMDGPUPromoteAllocaImpl::collectAllocaUses(AllocaAnalysis &AA) const {
   };
 
   SmallVector<Instruction *, 4> WorkList({AA.Alloca});
+
+  // Classify the "other" operand of a pointer phi/select (i.e. an operand not
+  // derived from Cur). Returns false if the merge makes the alloca entirely
+  // unpromotable (merged with an unknown object). Otherwise records links to
+  // any other allocas (for grouping).
+  //
+  // The operand may itself be a chain of phis/selects (e.g. a phi of a phi), so
+  // we look through them to find the set of underlying root allocas. Visited
+  // guards against cyclic pointer phis.
+  SmallPtrSet<Value *, 8> Visited;
+  std::function<bool(Value *)> ClassifyMergeOperand = [&](Value *Other) -> bool {
+    Other = Other->stripPointerCasts();
+    if (AA.Pointers.contains(Other))
+      return true; // Derived from the same pointer.
+    if (!Visited.insert(Other).second)
+      return true; // Already classified (or on a phi cycle).
+
+    if (isa<ConstantPointerNull, ConstantAggregateZero>(Other)) {
+      // Fine for LDS (null stays null), but we can't give it a vector lane.
+      AA.HaveUnpromotableMerge = true;
+      return true;
+    }
+
+    Value *Obj = getUnderlyingObject(Other);
+    // getUnderlyingObject looks through GEPs/casts but not phi/select; recurse
+    // through those to reach the root allocas.
+    if (auto *Phi = dyn_cast<PHINode>(Obj)) {
+      for (Value *In : Phi->incoming_values())
+        if (!ClassifyMergeOperand(In))
+          return false;
+      return true;
+    }
----------------
ruiling wrote:

Yes, that is helpful, I have switch to it and the implementation here is much simpler.

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


More information about the llvm-commits mailing list