@@ -930,6 +930,49 @@ bool WIAnalysisRunner::isWaveBroadcastIndex(const llvm::Instruction* inst)
930
930
return false ;
931
931
}
932
932
933
+ // Checks all incoming values of PHI for a unique value, including PHI nodes that
934
+ // loop back on itself. We ignore undef values as not counting towards a unique incoming value.
935
+ static bool hasUniqueIncoming (llvm::PHINode* PN, Value*& UniqueVal, std::set<PHINode*>& phiLoop)
936
+ {
937
+ UniqueVal = nullptr ;
938
+ phiLoop.insert (PN);
939
+
940
+ for (Value* V : PN->incoming_values ())
941
+ {
942
+ if (isa<UndefValue>(V))
943
+ continue ;
944
+
945
+ if (auto * phi = dyn_cast<PHINode>(V))
946
+ {
947
+ // Ignore previously seen PHIs
948
+ if (phiLoop.count (phi) > 0 )
949
+ continue ;
950
+
951
+ Value* temp;
952
+ if (hasUniqueIncoming (phi, temp, phiLoop))
953
+ {
954
+ V = temp;
955
+ }
956
+ }
957
+
958
+ if (!UniqueVal)
959
+ UniqueVal = V;
960
+ else if (UniqueVal != V)
961
+ {
962
+ UniqueVal = nullptr ;
963
+ return false ;
964
+ }
965
+ }
966
+ return true ;
967
+ }
968
+
969
+ bool WIAnalysisRunner::hasUniqueNonUndef (llvm::PHINode* PN)
970
+ {
971
+ Value* temp;
972
+ std::set<PHINode*> phiLoop;
973
+ return hasUniqueIncoming (PN, temp, phiLoop);
974
+ }
975
+
933
976
void WIAnalysisRunner::update_cf_dep (const IGCLLVM::TerminatorInst* inst)
934
977
{
935
978
IGC_ASSERT (hasDependency (inst));
@@ -1098,14 +1141,23 @@ void WIAnalysisRunner::updatePHIDepAtJoin(BasicBlock* blk, BranchInfo* brInfo)
1098
1141
continue ;
1099
1142
}
1100
1143
Value* trickySrc = nullptr ;
1144
+ bool isUnique = hasUniqueNonUndef (phi);
1101
1145
for (unsigned predIdx = 0 ; predIdx < phi->getNumOperands (); ++predIdx)
1102
1146
{
1103
1147
Value* srcVal = phi->getOperand (predIdx);
1104
1148
Instruction* defi = dyn_cast<Instruction>(srcVal);
1105
1149
if (defi && brInfo->influence_region .count (defi->getParent ()))
1106
1150
{
1107
- updateDepMap (phi, brDep);
1108
- break ;
1151
+ // If we have a phi join that looks like this:
1152
+ // %v = phi i32 [ %x, %if ], [ undef, %else ]
1153
+ //
1154
+ // Then if %x is uniform, %v isn't really non-uniform because
1155
+ // there will be no phi-mov associated with the undef.
1156
+ if (!isUnique)
1157
+ {
1158
+ updateDepMap (phi, brDep);
1159
+ break ;
1160
+ }
1109
1161
}
1110
1162
else
1111
1163
{
@@ -1120,7 +1172,7 @@ void WIAnalysisRunner::updatePHIDepAtJoin(BasicBlock* blk, BranchInfo* brInfo)
1120
1172
{
1121
1173
trickySrc = srcVal;
1122
1174
}
1123
- else if (trickySrc != srcVal)
1175
+ else if (trickySrc != srcVal && !isUnique )
1124
1176
{
1125
1177
updateDepMap (phi, brDep);
1126
1178
break ;
0 commit comments