@@ -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 (
@@ -174,33 +203,41 @@ static bool isDereferenceableAndAlignedPointer(
174
203
// information for values that cannot be freed in the function.
175
204
// TODO: More precisely check if the pointer can be freed between assumption
176
205
// 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
+ }
200
233
}
201
234
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);
204
241
}
205
242
206
243
bool llvm::isDereferenceableAndAlignedPointer (
@@ -317,8 +354,8 @@ bool llvm::isDereferenceableAndAlignedInLoop(
317
354
return false ;
318
355
319
356
const SCEV *MaxBECount =
320
- Predicates ? SE.getPredicatedConstantMaxBackedgeTakenCount (L, *Predicates)
321
- : SE.getConstantMaxBackedgeTakenCount (L);
357
+ Predicates ? SE.getPredicatedSymbolicMaxBackedgeTakenCount (L, *Predicates)
358
+ : SE.getSymbolicMaxBackedgeTakenCount (L);
322
359
if (isa<SCEVCouldNotCompute>(MaxBECount))
323
360
return false ;
324
361
@@ -334,9 +371,11 @@ bool llvm::isDereferenceableAndAlignedInLoop(
334
371
335
372
Value *Base = nullptr ;
336
373
APInt AccessSize;
374
+ const SCEV *AccessSizeSCEV = nullptr ;
337
375
if (const SCEVUnknown *NewBase = dyn_cast<SCEVUnknown>(AccessStart)) {
338
376
Base = NewBase->getValue ();
339
377
AccessSize = MaxPtrDiff;
378
+ AccessSizeSCEV = PtrDiff;
340
379
} else if (auto *MinAdd = dyn_cast<SCEVAddExpr>(AccessStart)) {
341
380
if (MinAdd->getNumOperands () != 2 )
342
381
return false ;
@@ -360,12 +399,20 @@ bool llvm::isDereferenceableAndAlignedInLoop(
360
399
return false ;
361
400
362
401
AccessSize = MaxPtrDiff + Offset->getAPInt ();
402
+ AccessSizeSCEV = SE.getAddExpr (PtrDiff, Offset);
363
403
Base = NewBase->getValue ();
364
404
} else
365
405
return false ;
366
406
367
407
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,
369
416
HeaderFirstNonPHI, AC, &DT);
370
417
}
371
418
0 commit comments