@@ -150,24 +150,26 @@ const SCEV *vputils::getSCEVExprForVPValue(const VPValue *V,
150150 .Default ([&SE](const VPRecipeBase *) { return SE.getCouldNotCompute (); });
151151}
152152
153- bool vputils::isSingleScalar (const VPValue *VPV) {
154- auto PreservesUniformity = [](unsigned Opcode) -> bool {
155- if (Instruction::isBinaryOp (Opcode) || Instruction::isCast (Opcode))
156- return true ;
157- switch (Opcode) {
158- case Instruction::GetElementPtr:
159- case Instruction::ICmp:
160- case Instruction::FCmp:
161- case Instruction::Select:
162- case VPInstruction::Not:
163- case VPInstruction::Broadcast:
164- case VPInstruction::PtrAdd:
165- return true ;
166- default :
167- return false ;
168- }
169- };
153+ // / Returns true if \p Opcode preserves uniformity, i.e., if all operands are
154+ // / uniform, the result will also be uniform.
155+ static bool preservesUniformity (unsigned Opcode) {
156+ if (Instruction::isBinaryOp (Opcode) || Instruction::isCast (Opcode))
157+ return true ;
158+ switch (Opcode) {
159+ case Instruction::GetElementPtr:
160+ case Instruction::ICmp:
161+ case Instruction::FCmp:
162+ case Instruction::Select:
163+ case VPInstruction::Not:
164+ case VPInstruction::Broadcast:
165+ case VPInstruction::PtrAdd:
166+ return true ;
167+ default :
168+ return false ;
169+ }
170+ }
170171
172+ bool vputils::isSingleScalar (const VPValue *VPV) {
171173 // A live-in must be uniform across the scope of VPlan.
172174 if (VPV->isLiveIn ())
173175 return true ;
@@ -179,19 +181,19 @@ bool vputils::isSingleScalar(const VPValue *VPV) {
179181 // lanes.
180182 if (RegionOfR && RegionOfR->isReplicator ())
181183 return false ;
182- return Rep->isSingleScalar () || (PreservesUniformity (Rep->getOpcode ()) &&
184+ return Rep->isSingleScalar () || (preservesUniformity (Rep->getOpcode ()) &&
183185 all_of (Rep->operands (), isSingleScalar));
184186 }
185187 if (isa<VPWidenGEPRecipe, VPDerivedIVRecipe, VPBlendRecipe,
186188 VPWidenSelectRecipe>(VPV))
187189 return all_of (VPV->getDefiningRecipe ()->operands (), isSingleScalar);
188190 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
189- return PreservesUniformity (WidenR->getOpcode ()) &&
191+ return preservesUniformity (WidenR->getOpcode ()) &&
190192 all_of (WidenR->operands (), isSingleScalar);
191193 }
192194 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
193195 return VPI->isSingleScalar () || VPI->isVectorToScalar () ||
194- (PreservesUniformity (VPI->getOpcode ()) &&
196+ (preservesUniformity (VPI->getOpcode ()) &&
195197 all_of (VPI->operands (), isSingleScalar));
196198 if (isa<VPPartialReductionRecipe>(VPV))
197199 return false ;
@@ -234,9 +236,15 @@ bool vputils::isUniformAcrossVFsAndUFs(VPValue *V) {
234236 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr ())) &&
235237 all_of (R->operands (), isUniformAcrossVFsAndUFs);
236238 })
239+ .Case <VPWidenRecipe>([](const auto *R) {
240+ return preservesUniformity (R->getOpcode ()) &&
241+ all_of (R->operands (), isUniformAcrossVFsAndUFs);
242+ })
237243 .Case <VPInstruction>([](const auto *VPI) {
238- return VPI->isScalarCast () &&
239- isUniformAcrossVFsAndUFs (VPI->getOperand (0 ));
244+ return (VPI->isScalarCast () &&
245+ isUniformAcrossVFsAndUFs (VPI->getOperand (0 ))) ||
246+ (preservesUniformity (VPI->getOpcode ()) &&
247+ all_of (VPI->operands (), isUniformAcrossVFsAndUFs));
240248 })
241249 .Case <VPWidenCastRecipe>([](const auto *R) {
242250 // A cast is uniform according to its operand.
0 commit comments