@@ -31,6 +31,35 @@ static bool isAligned(const Value *Base, Align Alignment,
3131 return Base->getPointerAlignment (DL) >= Alignment;
3232}
3333
34+ static bool isDereferenceableAndAlignedPointerViaAssumption (
35+ const Value *Ptr, Align Alignment,
36+ function_ref<bool (const RetainedKnowledge &RK)> CheckSize,
37+ const DataLayout &DL, const Instruction *CtxI, AssumptionCache *AC,
38+ const DominatorTree *DT) {
39+ if (!CtxI || Ptr->canBeFreed ())
40+ return false ;
41+ // / Look through assumes to see if both dereferencability and alignment can
42+ // / be proven by an assume if needed.
43+ RetainedKnowledge AlignRK;
44+ RetainedKnowledge DerefRK;
45+ bool IsAligned = Ptr->getPointerAlignment (DL) >= Alignment;
46+ return getKnowledgeForValue (
47+ Ptr, {Attribute::Dereferenceable, Attribute::Alignment}, AC,
48+ [&](RetainedKnowledge RK, Instruction *Assume, auto ) {
49+ if (!isValidAssumeForContext (Assume, CtxI, DT))
50+ return false ;
51+ if (RK.AttrKind == Attribute::Alignment)
52+ AlignRK = std::max (AlignRK, RK);
53+ if (RK.AttrKind == Attribute::Dereferenceable)
54+ DerefRK = std::max (DerefRK, RK);
55+ IsAligned |= AlignRK && AlignRK.ArgValue >= Alignment.value ();
56+ if (IsAligned && DerefRK && CheckSize (DerefRK))
57+ return true ; // We have found what we needed so we stop looking
58+ return false ; // Other assumes may have better information. so
59+ // keep looking
60+ });
61+ }
62+
3463// / Test if V is always a pointer to allocated and suitably aligned memory for
3564// / a simple load or store.
3665static bool isDereferenceableAndAlignedPointer (
@@ -174,33 +203,41 @@ static bool isDereferenceableAndAlignedPointer(
174203 // information for values that cannot be freed in the function.
175204 // TODO: More precisely check if the pointer can be freed between assumption
176205 // and use.
177- if (CtxI && !V->canBeFreed ()) {
178- // / Look through assumes to see if both dereferencability and alignment can
179- // / be proven by an assume if needed.
180- RetainedKnowledge AlignRK;
181- RetainedKnowledge DerefRK;
182- bool IsAligned = V->getPointerAlignment (DL) >= Alignment;
183- if (getKnowledgeForValue (
184- V, {Attribute::Dereferenceable, Attribute::Alignment}, AC,
185- [&](RetainedKnowledge RK, Instruction *Assume, auto ) {
186- if (!isValidAssumeForContext (Assume, CtxI, DT))
187- return false ;
188- if (RK.AttrKind == Attribute::Alignment)
189- AlignRK = std::max (AlignRK, RK);
190- if (RK.AttrKind == Attribute::Dereferenceable)
191- DerefRK = std::max (DerefRK, RK);
192- IsAligned |= AlignRK && AlignRK.ArgValue >= Alignment.value ();
193- if (IsAligned && DerefRK &&
194- DerefRK.ArgValue >= Size.getZExtValue ())
195- return true ; // We have found what we needed so we stop looking
196- return false ; // Other assumes may have better information. so
197- // keep looking
198- }))
199- return true ;
206+ if (CtxI) {
207+ const Value *UO = getUnderlyingObjectAggressive (V);
208+ if (!V->canBeFreed () || (UO && !UO->canBeFreed ())) {
209+ // / Look through assumes to see if both dereferencability and alignment
210+ // / can be proven by an assume if needed.
211+ RetainedKnowledge AlignRK;
212+ RetainedKnowledge DerefRK;
213+ bool IsAligned = V->getPointerAlignment (DL) >= Alignment;
214+ if (getKnowledgeForValue (
215+ V, {Attribute::Dereferenceable, Attribute::Alignment}, AC,
216+ [&](RetainedKnowledge RK, Instruction *Assume, auto ) {
217+ if (!isValidAssumeForContext (Assume, CtxI, DT))
218+ return false ;
219+ if (RK.AttrKind == Attribute::Alignment)
220+ AlignRK = std::max (AlignRK, RK);
221+ if (RK.AttrKind == Attribute::Dereferenceable)
222+ DerefRK = std::max (DerefRK, RK);
223+ IsAligned |= AlignRK && AlignRK.ArgValue >= Alignment.value ();
224+ if (IsAligned && DerefRK &&
225+ DerefRK.ArgValue >= Size.getZExtValue ())
226+ return true ; // We have found what we needed so we stop
227+ // looking
228+ return false ; // Other assumes may have better information. so
229+ // keep looking
230+ }))
231+ return true ;
232+ }
200233 }
201234
202- // If we don't know, assume the worst.
203- return false ;
235+ return isDereferenceableAndAlignedPointerViaAssumption (
236+ V, Alignment,
237+ [Size](const RetainedKnowledge &RK) {
238+ return RK.ArgValue >= Size.getZExtValue ();
239+ },
240+ DL, CtxI, AC, DT);
204241}
205242
206243bool llvm::isDereferenceableAndAlignedPointer (
@@ -317,8 +354,8 @@ bool llvm::isDereferenceableAndAlignedInLoop(
317354 return false ;
318355
319356 const SCEV *MaxBECount =
320- Predicates ? SE.getPredicatedConstantMaxBackedgeTakenCount (L, *Predicates)
321- : SE.getConstantMaxBackedgeTakenCount (L);
357+ Predicates ? SE.getPredicatedSymbolicMaxBackedgeTakenCount (L, *Predicates)
358+ : SE.getSymbolicMaxBackedgeTakenCount (L);
322359 if (isa<SCEVCouldNotCompute>(MaxBECount))
323360 return false ;
324361
@@ -334,9 +371,11 @@ bool llvm::isDereferenceableAndAlignedInLoop(
334371
335372 Value *Base = nullptr ;
336373 APInt AccessSize;
374+ const SCEV *AccessSizeSCEV = nullptr ;
337375 if (const SCEVUnknown *NewBase = dyn_cast<SCEVUnknown>(AccessStart)) {
338376 Base = NewBase->getValue ();
339377 AccessSize = MaxPtrDiff;
378+ AccessSizeSCEV = PtrDiff;
340379 } else if (auto *MinAdd = dyn_cast<SCEVAddExpr>(AccessStart)) {
341380 if (MinAdd->getNumOperands () != 2 )
342381 return false ;
@@ -360,12 +399,20 @@ bool llvm::isDereferenceableAndAlignedInLoop(
360399 return false ;
361400
362401 AccessSize = MaxPtrDiff + Offset->getAPInt ();
402+ AccessSizeSCEV = SE.getAddExpr (PtrDiff, Offset);
363403 Base = NewBase->getValue ();
364404 } else
365405 return false ;
366406
367407 Instruction *HeaderFirstNonPHI = &*L->getHeader ()->getFirstNonPHIIt ();
368- return isDereferenceableAndAlignedPointer (Base, Alignment, AccessSize, DL,
408+ return isDereferenceableAndAlignedPointerViaAssumption (
409+ Base, Alignment,
410+ [&SE, PtrDiff](const RetainedKnowledge &RK) {
411+ return SE.isKnownPredicate (CmpInst::ICMP_ULE, PtrDiff,
412+ SE.getSCEV (RK.IRArgValue ));
413+ },
414+ DL, HeaderFirstNonPHI, AC, &DT) ||
415+ isDereferenceableAndAlignedPointer (Base, Alignment, AccessSize, DL,
369416 HeaderFirstNonPHI, AC, &DT);
370417}
371418
0 commit comments