[llvm] [Uniformity] Avoid marking all PHIs as divergent in join blocks (PR #157808)
David Stuttard via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 10 01:20:36 PDT 2025
================
@@ -930,6 +933,44 @@ void GenericUniformityAnalysisImpl<ContextT>::taintAndPushPhiNodes(
// https://reviews.llvm.org/D19013
if (ContextT::isConstantOrUndefValuePhi(Phi))
continue;
+
+ // Attempt to maintain uniformity for PHIs by considering control
+ // dependencies.
+ SmallVector<ConstValueRefT> Values;
+ SmallVector<const BlockT *> Blocks;
+ Context.getPhiInputs(Phi, Values, Blocks);
+ assert(Blocks.size() == Values.size());
+
+ // Allow an empty Blocks/Values list to signify getPhiInputs is not
+ // implemented; in which case no uniformity is possible.
+ bool Uniform = !Values.empty();
+
+ std::optional<ConstValueRefT> CommonValue;
+ for (unsigned I = 0; I < Blocks.size() && Uniform; ++I) {
+ if (DivDesc.CycleDivBlocks.contains(Blocks[I])) {
+ // If PHI is reachable via divergent exit it is divergent.
+ Uniform = false;
+ } else if (DT.dominates(&DivTermBlock, Blocks[I]) ||
+ DivDesc.BlockLabels.lookup_or(Blocks[I], nullptr)) {
+ // If all edges from the marked path share a common value then
+ // uniformity is preserved when the value is itself uniform.
+ if (!CommonValue)
+ CommonValue = Values[I];
+ else
+ Uniform = Values[I] == *CommonValue;
+ }
+ // Ignore undefined values when checking definitions.
+ if (!Values[I])
----------------
dstutt wrote:
If Values[I] is undefined, and it isn't the first one - won't Uniform already be set to false?
https://github.com/llvm/llvm-project/pull/157808
More information about the llvm-commits
mailing list