-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[ConstraintElim] Teach checkAndReplaceCondition about samesign #128168
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-transforms Author: Marina Taylor (citymarina) ChangesFull diff: https://github.com/llvm/llvm-project/pull/128168.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 6dd26910f6846..9a1a3f3dfeabc 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1427,7 +1427,7 @@ static std::optional<bool> checkCondition(CmpInst::Predicate Pred, Value *A,
}
static bool checkAndReplaceCondition(
- CmpInst *Cmp, ConstraintInfo &Info, unsigned NumIn, unsigned NumOut,
+ ICmpInst *Cmp, ConstraintInfo &Info, unsigned NumIn, unsigned NumOut,
Instruction *ContextInst, Module *ReproducerModule,
ArrayRef<ReproducerEntry> ReproducerCondStack, DominatorTree &DT,
SmallVectorImpl<Instruction *> &ToRemove) {
@@ -1460,6 +1460,13 @@ static bool checkAndReplaceCondition(
checkCondition(Cmp->getPredicate(), Cmp->getOperand(0),
Cmp->getOperand(1), Cmp, Info))
return ReplaceCmpWithConstant(Cmp, *ImpliedCondition);
+
+ if (Cmp->hasSameSign())
+ if (auto ImpliedCondition = checkCondition(
+ ICmpInst::getFlippedSignednessPredicate(Cmp->getPredicate()),
+ Cmp->getOperand(0), Cmp->getOperand(1), Cmp, Info))
+ return ReplaceCmpWithConstant(Cmp, *ImpliedCondition);
+
return false;
}
diff --git a/llvm/test/Transforms/ConstraintElimination/transfer-samesign-facts.ll b/llvm/test/Transforms/ConstraintElimination/transfer-samesign-facts.ll
index 1b155e050de29..09cbbf1c661c7 100644
--- a/llvm/test/Transforms/ConstraintElimination/transfer-samesign-facts.ll
+++ b/llvm/test/Transforms/ConstraintElimination/transfer-samesign-facts.ll
@@ -303,3 +303,23 @@ define i1 @ugt_assumed_positive_values(i8 %a, i8 %b) {
ret i1 %result
}
+
+define i1 @samesign_flipped_signedness(i8 %a) {
+; CHECK-LABEL: @samesign_flipped_signedness(
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[A:%.*]], 0
+; CHECK-NEXT: br i1 [[TMP1]], label [[GREATER:%.*]], label [[EXIT:%.*]]
+; CHECK: greater:
+; CHECK-NEXT: ret i1 true
+; CHECK: exit:
+; CHECK-NEXT: ret i1 false
+;
+ %1 = icmp ugt i8 %a, 0
+ br i1 %1, label %greater, label %exit
+
+greater:
+ %2 = icmp samesign sgt i8 %a, 0
+ ret i1 %2
+
+exit:
+ ret i1 false
+}
|
95b8c00
to
b4a5228
Compare
I implemented the same feature last year :) 33c92a0 Compile-time impact: https://llvm-compile-time-tracker.com/compare.php?from=d1a7225076218ce224cd29c74259b715b393dc9d&to=33c92a07b3a831778592b60962cced91d0b07275&stat=instructions:u |
IR diff looks OK. |
llvm/test/Transforms/ConstraintElimination/transfer-samesign-facts.ll
Outdated
Show resolved
Hide resolved
llvm/test/Transforms/ConstraintElimination/transfer-samesign-facts.ll
Outdated
Show resolved
Hide resolved
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.
Looks reasonable, but I think the test coverage is lacking: how about a dominating samesign condition as well?
llvm/test/Transforms/ConstraintElimination/transfer-samesign-facts.ll
Outdated
Show resolved
Hide resolved
b4a5228
to
1264d23
Compare
Does the added test from #120089 (comment) cover the scenario that you were looking for? If not, could you sketch out for me what you had in mind? |
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.
Almost there.
llvm/test/Transforms/ConstraintElimination/transfer-samesign-facts.ll
Outdated
Show resolved
Hide resolved
%cmp_ult = icmp samesign ult i32 %a, 65 | ||
br i1 %cmp_ult, label %for.cond.preheader, label %if.else | ||
|
||
for.cond.preheader: | ||
ret i1 false | ||
|
||
if.else: | ||
%cmp_ugt = icmp samesign ugt i32 %a, -65 | ||
ret i1 %cmp_ugt |
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.
Note: -65 is interpreted as INT_MAX - 64
unsigned, and this wouldn't have been simplified to false
before samesign support. However, the samesign on ult is redundant. Typically, we want two tests: one of the icmps should have samesign, and the other shouldn't.
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.
Putting together the recent comments:
- Exactly one of the icmps should have samesign
- samesign only goes with unsigned
- Want a dominating samesign test
that lead me to write:
define i1 @implied_condition_ugt_sgt(i8 %a, i8 %b) {
%cmp_ugt = icmp samesign ugt i8 %a, %b
br i1 %cmp_ugt, label %greater, label %exit
greater:
%cmp_sgt = icmp sgt i8 %a, %b
ret i1 %cmp_sgt
exit:
ret i1 false
}
but in this code, greater:
is already optimized to ret i1 true
even without this patch. Have I misunderstood some part?
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.
Sorry, my bad! There are already tests for this. If you could just write one test with %a and %b and another with %a and a constant, that would be good.
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.
Does the latest update capture what you had in mind?
llvm/test/Transforms/ConstraintElimination/transfer-samesign-facts.ll
Outdated
Show resolved
Hide resolved
Could you also re-title this PR "[ConstraintElim] Teach checkAndReplaceCondition about samesign", as there are already other patches that teach other parts of ConstraintElim about samesign, and we want to disambiguate. |
1264d23
to
8f3d2de
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, thanks!
br i1 %cmp_sle, label %less_or_equal, label %exit | ||
|
||
less_or_equal: | ||
%cmp_ule = icmp samesign ule i8 %a, 42 |
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.
could you also add a test with samesign
that cannot be simplified to also guard the negative case?
And maybe a variant with samesign
on the signed known condition to also cover the case where we have samesign but a single predicate?
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.
And maybe a variant with samesign on the signed known condition
Based on comments above, I thought samesign
mustn't go on signed predicates?
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.
Unless I misunderstood something, @fhahn: samesign
is always canonicalized with unsigned predicates, and we generally avoid writing tests with samesign
and signed predicates.
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.
Yep, AFAIK you can have samesign
with signed predicates in general, it looks like ConstraintElimination already handles those case (https://llvm.godbolt.org/z/fhs3r5M56), so this may already be covered by tests
8f3d2de
to
dbe26da
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, thanks!
When landing, could you add a brief description to the commit message, perhaps including a link to an alive2 proof for the motivating example?
Thanks, I've updated the description. If this is good to go, I could use some help to land as I don't yet have write access (I'll probably have enough commits to request it after this). |
Thank you! |
samesign upred
is equivalent tospred
: https://alive2.llvm.org/ce/z/57iaEC