4444
4545using namespace llvm ;
4646using namespace VPlanPatternMatch ;
47+ using namespace SCEVPatternMatch ;
4748
4849bool VPlanTransforms::tryToConvertVPInstructionsToVPRecipes (
4950 VPlan &Plan,
@@ -155,38 +156,36 @@ static bool isNoAliasViaDistance(VPReplicateRecipe *A, VPReplicateRecipe *B,
155156 if (isa<SCEVCouldNotCompute>(SCEVA) || isa<SCEVCouldNotCompute>(SCEVB))
156157 return false ;
157158
158- const SCEV *Distance = SE.getMinusSCEV (SCEVA, SCEVB);
159- auto *ConstDist = dyn_cast<SCEVConstant>(Distance);
160- if (!ConstDist)
159+ const APInt *Distance;
160+ if (!match (SE.getMinusSCEV (SCEVA, SCEVB), m_scev_APInt (Distance)))
161161 return false ;
162162
163163 const DataLayout &DL = L.getHeader ()->getModule ()->getDataLayout ();
164164 Type *TyA = TypeInfo.inferScalarType (A->getOperand (0 ));
165- TypeSize SizeA = DL.getTypeStoreSize (TyA);
165+ uint64_t SizeA = DL.getTypeStoreSize (TyA);
166166 Type *TyB = TypeInfo.inferScalarType (B->getOperand (0 ));
167- TypeSize SizeB = DL.getTypeStoreSize (TyB);
168-
167+ uint64_t SizeB = DL.getTypeStoreSize (TyB);
169168 // Use the maximum store size to ensure no overlap from either direction.
170- uint64_t MaxStoreSize =
171- std::max (SizeA.getFixedValue (), SizeB.getFixedValue ());
172- const APInt &DistValue = ConstDist->getAPInt ();
169+ uint64_t MaxStoreSize = std::max (SizeA, SizeB);
170+
173171 auto VFs = B->getParent ()->getPlan ()->vectorFactors ();
174172 ElementCount MaxVF = *max_element (VFs, ElementCount::isKnownLT);
175- return DistValue. abs ().uge (
173+ return Distance-> abs ().uge (
176174 MaxVF.multiplyCoefficientBy (MaxStoreSize).getFixedValue ());
177175}
178176
179177// Check if a memory operation doesn't alias with memory operations in blocks
180- // between FirstBB and LastBB using scoped noalias metadata.
181- // For load hoisting, we only check writes in one direction.
182- // For store sinking, we check both reads and writes bidirectionally.
178+ // between FirstBB and LastBB using scoped noalias metadata. If \p CheckReads is
179+ // false, we only check recipes that may write to memory. Otherwise we check
180+ // recipes that both read and write memory. If a \p GroupLeader is passed, SCEV
181+ // is used to try to prove no-alias between \p GroupLeader and other replicate
182+ // recipes.
183183static bool canHoistOrSinkWithNoAliasCheck (
184184 const MemoryLocation &MemLoc, VPBasicBlock *FirstBB, VPBasicBlock *LastBB,
185185 bool CheckReads,
186186 const SmallPtrSetImpl<VPRecipeBase *> *ExcludeRecipes = nullptr ,
187- ScalarEvolution *SE = nullptr , const Loop *L = nullptr ,
188- VPTypeAnalysis *TypeInfo = nullptr ,
189- ArrayRef<VPReplicateRecipe *> MemOpsInGroup = {}) {
187+ VPReplicateRecipe *GroupLeader = nullptr , ScalarEvolution *SE = nullptr ,
188+ const Loop *L = nullptr , VPTypeAnalysis *TypeInfo = nullptr ) {
190189 if (!MemLoc.AATags .Scope )
191190 return false ;
192191
@@ -205,10 +204,12 @@ static bool canHoistOrSinkWithNoAliasCheck(
205204 if (!R.mayWriteToMemory () && !(CheckReads && R.mayReadFromMemory ()))
206205 continue ;
207206
208- // For stores, check if we can use SCEV to prove no-alias.
207+ // For stores, check if we can use SCEV to prove no-alias with the group
208+ // leader (all members of the group write to the same address with the
209+ // same size).
209210 if (auto *Store = dyn_cast<VPReplicateRecipe>(&R)) {
210- if (SE && L && TypeInfo && !MemOpsInGroup. empty () &&
211- isNoAliasViaDistance (Store, MemOpsInGroup[ 0 ] , *SE, *L, *TypeInfo))
211+ if (GroupLeader &&
212+ isNoAliasViaDistance (Store, GroupLeader , *SE, *L, *TypeInfo))
212213 continue ;
213214 }
214215
@@ -4359,7 +4360,7 @@ canSinkStoreWithNoAliasCheck(ArrayRef<VPReplicateRecipe *> StoresToSink,
43594360 VPBasicBlock *LastBB = StoresToSink.back ()->getParent ();
43604361 return canHoistOrSinkWithNoAliasCheck (*StoreLoc, FirstBB, LastBB,
43614362 /* CheckReads=*/ true , &StoresToSinkSet,
4362- SE, L, &TypeInfo, StoresToSink );
4363+ StoresToSink[ 0 ], SE, L, &TypeInfo);
43634364}
43644365
43654366void VPlanTransforms::sinkPredicatedStores (VPlan &Plan, ScalarEvolution &SE,
0 commit comments