[llvm] c3e7f98 - [DA] Fix overflow of calculation in weakCrossingSIVtest (#188450)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 30 01:45:49 PDT 2026
Author: Ruoyu Qiu
Date: 2026-03-30T08:45:44Z
New Revision: c3e7f98997508dc5177743401a7c97c0088a0555
URL: https://github.com/llvm/llvm-project/commit/c3e7f98997508dc5177743401a7c97c0088a0555
DIFF: https://github.com/llvm/llvm-project/commit/c3e7f98997508dc5177743401a7c97c0088a0555.diff
LOG: [DA] Fix overflow of calculation in weakCrossingSIVtest (#188450)
This patch fixes a correctness issue where integer overflow in the
upper bound calculation of weakCrossingSIVtest caused the pass to
incorrectly prove independence.
The previous logic used `SCEV::getMulExpr` to calculate
`2 * ConstCoeff * UpperBound` and compared it to `Delta` using
`isKnownPredicate`. In the presence of overflow, this could yield
unsafe results.
This change replaces the SCEV arithmetic with `ConstantRange` to
work around calculation overflows, ensures we conservatively assume
a dependence if the bounds cannot be proven safe.
---------
Signed-off-by: Ruoyu Qiu <cabbaken at outlook.com>
Added:
Modified:
llvm/lib/Analysis/DependenceAnalysis.cpp
llvm/test/Analysis/DependenceAnalysis/weak-crossing-siv-overflow.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 22dfc8ba8622c..de08de7da5f06 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -1424,28 +1424,21 @@ bool DependenceInfo::weakCrossingSIVtest(const SCEVAddRecExpr *Src,
return true;
}
- // We're certain that Delta > 0 and ConstCoeff > 0.
- // Check Delta/(2*ConstCoeff) against upper loop bound
- const Loop *CurSrcLoop = Src->getLoop();
- if (const SCEV *UpperBound =
- collectUpperBound(CurSrcLoop, Delta->getType())) {
- LLVM_DEBUG(dbgs() << "\t UpperBound = " << *UpperBound << "\n");
- const SCEV *ConstantTwo = SE->getConstant(UpperBound->getType(), 2);
- const SCEV *ML =
- SE->getMulExpr(SE->getMulExpr(ConstCoeff, UpperBound), ConstantTwo);
- LLVM_DEBUG(dbgs() << "\t ML = " << *ML << "\n");
- if (SE->isKnownPredicate(CmpInst::ICMP_EQ, Delta, ML)) {
- // i = i' = UB
- Result.DV[Level].Direction &= ~Dependence::DVEntry::LT;
- Result.DV[Level].Direction &= ~Dependence::DVEntry::GT;
- ++WeakCrossingSIVsuccesses;
- if (!Result.DV[Level].Direction) {
- ++WeakCrossingSIVindependence;
- return true;
- }
- Result.DV[Level].Distance = SE->getZero(Delta->getType());
- return false;
+ ConstantRange SrcRange = SE->getSignedRange(Src);
+ ConstantRange DstRange = SE->getSignedRange(Dst);
+ LLVM_DEBUG(dbgs() << "\t SrcRange = " << SrcRange << "\n");
+ LLVM_DEBUG(dbgs() << "\t DstRange = " << DstRange << "\n");
+ if (SrcRange.intersectWith(DstRange).isSingleElement()) {
+ // The ranges touch at exactly one value (i = i' = BTC).
+ Result.DV[Level].Direction &= ~Dependence::DVEntry::LT;
+ Result.DV[Level].Direction &= ~Dependence::DVEntry::GT;
+ ++WeakCrossingSIVsuccesses;
+ if (!Result.DV[Level].Direction) {
+ ++WeakCrossingSIVindependence;
+ return true;
}
+ Result.DV[Level].Distance = SE->getZero(Delta->getType());
+ return false;
}
// check that Coeff divides Delta
diff --git a/llvm/test/Analysis/DependenceAnalysis/weak-crossing-siv-overflow.ll b/llvm/test/Analysis/DependenceAnalysis/weak-crossing-siv-overflow.ll
index 82e5f0a37bc3f..de96239c27bbd 100644
--- a/llvm/test/Analysis/DependenceAnalysis/weak-crossing-siv-overflow.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/weak-crossing-siv-overflow.ll
@@ -80,9 +80,6 @@ exit:
; A[-3*i + INT64_MAX] | | A[INT64_MAX - 3] | A[1] |
; A[3*i + 1] | A[1] | | | A[INT64_MAX - 3]
;
-; The root cause is that the product of the BTC, the coefficient, and 2
-; triggers an overflow.
-;
define void @weakcorssing_prod_ovfl(ptr %A) {
; CHECK-ALL-LABEL: 'weakcorssing_prod_ovfl'
; CHECK-ALL-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1
@@ -117,6 +114,62 @@ loop:
%ec = icmp sgt i64 %i.inc, 3074457345618258602
br i1 %ec, label %exit, label %loop
+exit:
+ ret void
+}
+
+; max_i = 1ULL << 62 // 4611686018427387904
+; for (long long i = 0; i <= max_i; i++) {
+; A[i - ((1ULL << 62) - 1)] = 0;
+; A[-i + (1ULL << 62)] = 1;
+; }
+;
+; There is a dependence between `A[i - ((1ULL << 62) - 1)]`
+; and `A[-i + (1ULL << 62)]`, for example,
+;
+; memory access | i == 0 | i == 1 | i == max_i - 1 | i == max_i
+; ----------------------------|-------------------------|-------------------------|----------------|------------------
+; A[i - ((1ULL << 62) - 1)] | A[-4611686018427387903] | A[-4611686018427387902] | A[0] | A[1]
+; A[-i + (1ULL << 62)] | A[4611686018427387904] | A[4611686018427387903] | A[1] | A[0]
+;
+define void @test_weakcrossing_siv_overflow(ptr %A) {
+; CHECK-ALL-LABEL: 'test_weakcrossing_siv_overflow'
+; CHECK-ALL-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1
+; CHECK-ALL-NEXT: da analyze - none!
+; CHECK-ALL-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
+; CHECK-ALL-NEXT: da analyze - output [<>]!
+; CHECK-ALL-NEXT: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
+; CHECK-ALL-NEXT: da analyze - none!
+;
+; CHECK-WEAK-CROSSING-SIV-LABEL: 'test_weakcrossing_siv_overflow'
+; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1
+; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - output [*]!
+; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
+; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - output [<>]!
+; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
+; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - output [*]!
+;
+entry:
+ br label %loop
+
+loop:
+ %i = phi i64 [ 0, %entry ], [ %i.inc, %loop ]
+ %subscript.0 = phi i64 [ -4611686018427387903, %entry ], [ %subscript.0.next, %loop ]
+ %subscript.1 = phi i64 [ 4611686018427387904, %entry ], [ %subscript.1.next, %loop ]
+
+ %idx.0 = getelementptr inbounds i8, ptr %A, i64 %subscript.0
+ store i8 0, ptr %idx.0
+
+ %idx.1 = getelementptr inbounds i8, ptr %A, i64 %subscript.1
+ store i8 1, ptr %idx.1
+
+ %i.inc = add nuw nsw i64 %i, 1
+ %subscript.0.next = add nsw i64 %subscript.0, 1
+ %subscript.1.next = add nsw i64 %subscript.1, -1
+
+ %ec = icmp sgt i64 %i.inc, 4611686018427387904
+ br i1 %ec, label %exit, label %loop
+
exit:
ret void
}
More information about the llvm-commits
mailing list