-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[DA] Add overflow check in ExactSIV #157086
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-llvm-analysis Author: Ryotaro Kasuga (kasuga-fj) ChangesThis 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 As shown above, the This change is necessary for #157086, since Full diff: https://github.com/llvm/llvm-project/pull/157086.diff 2 Files Affected:
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!
;
|
There was a problem hiding this 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?
| @@ -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. | |||
There was a problem hiding this comment.
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...
5aec6d1 to
9d8c452
Compare
7678c02 to
94b1849
Compare
9d8c452 to
8377460
Compare
94b1849 to
06b81a6
Compare
8377460 to
059708d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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.
059708d to
6a3a5fc
Compare
06b81a6 to
a34c320
Compare
| ;; There exists dependency between `A[-6*i + INT64_MAX]` and `A[3*i - 2]`. | ||
| ;; For example, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unintended change?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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!
This reverts commit a4f0f1f.
a34c320 to
146b38e
Compare

This patch adds an overflow check to the
exactSIVtestfunction 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.