-
Couldn't load subscription status.
- Fork 15k
[DA] Check monotonicity for subscripts #154527
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
base: main
Are you sure you want to change the base?
Changes from 15 commits
a0d05ec
75639b9
5063efc
4dad091
8986cd4
dcb3b19
e93be2e
72b2902
b5ca793
65ccc61
d113571
137c193
f9b2a4e
e83fdb8
a098743
b16cc64
98a5de4
8c4f97b
c563a8f
55df30a
85129c6
e15715e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3308,6 +3308,242 @@ void DependenceInfo::updateDirection(Dependence::DVEntry &Level, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| llvm_unreachable("constraint has unexpected kind"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// The type of signed monotonicity of a SCEV expression. This property is | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// defined with respect to the outermost loop that DA is analyzing. Invariant | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// and MultiMonotonic mutually exclusive, and both imply NoSignedWrap. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// This is designed to classify the behavior of AddRec expressions, and does | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// not care about other SCEVs. For example, given the two loop invariants `A` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// and `B`, `A + B` is treated as Invariant even if the addition may wrap. On | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// the other hand, if either `A` or `B` is an AddRec and we cannot prove the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// addition doesn't wrap, the result is classified as Unknown. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enum class MonotonicityType { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Unknown, ///< The expression contains some non loop-invariant SCEVUnknown or | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ///< arithmetic operation that has some AddRec as its subexpression | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ///< and may cause signed wrap. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NoSignedWrap, ///< The expression doesn't contain any AddRecs that may wrap. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ///< This is a weaker property than Invariant or MultiMonotonic. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ///< Invariant and MultiMonotonic imply NoSignedWrap. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Invariant, ///< The expression is a loop-invariant. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MultiMonotonic, ///< The expression is monotonically increasing or decreasing | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ///< with respect to each loop. This is exclusive of | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ///< Invariant. That is, we say an SCEV is MultiMonotonic only | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ///< if it contains at least one AddRec where its step | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ///< reccurence value is non-zero. Monotonicity is checked | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ///< independently for each loop. It is allowed to contain | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ///< both increasing and decreasing AddRecs. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// A visitor that checks the signed monotonicity of SCEVs. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| struct SCEVSignedMonotonicityChecker | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : public SCEVVisitor<SCEVSignedMonotonicityChecker, MonotonicityType> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// \p Ptr is the pointer that the SCEV is associated with, if any. It may be | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// used for the inferrence. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static MonotonicityType checkMonotonicity(ScalarEvolution *SE, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const SCEV *Expr, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const Loop *OutermostLoop, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const Value *Ptr = nullptr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitAddRecExpr(const SCEVAddRecExpr *Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitUnknown(const SCEVUnknown *Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitSignExtendExpr(const SCEVSignExtendExpr *Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitConstant(const SCEVConstant *) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return MonotonicityType::Invariant; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitVScale(const SCEVVScale *) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return MonotonicityType::Invariant; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // TODO: Handle more cases. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitAddExpr(const SCEVAddExpr *Expr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return checkInvarianceOnly(Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitMulExpr(const SCEVMulExpr *Expr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return checkInvarianceOnly(Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitPtrToIntExpr(const SCEVPtrToIntExpr *Expr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return checkInvarianceOnly(Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitTruncateExpr(const SCEVTruncateExpr *Expr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return checkInvarianceOnly(Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitUDivExpr(const SCEVUDivExpr *Expr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return checkInvarianceOnly(Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitSMaxExpr(const SCEVSMaxExpr *Expr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return checkInvarianceOnly(Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitUMaxExpr(const SCEVUMaxExpr *Expr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return checkInvarianceOnly(Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitSMinExpr(const SCEVSMinExpr *Expr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return checkInvarianceOnly(Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitUMinExpr(const SCEVUMinExpr *Expr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return checkInvarianceOnly(Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitSequentialUMinExpr(const SCEVSequentialUMinExpr *Expr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return checkInvarianceOnly(Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MonotonicityType visitCouldNotCompute(const SCEVCouldNotCompute *Expr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return checkInvarianceOnly(Expr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ScalarEvolution *SE; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const Loop *OutermostLoop; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ; The value of step reccurence is not invariant with respect to the outer most | |
| ; loop (the i-loop). | |
| ; | |
| ; offset_i = 0; | |
| ; for (int i = 0; i < 100; i++) { | |
| ; for (int j = 0; j < 100; j++) | |
| ; a[offset_i + j] = 0; | |
| ; offset_i += (i % 2 == 0) ? 0 : 3; | |
| ; } | |
| ; | |
| define void @step_is_variant(ptr %a) { | |
| ; CHECK-LABEL: 'step_is_variant' | |
| ; CHECK: Failed to prove monotonicity for: %offset.i | |
| ; CHECK: Failed to prove monotonicity for: {%offset.i,+,1}<nuw><nsw><%loop.j> | |
| ; CHECK: Monotonicity: Unknown expr: {%offset.i,+,1}<nuw><nsw><%loop.j> | |
| ; | |
| entry: | |
| br label %loop.i.header | |
| loop.i.header: | |
| %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ] | |
| %offset.i = phi i64 [ 0, %entry ], [ %offset.i.next, %loop.i.latch ] | |
| %step.i.0 = phi i64 [ 0, %entry ], [ %step.i.1, %loop.i.latch ] | |
| %step.i.1 = phi i64 [ 3, %entry ], [ %step.i.0, %loop.i.latch ] | |
| br label %loop.j | |
| loop.j: | |
| %j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j ] | |
| %offset = add nsw i64 %offset.i, %j | |
| %idx = getelementptr inbounds i8, ptr %a, i64 %offset | |
| store i8 0, ptr %idx | |
| %j.inc = add nsw i64 %j, 1 | |
| %exitcond.j = icmp eq i64 %j.inc, 100 | |
| br i1 %exitcond.j, label %loop.i.latch, label %loop.j | |
| loop.i.latch: | |
| %i.inc = add nsw i64 %i, 1 | |
| %offset.i.next = add nsw i64 %offset.i, %step.i.0 | |
| %exitcond.i = icmp eq i64 %i.inc, 100 | |
| br i1 %exitcond.i, label %exit, label %loop.i.header | |
| exit: | |
| ret void | |
| } |
Outdated
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.
Found a more serious issue (ref: #157859). To keep this PR simpler, I now think it is better to ignore the delinearized subscripts at the moment, and check monotonicity only when delinearization fails...
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.
done
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.
Removed support for
SCEVAddExprandSCEVMulExprin e83fdb8. The rationale is as follows:%m * {0,+,%n}<%loop>, I think this reasoning is not valid (but if it is{0,+,(%m * %n)}<%loop>, it seems valid). Additionally, I found leveraging GEP attributes is beneficial -- removing this logic caused some tests to fail, which seems non-trivial at a glance. At least, as a first step, I feel it's reasonable to remove these handlings for add/mul and leave the reasoning to GEP attributes.SCEVAddExprandSCEVMulExpris non-trivial. For example, in the case of{0,+,1}<%loop> + {0,+,-1}<%loop>(apparently, this could happen), it is unclear whether this should be considered Monotonic or Invariant.Removing the support caused some test regressions, but all failures were of the form like
[* *]becomingconfused. I believe the semantic impact of these changes is essentially negligible.