Skip to content

Conversation

kasuga-fj
Copy link
Contributor

@kasuga-fj kasuga-fj commented Sep 5, 2025

This patch adds an overflow check to the exactSIVtest function to fix the issue demonstrated in the test case added in #157085. This patch only fixes one of the routines. To fully resolve the test case, the other functions need to be addressed as well.

@kasuga-fj kasuga-fj marked this pull request as ready for review September 5, 2025 12:29
@llvmbot llvmbot added the llvm:analysis Includes value tracking, cost tables and constant folding label Sep 5, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 5, 2025

@llvm/pr-subscribers-llvm-analysis

Author: Ryotaro Kasuga (kasuga-fj)

Changes

This patch removes base pointers from subscripts when delinearization fails. Previously, in such cases, the pointer type SCEVs were used instead of offset SCEVs derived from them. For example, here is a portion of the debug output when analyzing strong0 in test/Analysis/DependenceAnalysis/StrongSIV.ll:

testing subscript 0, SIV
    src = {(8 + %A),+,4}<nuw><%for.body>
    dst = {(8 + %A),+,4}<nuw><%for.body>
	Strong SIV test
	    Coeff = 4, i64
	    SrcConst = (8 + %A), ptr
	    DstConst = (8 + %A), ptr
	    Delta = 0, i64
	    UpperBound = (-1 + %n), i64
	    Distance = 0
	    Remainder = 0

As shown above, the SrcConst and DstConst are pointer values rather than integer offsets. %A should be removed.

This change is necessary for #157086, since ScalarEvolution::willNotOverflow expects integer type SCEVs as arguments.


Full diff: https://github.com/llvm/llvm-project/pull/157086.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/DependenceAnalysis.cpp (+13-1)
  • (modified) llvm/test/Analysis/DependenceAnalysis/ExactSIV.ll (+1-1)
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 0f77a1410e83b..6e576e866b310 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -1170,6 +1170,15 @@ const SCEVConstant *DependenceInfo::collectConstantUpperBound(const Loop *L,
   return nullptr;
 }
 
+/// Returns \p A - \p B if it guaranteed not to signed wrap. Otherwise returns
+/// nullptr. \p A and \p B must have the same integer type.
+static const SCEV *minusSCEVNoSignedOverflow(const SCEV *A, const SCEV *B,
+                                             ScalarEvolution &SE) {
+  if (SE.willNotOverflow(Instruction::Sub, /*Signed=*/true, A, B))
+    return SE.getMinusSCEV(A, B);
+  return nullptr;
+}
+
 // testZIV -
 // When we have a pair of subscripts of the form [c1] and [c2],
 // where c1 and c2 are both loop invariant, we attack it using
@@ -1626,7 +1635,9 @@ bool DependenceInfo::exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
   assert(0 < Level && Level <= CommonLevels && "Level out of range");
   Level--;
   Result.Consistent = false;
-  const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
+  const SCEV *Delta = minusSCEVNoSignedOverflow(DstConst, SrcConst, *SE);
+  if (!Delta)
+    return false;
   LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
   NewConstraint.setLine(SrcCoeff, SE->getNegativeSCEV(DstCoeff), Delta,
                         CurLoop);
@@ -1716,6 +1727,7 @@ bool DependenceInfo::exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
   // explore directions
   unsigned NewDirection = Dependence::DVEntry::NONE;
   APInt LowerDistance, UpperDistance;
