@@ -31,6 +31,35 @@ static bool isAligned(const Value *Base, Align Alignment,
31
31
return Base->getPointerAlignment (DL) >= Alignment;
32
32
}
33
33
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
+
34
63
// / Test if V is always a pointer to allocated and suitably aligned memory for
35
64
// / a simple load or store.
36
65
static bool isDereferenceableAndAlignedPointer (
@@ -199,8 +228,12 @@ static bool isDereferenceableAndAlignedPointer(
199
228
return true ;
200
229
}
201
230
202
- // If we don't know, assume the worst.
203
- return false ;
231
+ return isDereferenceableAndAlignedPointerViaAssumption (
232
+ V, Alignment,
233
+ [Size](const RetainedKnowledge &RK) {
234
+ return RK.ArgValue >= Size.getZExtValue ();
235
+ },
236
+ DL, CtxI, AC, DT);
204
237
}
205
238
206
239
bool llvm::isDereferenceableAndAlignedPointer (
@@ -317,8 +350,8 @@ bool llvm::isDereferenceableAndAlignedInLoop(
317
350
return false ;
318
351
319
352
const SCEV *MaxBECount =
320
- Predicates ? SE.getPredicatedConstantMaxBackedgeTakenCount (L, *Predicates)
321
- : SE.getConstantMaxBackedgeTakenCount (L);
353
+ Predicates ? SE.getPredicatedSymbolicMaxBackedgeTakenCount (L, *Predicates)
354
+ : SE.getSymbolicMaxBackedgeTakenCount (L);
322
355
const SCEV *BECount = Predicates
323
356
? SE.getPredicatedBackedgeTakenCount (L, *Predicates)
324
357
: SE.getBackedgeTakenCount (L);
@@ -339,9 +372,11 @@ bool llvm::isDereferenceableAndAlignedInLoop(
339
372
340
373
Value *Base = nullptr ;
341
374
APInt AccessSize;
375
+ const SCEV *AccessSizeSCEV = nullptr ;
342
376
if (const SCEVUnknown *NewBase = dyn_cast<SCEVUnknown>(AccessStart)) {
343
377
Base = NewBase->getValue ();
344
378
AccessSize = MaxPtrDiff;
379
+ AccessSizeSCEV = PtrDiff;
345
380
} else if (auto *MinAdd = dyn_cast<SCEVAddExpr>(AccessStart)) {
346
381
if (MinAdd->getNumOperands () != 2 )
347
382
return false ;
@@ -365,12 +400,20 @@ bool llvm::isDereferenceableAndAlignedInLoop(
365
400
return false ;
366
401
367
402
AccessSize = MaxPtrDiff + Offset->getAPInt ();
403
+ AccessSizeSCEV = SE.getAddExpr (PtrDiff, Offset);
368
404
Base = NewBase->getValue ();
369
405
} else
370
406
return false ;
371
407
372
408
Instruction *HeaderFirstNonPHI = &*L->getHeader ()->getFirstNonPHIIt ();
373
- return isDereferenceableAndAlignedPointer (Base, Alignment, AccessSize, DL,
409
+ return isDereferenceableAndAlignedPointerViaAssumption (
410
+ Base, Alignment,
411
+ [&SE, PtrDiff](const RetainedKnowledge &RK) {
412
+ return SE.isKnownPredicate (CmpInst::ICMP_ULE, PtrDiff,
413
+ SE.getSCEV (RK.IRArgValue ));
414
+ },
415
+ DL, HeaderFirstNonPHI, AC, &DT) ||
416
+ isDereferenceableAndAlignedPointer (Base, Alignment, AccessSize, DL,
374
417
HeaderFirstNonPHI, AC, &DT);
375
418
}
376
419
0 commit comments