[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