+  // TODO: Overflow check may be needed.
   if (TA.sgt(TB)) {
     LowerDistance = (TY - TX) + (TA - TB) * TL;
     UpperDistance = (TY - TX) + (TA - TB) * TU;
diff --git a/llvm/test/Analysis/DependenceAnalysis/ExactSIV.ll b/llvm/test/Analysis/DependenceAnalysis/ExactSIV.ll
index 97b58c06303e6..5a8a60a6833ae 100644
--- a/llvm/test/Analysis/DependenceAnalysis/ExactSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/ExactSIV.ll
@@ -834,7 +834,7 @@ define void @exact14(ptr %A) {
 ; CHECK-SIV-ONLY-NEXT:  Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1
 ; CHECK-SIV-ONLY-NEXT:    da analyze - none!
 ; CHECK-SIV-ONLY-NEXT:  Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
-; CHECK-SIV-ONLY-NEXT:    da analyze - none!
+; CHECK-SIV-ONLY-NEXT:    da analyze - output [*|<]!
 ; CHECK-SIV-ONLY-NEXT:  Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
 ; CHECK-SIV-ONLY-NEXT:    da analyze - none!
 ;

@kasuga-fj kasuga-fj marked this pull request as draft September 5, 2025 12:30
Copy link
Contributor Author

@kasuga-fj kasuga-fj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, I've added the minimal necessary checks, but it’s unclear whether similar checks are also needed elsewhere in this function. Apparently, such checks aren't necessary for GCD computation (ref). However, I'm not sure whether they are needed in subsequent steps. It might be safer to include it for now, just in case, until we can prove it's unnecessary?

// explore directions
unsigned NewDirection = Dependence::DVEntry::NONE;
APInt LowerDistance, UpperDistance;
// TODO: Overflow check may be needed.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect this part could cause overflows, but not entirely sure...

@kasuga-fj kasuga-fj marked this pull request as ready for review September 5, 2025 13:31
@kasuga-fj kasuga-fj requested a review from Meinersbur September 5, 2025 13:32
@kasuga-fj kasuga-fj force-pushed the users/kasuga-fj/da-fix-exact-siv-ovfl-2 branch from 5aec6d1 to 9d8c452 Compare September 5, 2025 13:48
@kasuga-fj kasuga-fj force-pushed the users/kasuga-fj/da-fix-exact-siv-ovfl-3 branch 2 times, most recently from 7678c02 to 94b1849 Compare September 12, 2025 10:09
@kasuga-fj kasuga-fj force-pushed the users/kasuga-fj/da-fix-exact-siv-ovfl-2 branch from 9d8c452 to 8377460 Compare September 12, 2025 10:09
@kasuga-fj kasuga-fj force-pushed the users/kasuga-fj/da-fix-exact-siv-ovfl-3 branch from 94b1849 to 06b81a6 Compare September 12, 2025 10:25
@kasuga-fj kasuga-fj force-pushed the users/kasuga-fj/da-fix-exact-siv-ovfl-2 branch from 8377460 to 059708d Compare September 12, 2025 10:25
Copy link
Member

@Meinersbur Meinersbur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

kasuga-fj added a commit that referenced this pull request Sep 16, 2025
This patch removes base pointers from subscripts when delinearization
fails. Previously, in such cases, the pointer type SCEVs were used
instead of offset SCEVs derived from them.
For example, here is a portion of the debug output when analyzing
`strong0` in `test/Analysis/DependenceAnalysis/StrongSIV.ll`:

```
testing subscript 0, SIV
    src = {(8 + %A),+,4}<nuw><%for.body>
    dst = {(8 + %A),+,4}<nuw><%for.body>
	Strong SIV test
	    Coeff = 4, i64
	    SrcConst = (8 + %A), ptr
	    DstConst = (8 + %A), ptr
	    Delta = 0, i64
	    UpperBound = (-1 + %n), i64
	    Distance = 0
	    Remainder = 0
```

As shown above, the `SrcConst` and `DstConst` are pointer values rather
than integer offsets. `%A` should be removed.

This change is necessary for #157086, since
`ScalarEvolution::willNotOverflow` expects integer type SCEVs as
arguments. This change alone alone should not affect the analysis
results.
@kasuga-fj kasuga-fj force-pushed the users/kasuga-fj/da-fix-exact-siv-ovfl-2 branch from 059708d to 6a3a5fc Compare September 16, 2025 13:15
@kasuga-fj kasuga-fj force-pushed the users/kasuga-fj/da-fix-exact-siv-ovfl-3 branch from 06b81a6 to a34c320 Compare September 16, 2025 13:15
Comment on lines 818 to 819
;; There exists dependency between `A[-6*i + INT64_MAX]` and `A[3*i - 2]`.
;; For example,
Copy link
Member

@Meinersbur Meinersbur Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unintended change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is intentional. I think it's non-trivial that the dependency exists between them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to be the same change as in 32203e6, before my request to adjust the comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only meant to remove the FIXME assuming this PR would fix the bug. But after thinking it through, it only addresses part of the issue, and the result is still incorrect. You're right, I've reverted the comment change. Thanks!

Base automatically changed from users/kasuga-fj/da-fix-exact-siv-ovfl-2 to main September 16, 2025 19:17
kimsh02 pushed a commit to kimsh02/llvm-project that referenced this pull request Sep 19, 2025
This patch removes base pointers from subscripts when delinearization
fails. Previously, in such cases, the pointer type SCEVs were used
instead of offset SCEVs derived from them.
For example, here is a portion of the debug output when analyzing
`strong0` in `test/Analysis/DependenceAnalysis/StrongSIV.ll`:

```
testing subscript 0, SIV
    src = {(8 + %A),+,4}<nuw><%for.body>
    dst = {(8 + %A),+,4}<nuw><%for.body>
	Strong SIV test
	    Coeff = 4, i64
	    SrcConst = (8 + %A), ptr
	    DstConst = (8 + %A), ptr
	    Delta = 0, i64
	    UpperBound = (-1 + %n), i64
	    Distance = 0
	    Remainder = 0
```

As shown above, the `SrcConst` and `DstConst` are pointer values rather
than integer offsets. `%A` should be removed.

This change is necessary for llvm#157086, since
`ScalarEvolution::willNotOverflow` expects integer type SCEVs as
arguments. This change alone alone should not affect the analysis
results.
@kasuga-fj kasuga-fj force-pushed the users/kasuga-fj/da-fix-exact-siv-ovfl-3 branch from a34c320 to 146b38e Compare September 19, 2025 08:37
@kasuga-fj kasuga-fj merged commit b6231f5 into main Sep 19, 2025
9 checks passed
@kasuga-fj kasuga-fj deleted the users/kasuga-fj/da-fix-exact-siv-ovfl-3 branch September 19, 2025 11:08
itzexpoexpo pushed a commit to itzexpoexpo/llvm-project that referenced this pull request Sep 21, 2025
This patch removes base pointers from subscripts when delinearization
fails. Previously, in such cases, the pointer type SCEVs were used
instead of offset SCEVs derived from them.
For example, here is a portion of the debug output when analyzing
`strong0` in `test/Analysis/DependenceAnalysis/StrongSIV.ll`:

```
testing subscript 0, SIV
    src = {(8 + %A),+,4}<nuw><%for.body>
    dst = {(8 + %A),+,4}<nuw><%for.body>
	Strong SIV test
	    Coeff = 4, i64
	    SrcConst = (8 + %A), ptr
	    DstConst = (8 + %A), ptr
	    Delta = 0, i64
	    UpperBound = (-1 + %n), i64
	    Distance = 0
	    Remainder = 0
```

As shown above, the `SrcConst` and `DstConst` are pointer values rather
than integer offsets. `%A` should be removed.

This change is necessary for llvm#157086, since
`ScalarEvolution::willNotOverflow` expects integer type SCEVs as
arguments. This change alone alone should not affect the analysis
results.
SeongjaeP pushed a commit to SeongjaeP/llvm-project that referenced this pull request Sep 23, 2025
This patch removes base pointers from subscripts when delinearization
fails. Previously, in such cases, the pointer type SCEVs were used
instead of offset SCEVs derived from them.
For example, here is a portion of the debug output when analyzing
`strong0` in `test/Analysis/DependenceAnalysis/StrongSIV.ll`:

```
testing subscript 0, SIV
    src = {(8 + %A),+,4}<nuw><%for.body>
    dst = {(8 + %A),+,4}<nuw><%for.body>
	Strong SIV test
	    Coeff = 4, i64
	    SrcConst = (8 + %A), ptr
	    DstConst = (8 + %A), ptr
	    Delta = 0, i64
	    UpperBound = (-1 + %n), i64
	    Distance = 0
	    Remainder = 0
```

As shown above, the `SrcConst` and `DstConst` are pointer values rather
than integer offsets. `%A` should be removed.

This change is necessary for llvm#157086, since
`ScalarEvolution::willNotOverflow` expects integer type SCEVs as
arguments. This change alone alone should not affect the analysis
results.
SeongjaeP pushed a commit to SeongjaeP/llvm-project that referenced this pull request Sep 23, 2025
This patch adds an overflow check to the `exactSIVtest` function to fix
the issue demonstrated in the test case added in llvm#157085. This patch
only fixes one of the routines. To fully resolve the test case, the
other functions need to be addressed as well.
YixingZhang007 pushed a commit to YixingZhang007/llvm-project that referenced this pull request Sep 27, 2025
This patch adds an overflow check to the `exactSIVtest` function to fix
the issue demonstrated in the test case added in llvm#157085. This patch
only fixes one of the routines. To fully resolve the test case, the
other functions need to be addressed as well.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:analysis Includes value tracking, cost tables and constant folding
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants