[llvm-branch-commits] [llvm] [DA] Add precondition `0 <=s UB` to function `inferAffineDomain` (PR #187218)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Mar 18 02:31:30 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Ryotaro Kasuga (kasuga-fj)
<details>
<summary>Changes</summary>
This patch fixes issues where the Exact SIV/RDIV tests can return incorrect results when the BTC is negative in a signed sense. The root cause is that BTCs should be interpreted in an unsigned sense, but `inferAffineDomain` uses the BTC in inequalities that are interpreted in a signed sense. These inequalities make sense only when the BTC is non-negative. Thus we need to check it beforehand.
---
Full diff: https://github.com/llvm/llvm-project/pull/187218.diff
2 Files Affected:
- (modified) llvm/lib/Analysis/DependenceAnalysis.cpp (+23-12)
- (modified) llvm/test/Analysis/DependenceAnalysis/rdiv-large-btc.ll (+2-2)
``````````diff
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 01300d0acbdf1..83777fe82afe2 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -1561,11 +1561,11 @@ ceilingOfQuotient(const OverflowSafeSignedAPInt &OA,
/// integer, infer the possible range of k based on the known range of the
/// affine expression. If we know A*k + B is non-negative, i.e.,
///
-/// A*k + B >= 0
+/// A*k + B >=s 0
///
/// we can derive the following inequalities for k when A is positive:
///
-/// k >= -B / A
+/// k >=s -B / A
///
/// Since k is an integer, it means k is greater than or equal to the
/// ceil(-B / A).
@@ -1573,11 +1573,11 @@ ceilingOfQuotient(const OverflowSafeSignedAPInt &OA,
/// If the upper bound of the affine expression \p UB is passed, the following
/// inequality can be derived as well:
///
-/// A*k + B <= UB
+/// A*k + B <=s UB
///
/// which leads to:
///
-/// k <= (UB - B) / A
+/// k <=s (UB - B) / A
///
/// Again, as k is an integer, it means k is less than or equal to the
/// floor((UB - B) / A).
@@ -1585,12 +1585,14 @@ ceilingOfQuotient(const OverflowSafeSignedAPInt &OA,
/// The similar logic applies when A is negative, but the inequalities sign flip
/// while working with them.
///
-/// Preconditions: \p A is non-zero, and we know A*k + B is non-negative.
+/// Preconditions: \p A is non-zero, and we know A*k + B and \p UB are
+/// non-negative.
static std::pair<OverflowSafeSignedAPInt, OverflowSafeSignedAPInt>
inferDomainOfAffine(OverflowSafeSignedAPInt A, OverflowSafeSignedAPInt B,
OverflowSafeSignedAPInt UB) {
assert(A && B && "A and B must be available");
assert(*A != 0 && "A must be non-zero");
+ assert((!UB || UB->isNonNegative()) && "UB must be non-negative");
OverflowSafeSignedAPInt TL, TU;
if (A->sgt(0)) {
TL = ceilingOfQuotient(-B, A);
@@ -1681,8 +1683,11 @@ bool DependenceInfo::exactSIVtest(const SCEVAddRecExpr *Src,
// UM is perhaps unavailable, let's check
if (const SCEVConstant *CUB =
collectConstantUpperBound(Src->getLoop(), Delta->getType())) {
- UM = CUB->getAPInt();
- LLVM_DEBUG(dbgs() << "\t UM = " << *UM << "\n");
+ APInt Tmp = CUB->getAPInt();
+ if (Tmp.isNonNegative()) {
+ UM = CUB->getAPInt();
+ LLVM_DEBUG(dbgs() << "\t UM = " << *UM << "\n");
+ }
}
APInt TU(APInt::getSignedMaxValue(Bits));
@@ -2060,16 +2065,22 @@ bool DependenceInfo::exactRDIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
// SrcUM is perhaps unavailable, let's check
if (const SCEVConstant *UpperBound =
collectConstantUpperBound(SrcLoop, Delta->getType())) {
- SrcUM = UpperBound->getAPInt();
- LLVM_DEBUG(dbgs() << "\t SrcUM = " << *SrcUM << "\n");
+ APInt Tmp = UpperBound->getAPInt();
+ if (Tmp.isNonNegative()) {
+ SrcUM = UpperBound->getAPInt();
+ LLVM_DEBUG(dbgs() << "\t SrcUM = " << *SrcUM << "\n");
+ }
}
std::optional<APInt> DstUM;
- // UM is perhaps unavailable, let's check
+ // DstUM is perhaps unavailable, let's check
if (const SCEVConstant *UpperBound =
collectConstantUpperBound(DstLoop, Delta->getType())) {
- DstUM = UpperBound->getAPInt();
- LLVM_DEBUG(dbgs() << "\t DstUM = " << *DstUM << "\n");
+ APInt Tmp = UpperBound->getAPInt();
+ if (Tmp.isNonNegative()) {
+ DstUM = UpperBound->getAPInt();
+ LLVM_DEBUG(dbgs() << "\t DstUM = " << *DstUM << "\n");
+ }
}
APInt TU(APInt::getSignedMaxValue(Bits));
diff --git a/llvm/test/Analysis/DependenceAnalysis/rdiv-large-btc.ll b/llvm/test/Analysis/DependenceAnalysis/rdiv-large-btc.ll
index 575b22028e40a..56ab9c08a9336 100644
--- a/llvm/test/Analysis/DependenceAnalysis/rdiv-large-btc.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/rdiv-large-btc.ll
@@ -23,7 +23,7 @@ define void @rdiv_large_btc(ptr %A) {
; CHECK-ALL-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.0, align 1
; CHECK-ALL-NEXT: da analyze - none!
; CHECK-ALL-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.1, align 1
-; CHECK-ALL-NEXT: da analyze - none!
+; CHECK-ALL-NEXT: da analyze - output [|<]!
; CHECK-ALL-NEXT: Src: store i8 0, ptr %gep.1, align 1 --> Dst: store i8 0, ptr %gep.1, align 1
; CHECK-ALL-NEXT: da analyze - none!
;
@@ -31,7 +31,7 @@ define void @rdiv_large_btc(ptr %A) {
; CHECK-EXACT-RDIV-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.0, align 1
; CHECK-EXACT-RDIV-NEXT: da analyze - output [*]!
; CHECK-EXACT-RDIV-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.1, align 1
-; CHECK-EXACT-RDIV-NEXT: da analyze - none!
+; CHECK-EXACT-RDIV-NEXT: da analyze - output [|<]!
; CHECK-EXACT-RDIV-NEXT: Src: store i8 0, ptr %gep.1, align 1 --> Dst: store i8 0, ptr %gep.1, align 1
; CHECK-EXACT-RDIV-NEXT: da analyze - output [*]!
;
``````````
</details>
https://github.com/llvm/llvm-project/pull/187218
More information about the llvm-branch-commits
mailing list