[llvm] [LAA] Be more careful when evaluating AddRecs at symbolic max BTC. (PR #128061)
David Sherwood via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 27 08:03:21 PDT 2025
================
@@ -188,9 +188,56 @@ RuntimeCheckingPtrGroup::RuntimeCheckingPtrGroup(
Members.push_back(Index);
}
+/// Return true, if evaluating \p AR at \p MaxBTC cannot wrap, because \p AR at
+/// \p MaxBTC is guaranteed inbounds of the accessed object.
+static bool evaluateAddRecAtMaxBTCWillNotWrap(const SCEVAddRecExpr *AR,
+ const SCEV *MaxBTC,
+ ScalarEvolution &SE,
+ const DataLayout &DL) {
+ auto *PointerBase = SE.getPointerBase(AR->getStart());
+ auto *StartPtr = dyn_cast<SCEVUnknown>(PointerBase);
+ if (!StartPtr)
+ return false;
+ bool CheckForNonNull, CheckForFreed;
+ uint64_t DerefBytes = StartPtr->getValue()->getPointerDereferenceableBytes(
+ DL, CheckForNonNull, CheckForFreed);
+
+ if (CheckForNonNull || CheckForFreed)
+ return false;
+
+ const SCEV *Step = AR->getStepRecurrence(SE);
+ Type *WiderTy = SE.getWiderType(MaxBTC->getType(), Step->getType());
+ Step = SE.getNoopOrSignExtend(Step, WiderTy);
+ MaxBTC = SE.getNoopOrSignExtend(MaxBTC, WiderTy);
+ if (SE.isKnownPositive(Step)) {
+ // For positive steps, check if (AR->getStart() - StartPtr) + MaxBTC <=
+ // DerefBytes / Step
+ const SCEV *StartOffset = SE.getNoopOrSignExtend(
+ SE.getMinusSCEV(AR->getStart(), StartPtr), WiderTy);
+ return SE.isKnownPredicate(
+ CmpInst::ICMP_ULE, SE.getAddExpr(StartOffset, MaxBTC),
+ SE.getUDivExpr(SE.getConstant(WiderTy, DerefBytes), Step));
+ }
+ if (SE.isKnownNegative(Step)) {
+ // For negative steps, check using StartOffset == AR->getStart() - StartPtr:
+ // * StartOffset >= MaxBTC * Step
+ // * AND StartOffset <= DerefBytes / Step
----------------
david-arm wrote:
This seems inconsistent - the first condition treats StartOffset in units of bytes (i.e. >= MaxBTC * Step), whereas the second condition treats StartOffset in units of steps. Given that the StartOffset is not guaranteed to be a multiple of Step I think this should be:
```
// * StartOffset >= MaxBTC * abs(Step)
// * AND StartOffset <= DerefBytes
```
https://github.com/llvm/llvm-project/pull/128061
More information about the llvm-commits
mailing list