[llvm-branch-commits] [llvm] [DA] Fix the Weak Zero SIV tests when Delta is a signed minimum. (PR #184999)
Ryotaro Kasuga via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Mar 6 05:30:31 PST 2026
https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/184999
>From fe5607a76e296c4f47b04f2a320d388c373f1d76 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Fri, 6 Mar 2026 12:07:15 +0000
Subject: [PATCH] [DA] Fix the Weak Zero SIV tests when Delta is a signed
minimum.
---
llvm/lib/Analysis/DependenceAnalysis.cpp | 44 +++++++++----------
.../DependenceAnalysis/WeakZeroDstSIV.ll | 2 +-
.../DependenceAnalysis/WeakZeroSrcSIV.ll | 2 +-
.../weak-zero-siv-delta-signed-min.ll | 12 ++---
4 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 56177f11cc870..c1670760f612f 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -1153,6 +1153,22 @@ static const SCEV *minusSCEVNoSignedOverflow(const SCEV *A, const SCEV *B,
return nullptr;
}
+/// Returns the absolute value of \p A. In the context of dependence analysis,
+/// we need an absolute value in a mathematical sense. If \p A is the signed
+/// minimum value, we cannot represent it unless extending the original type.
+/// In that case, nullptr is returned to indicate the failure.
+static const SCEV *absSCEVNoSignedOverflow(const SCEV *A, ScalarEvolution &SE) {
+ IntegerType *Ty = cast<IntegerType>(A->getType());
+ if (!Ty)
+ return nullptr;
+
+ const SCEV *SMin =
+ SE.getConstant(APInt::getSignedMinValue(Ty->getBitWidth()));
+ if (!SE.isKnownPredicate(CmpInst::ICMP_NE, A, SMin))
+ return nullptr;
+ return SE.getAbsExpr(A, /*IsNSW=*/true);
+}
+
/// Returns true iff \p Test is enabled.
static bool isDependenceTestEnabled(DependenceTestType Test) {
if (EnableDependenceTest == DependenceTestType::All)
@@ -1849,8 +1865,9 @@ bool DependenceInfo::weakZeroSrcSIVtest(const SCEV *DstCoeff,
const SCEV *AbsCoeff = SE->isKnownNegative(ConstCoeff)
? SE->getNegativeSCEV(ConstCoeff)
: ConstCoeff;
- const SCEV *NewDelta =
- SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
+ const SCEV *NewDelta = absSCEVNoSignedOverflow(Delta, *SE);
+ if (!NewDelta)
+ return false;
// check that Delta/SrcCoeff < iteration count
// really check NewDelta < count*AbsCoeff
@@ -1873,15 +1890,6 @@ bool DependenceInfo::weakZeroSrcSIVtest(const SCEV *DstCoeff,
}
}
- // check that Delta/SrcCoeff >= 0
- // really check that NewDelta >= 0
- if (SE->isKnownNegative(NewDelta)) {
- // No dependence, newDelta < 0
- ++WeakZeroSIVindependence;
- ++WeakZeroSIVsuccesses;
- return true;
- }
-
// if SrcCoeff doesn't divide Delta, then no dependence
if (isa<SCEVConstant>(Delta) &&
!isRemainderZero(cast<SCEVConstant>(Delta), ConstCoeff)) {
@@ -1961,8 +1969,9 @@ bool DependenceInfo::weakZeroDstSIVtest(const SCEV *SrcCoeff,
const SCEV *AbsCoeff = SE->isKnownNegative(ConstCoeff)
? SE->getNegativeSCEV(ConstCoeff)
: ConstCoeff;
- const SCEV *NewDelta =
- SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
+ const SCEV *NewDelta = absSCEVNoSignedOverflow(Delta, *SE);
+ if (!NewDelta)
+ return false;
// check that Delta/SrcCoeff < iteration count
// really check NewDelta < count*AbsCoeff
@@ -1985,15 +1994,6 @@ bool DependenceInfo::weakZeroDstSIVtest(const SCEV *SrcCoeff,
}
}
- // check that Delta/SrcCoeff >= 0
- // really check that NewDelta >= 0
- if (SE->isKnownNegative(NewDelta)) {
- // No dependence, newDelta < 0
- ++WeakZeroSIVindependence;
- ++WeakZeroSIVsuccesses;
- return true;
- }
-
// if SrcCoeff doesn't divide Delta, then no dependence
if (isa<SCEVConstant>(Delta) &&
!isRemainderZero(cast<SCEVConstant>(Delta), ConstCoeff)) {
diff --git a/llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll b/llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll
index 90d002b5aad5e..e9e0660f7cbc9 100644
--- a/llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll
@@ -270,7 +270,7 @@ define void @weakzerodst5(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - flow [*|<]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll b/llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll
index 5a1cc2325afd0..1969413db5227 100644
--- a/llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll
@@ -268,7 +268,7 @@ define void @weakzerosrc5(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - output [S]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - flow [*|<]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/weak-zero-siv-delta-signed-min.ll b/llvm/test/Analysis/DependenceAnalysis/weak-zero-siv-delta-signed-min.ll
index 90c3477234043..01d4f218a18ec 100644
--- a/llvm/test/Analysis/DependenceAnalysis/weak-zero-siv-delta-signed-min.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/weak-zero-siv-delta-signed-min.ll
@@ -11,14 +11,14 @@
; A[-i + (1 << 62)] = 1;
; }
;
-; FIXME: There is a dependency between the two stores in all directions.
+; There is a dependency between the two stores in all directions.
;
define void @weak_zero_src_siv_large_btc(ptr %A) {
; CHECK-ALL-LABEL: 'weak_zero_src_siv_large_btc'
; 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 - output [S]!
; CHECK-ALL-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
-; CHECK-ALL-NEXT: da analyze - none!
+; CHECK-ALL-NEXT: da analyze - output [*|<]!
; CHECK-ALL-NEXT: Src: store i8 1, ptr %gep.1, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
; CHECK-ALL-NEXT: da analyze - none!
;
@@ -26,7 +26,7 @@ define void @weak_zero_src_siv_large_btc(ptr %A) {
; CHECK-WEAK-ZERO-SRC-SIV-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.0, align 1
; CHECK-WEAK-ZERO-SRC-SIV-NEXT: da analyze - output [S]!
; CHECK-WEAK-ZERO-SRC-SIV-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
-; CHECK-WEAK-ZERO-SRC-SIV-NEXT: da analyze - none!
+; CHECK-WEAK-ZERO-SRC-SIV-NEXT: da analyze - output [*|<]!
; CHECK-WEAK-ZERO-SRC-SIV-NEXT: Src: store i8 1, ptr %gep.1, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
; CHECK-WEAK-ZERO-SRC-SIV-NEXT: da analyze - output [*]!
;
@@ -63,14 +63,14 @@ exit:
; A[-(1 << 62)] = 1;
; }
;
-; FIXME: There is a dependency between the two stores in all directions.
+; There is a dependency between the two stores in all directions.
;
define void @weak_zero_dst_siv_large_btc(ptr %A) {
; CHECK-ALL-LABEL: 'weak_zero_dst_siv_large_btc'
; 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 1, ptr %gep.1, align 1
-; CHECK-ALL-NEXT: da analyze - none!
+; CHECK-ALL-NEXT: da analyze - output [*|<]!
; CHECK-ALL-NEXT: Src: store i8 1, ptr %gep.1, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
; CHECK-ALL-NEXT: da analyze - output [S]!
;
@@ -78,7 +78,7 @@ define void @weak_zero_dst_siv_large_btc(ptr %A) {
; CHECK-WEAK-ZERO-SRC-SIV-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.0, align 1
; CHECK-WEAK-ZERO-SRC-SIV-NEXT: da analyze - output [*]!
; CHECK-WEAK-ZERO-SRC-SIV-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
-; CHECK-WEAK-ZERO-SRC-SIV-NEXT: da analyze - none!
+; CHECK-WEAK-ZERO-SRC-SIV-NEXT: da analyze - output [*|<]!
; CHECK-WEAK-ZERO-SRC-SIV-NEXT: Src: store i8 1, ptr %gep.1, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
; CHECK-WEAK-ZERO-SRC-SIV-NEXT: da analyze - output [S]!
;
More information about the llvm-branch-commits
mailing list