-
Notifications
You must be signed in to change notification settings - Fork 12k
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
[SCEVExpander] Do not reuse disjoint or #80281
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Nikita Popov (nikic) ChangesSCEV treats "or disjoint" the same as "add nsw nuw". However, when expanding, we cannot generally replace an add SCEV node with an "or disjoint" instruction. Just dropping the poison flag is insufficient in this case, we would have to actually convert the or into an add. This is a partial fix for #79861. Full diff: https://github.com/llvm/llvm-project/pull/80281.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index ed55a13072aaa..eea01825a72b2 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -1370,6 +1370,13 @@ canReuseInstruction(ScalarEvolution &SE, const SCEV *S, Instruction *I,
if (programUndefinedIfPoison(I))
return true;
+ // Disjoint or instructions are interpreted as adds by SCEV. However, we
+ // can't replace an arbitrary add with disjoint or, even if we drop the flag.
+ // We would need to convert the or into an add.
+ if (auto *PDI = dyn_cast<PossiblyDisjointInst>(I))
+ if (PDI->isDisjoint())
+ return false;
+
// Otherwise, it is possible that I is more poisonous that S. Collect the
// poison-contributors of S, and then check whether I has any additional
// poison-contributors. Poison that is contributed through poison-generating
diff --git a/llvm/test/Transforms/IndVarSimplify/pr79861.ll b/llvm/test/Transforms/IndVarSimplify/pr79861.ll
index a8e2aa42a365c..7e267d04c94cc 100644
--- a/llvm/test/Transforms/IndVarSimplify/pr79861.ll
+++ b/llvm/test/Transforms/IndVarSimplify/pr79861.ll
@@ -75,14 +75,15 @@ define void @expander_or_disjoint(i64 %n) {
; CHECK-LABEL: define void @expander_or_disjoint(
; CHECK-SAME: i64 [[N:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[OR:%.*]] = or i64 [[N]], 1
+; CHECK-NEXT: [[OR:%.*]] = or disjoint i64 [[N]], 1
+; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[N]], 1
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_INC]] = add i64 [[IV]], 1
; CHECK-NEXT: [[ADD:%.*]] = add i64 [[IV]], [[OR]]
; CHECK-NEXT: call void @use(i64 [[ADD]])
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_INC]], [[OR]]
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_INC]], [[TMP0]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
|
SCEV treats "or disjoint" the same as "add nsw nuw". However, when expanding, we cannot generally replace an add SCEV node with an "or disjoint" instruction. Just dropping the poison flag is insufficient in this case, we would have to actually convert the or into an add. This is a partial fix for llvm#79861.
95a627e
to
60cb1bd
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
Mostly to make sure I understand this properly, an alternate fix here would be to treat the or as needing it's poison generating flags dropped, and then mutate the or to an add in the same place we're dropping metadata right?
Yes, exactly. |
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, thanks!
SCEV treats "or disjoint" the same as "add nsw nuw". However, when expanding, we cannot generally replace an add SCEV node with an "or disjoint" instruction. Just dropping the poison flag is insufficient in this case, we would have to actually convert the or into an add. This is a partial fix for llvm#79861.
SCEV treats "or disjoint" the same as "add nsw nuw". However, when expanding, we cannot generally replace an add SCEV node with an "or disjoint" instruction. Just dropping the poison flag is insufficient in this case, we would have to actually convert the or into an add. This is a partial fix for llvm#79861. (cherry picked from commit 5b8e1a6)
SCEV treats "or disjoint" the same as "add nsw nuw". However, when expanding, we cannot generally replace an add SCEV node with an "or disjoint" instruction. Just dropping the poison flag is insufficient in this case, we would have to actually convert the or into an add. This is a partial fix for llvm#79861. (cherry picked from commit 5b8e1a6)
SCEV treats "or disjoint" the same as "add nsw nuw". However, when expanding, we cannot generally replace an add SCEV node with an "or disjoint" instruction. Just dropping the poison flag is insufficient in this case, we would have to actually convert the or into an add. This is a partial fix for llvm#79861. (cherry picked from commit 5b8e1a6)
SCEV treats "or disjoint" the same as "add nsw nuw". However, when expanding, we cannot generally replace an add SCEV node with an "or disjoint" instruction. Just dropping the poison flag is insufficient in this case, we would have to actually convert the or into an add.
This is a partial fix for #79861.