@@ -1312,20 +1312,18 @@ void AccessAnalysis::processMemAccesses() {
1312
1312
}
1313
1313
}
1314
1314
1315
- static bool isInBoundsGep (Value *Ptr) {
1316
- if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr))
1317
- return GEP->isInBounds ();
1318
- return false ;
1319
- }
1320
-
1321
1315
// / Return true if an AddRec pointer \p Ptr is unsigned non-wrapping,
1322
1316
// / i.e. monotonically increasing/decreasing.
1323
1317
static bool isNoWrapAddRec (Value *Ptr, const SCEVAddRecExpr *AR,
1324
1318
PredicatedScalarEvolution &PSE, const Loop *L) {
1319
+
1325
1320
// FIXME: This should probably only return true for NUW.
1326
1321
if (AR->getNoWrapFlags (SCEV::NoWrapMask))
1327
1322
return true ;
1328
1323
1324
+ if (PSE.hasNoOverflow (Ptr, SCEVWrapPredicate::IncrementNUSW))
1325
+ return true ;
1326
+
1329
1327
// Scalar evolution does not propagate the non-wrapping flags to values that
1330
1328
// are derived from a non-wrapping induction variable because non-wrapping
1331
1329
// could be flow-sensitive.
@@ -1400,35 +1398,6 @@ std::optional<int64_t> llvm::getPtrStride(PredicatedScalarEvolution &PSE,
1400
1398
return std::nullopt;
1401
1399
}
1402
1400
1403
- // The address calculation must not wrap. Otherwise, a dependence could be
1404
- // inverted.
1405
- // An inbounds getelementptr that is a AddRec with a unit stride
1406
- // cannot wrap per definition. The unit stride requirement is checked later.
1407
- // An getelementptr without an inbounds attribute and unit stride would have
1408
- // to access the pointer value "0" which is undefined behavior in address
1409
- // space 0, therefore we can also vectorize this case.
1410
- unsigned AddrSpace = Ty->getPointerAddressSpace ();
1411
- bool IsInBoundsGEP = isInBoundsGep (Ptr);
1412
- bool IsNoWrapAddRec = !ShouldCheckWrap ||
1413
- PSE.hasNoOverflow (Ptr, SCEVWrapPredicate::IncrementNUSW) ||
1414
- isNoWrapAddRec (Ptr, AR, PSE, Lp);
1415
- if (!IsNoWrapAddRec && !IsInBoundsGEP &&
1416
- NullPointerIsDefined (Lp->getHeader ()->getParent (), AddrSpace)) {
1417
- if (!Assume) {
1418
- LLVM_DEBUG (
1419
- dbgs () << " LAA: Bad stride - Pointer may wrap in the address space "
1420
- << *Ptr << " SCEV: " << *AR << " \n " );
1421
- return std::nullopt;
1422
- }
1423
-
1424
- PSE.setNoOverflow (Ptr, SCEVWrapPredicate::IncrementNUSW);
1425
- IsNoWrapAddRec = true ;
1426
- LLVM_DEBUG (dbgs () << " LAA: Pointer may wrap in the address space:\n "
1427
- << " LAA: Pointer: " << *Ptr << " \n "
1428
- << " LAA: SCEV: " << *AR << " \n "
1429
- << " LAA: Added an overflow assumption\n " );
1430
- }
1431
-
1432
1401
// Check the step is constant.
1433
1402
const SCEV *Step = AR->getStepRecurrence (*PSE.getSE ());
1434
1403
@@ -1457,25 +1426,42 @@ std::optional<int64_t> llvm::getPtrStride(PredicatedScalarEvolution &PSE,
1457
1426
if (Rem)
1458
1427
return std::nullopt;
1459
1428
1460
- // If the SCEV could wrap but we have an inbounds gep with a unit stride we
1461
- // know we can't "wrap around the address space". In case of address space
1462
- // zero we know that this won't happen without triggering undefined behavior.
1463
- if (!IsNoWrapAddRec && Stride != 1 && Stride != -1 &&
1464
- (IsInBoundsGEP || !NullPointerIsDefined (Lp->getHeader ()->getParent (),
1465
- AddrSpace))) {
1466
- if (!Assume)
1467
- return std::nullopt;
1429
+ if (!ShouldCheckWrap)
1430
+ return Stride;
1431
+
1432
+ // The address calculation must not wrap. Otherwise, a dependence could be
1433
+ // inverted.
1434
+ if (isNoWrapAddRec (Ptr, AR, PSE, Lp))
1435
+ return Stride;
1436
+
1437
+ // An inbounds getelementptr that is a AddRec with a unit stride
1438
+ // cannot wrap per definition. If it did, the result would be poison
1439
+ // and any memory access dependent on it would be immediate UB
1440
+ // when executed.
1441
+ if (auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
1442
+ GEP && GEP->isInBounds () && (Stride == 1 || Stride == -1 ))
1443
+ return Stride;
1444
+
1445
+ // If the null pointer is undefined, then a access sequence which would
1446
+ // otherwise access it can be assumed not to unsigned wrap. Note that this
1447
+ // assumes the object in memory is aligned to the natural alignment.
1448
+ unsigned AddrSpace = Ty->getPointerAddressSpace ();
1449
+ if (!NullPointerIsDefined (Lp->getHeader ()->getParent (), AddrSpace) &&
1450
+ (Stride == 1 || Stride == -1 ))
1451
+ return Stride;
1468
1452
1469
- // We can avoid this case by adding a run-time check.
1470
- LLVM_DEBUG ( dbgs () << " LAA: Non unit strided pointer which is not either "
1471
- << " inbounds or in address space 0 may wrap:\n "
1453
+ if (Assume) {
1454
+ PSE. setNoOverflow (Ptr, SCEVWrapPredicate::IncrementNUSW);
1455
+ LLVM_DEBUG ( dbgs () << " LAA: Pointer may wrap:\n "
1472
1456
<< " LAA: Pointer: " << *Ptr << " \n "
1473
1457
<< " LAA: SCEV: " << *AR << " \n "
1474
1458
<< " LAA: Added an overflow assumption\n " );
1475
- PSE. setNoOverflow (Ptr, SCEVWrapPredicate::IncrementNUSW) ;
1459
+ return Stride ;
1476
1460
}
1477
-
1478
- return Stride;
1461
+ LLVM_DEBUG (
1462
+ dbgs () << " LAA: Bad stride - Pointer may wrap in the address space "
1463
+ << *Ptr << " SCEV: " << *AR << " \n " );
1464
+ return std::nullopt;
1479
1465
}
1480
1466
1481
1467
std::optional<int > llvm::getPointersDiff (Type *ElemTyA, Value *PtrA,
0 commit comments