-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SCEV] Better preserve wrapping info in SimplifyICmpOperands for UGE. #144404
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: Florian Hahn (fhahn) ChangesUpdate SimplifyICmpOperands to only try subtracting 1 from RHS first, if RHS is an op we can fold the subtract directly into. Otherwise try adding to LHS first, as we can preserve NUW flags. This improves results in a few cases, including the modified test case from berkeley-abc and new code to be added in Note that there are more cases where the results can be improved by better ordering here which I'll try to investigate as follow-up. Full diff: https://github.com/llvm/llvm-project/pull/144404.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 2dfe625eb0dcc..ea7c7ece5632f 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -10892,7 +10892,11 @@ bool ScalarEvolution::SimplifyICmpOperands(CmpPredicate &Pred, const SCEV *&LHS,
}
break;
case ICmpInst::ICMP_UGE:
- if (!getUnsignedRangeMin(RHS).isMinValue()) {
+ // If RHS is an op we can fold the -1, try that first.
+ if ((isa<SCEVConstant>(RHS) ||
+ match(RHS,
+ m_scev_AffineAddRec(m_SCEVConstant(), m_SCEV(), m_Loop()))) &&
+ !getUnsignedRangeMin(RHS).isMinValue()) {
RHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), RHS);
Pred = ICmpInst::ICMP_UGT;
Changed = true;
@@ -10901,6 +10905,10 @@ bool ScalarEvolution::SimplifyICmpOperands(CmpPredicate &Pred, const SCEV *&LHS,
SCEV::FlagNUW);
Pred = ICmpInst::ICMP_UGT;
Changed = true;
+ } else if (!getUnsignedRangeMin(RHS).isMinValue()) {
+ RHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), RHS);
+ Pred = ICmpInst::ICMP_UGT;
+ Changed = true;
}
break;
default:
diff --git a/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll b/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll
index b0dbbd5eaedf4..fb2fdb116f904 100644
--- a/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll
+++ b/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll
@@ -53,15 +53,12 @@ loop.latch:
define void @test_simplifycompare_rhs_not_constant1() {
; CHECK-LABEL: define void @test_simplifycompare_rhs_not_constant1() {
-; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[P:%.*]] = alloca i64, align 8
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
-; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[P]], %[[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP]] ]
-; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr i8, ptr [[PTR_IV]], i64 -8
-; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
-; CHECK-NEXT: [[EC:%.*]] = icmp ult ptr [[PTR_IV_NEXT]], [[P]]
-; CHECK-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP]]
+; CHECK-NEXT: call void @use(ptr [[P]])
+; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
|
@llvm/pr-subscribers-llvm-analysis Author: Florian Hahn (fhahn) ChangesUpdate SimplifyICmpOperands to only try subtracting 1 from RHS first, if RHS is an op we can fold the subtract directly into. Otherwise try adding to LHS first, as we can preserve NUW flags. This improves results in a few cases, including the modified test case from berkeley-abc and new code to be added in Note that there are more cases where the results can be improved by better ordering here which I'll try to investigate as follow-up. Full diff: https://github.com/llvm/llvm-project/pull/144404.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 2dfe625eb0dcc..ea7c7ece5632f 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -10892,7 +10892,11 @@ bool ScalarEvolution::SimplifyICmpOperands(CmpPredicate &Pred, const SCEV *&LHS,
}
break;
case ICmpInst::ICMP_UGE:
- if (!getUnsignedRangeMin(RHS).isMinValue()) {
+ // If RHS is an op we can fold the -1, try that first.
+ if ((isa<SCEVConstant>(RHS) ||
+ match(RHS,
+ m_scev_AffineAddRec(m_SCEVConstant(), m_SCEV(), m_Loop()))) &&
+ !getUnsignedRangeMin(RHS).isMinValue()) {
RHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), RHS);
Pred = ICmpInst::ICMP_UGT;
Changed = true;
@@ -10901,6 +10905,10 @@ bool ScalarEvolution::SimplifyICmpOperands(CmpPredicate &Pred, const SCEV *&LHS,
SCEV::FlagNUW);
Pred = ICmpInst::ICMP_UGT;
Changed = true;
+ } else if (!getUnsignedRangeMin(RHS).isMinValue()) {
+ RHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), RHS);
+ Pred = ICmpInst::ICMP_UGT;
+ Changed = true;
}
break;
default:
diff --git a/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll b/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll
index b0dbbd5eaedf4..fb2fdb116f904 100644
--- a/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll
+++ b/llvm/test/Transforms/IndVarSimplify/simplify-icmp-operands-order.ll
@@ -53,15 +53,12 @@ loop.latch:
define void @test_simplifycompare_rhs_not_constant1() {
; CHECK-LABEL: define void @test_simplifycompare_rhs_not_constant1() {
-; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[P:%.*]] = alloca i64, align 8
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
-; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[P]], %[[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP]] ]
-; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr i8, ptr [[PTR_IV]], i64 -8
-; CHECK-NEXT: call void @use(ptr [[PTR_IV]])
-; CHECK-NEXT: [[EC:%.*]] = icmp ult ptr [[PTR_IV_NEXT]], [[P]]
-; CHECK-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP]]
+; CHECK-NEXT: call void @use(ptr [[P]])
+; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
|
} else if (!getUnsignedRangeMin(RHS).isMinValue()) { | ||
RHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), RHS); | ||
Pred = ICmpInst::ICMP_UGT; | ||
Changed = true; |
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 unconditionally swapping the cases cause regressions?
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, we would loose flags in test_simplifycompare_rhs_constant
and test_simplifycompare_rhs_addrec
, but gain some in test_simplifycompare_rhs_not_constant2
The current version doesn't have any regression on a large test-set of C/C++ workloads.
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.
llvm-opt-benchmark results are available here: https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2452/files
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
// If RHS is an op we can fold the -1, try that first. | ||
if ((isa<SCEVConstant>(RHS) || | ||
match(RHS, | ||
m_scev_AffineAddRec(m_SCEVConstant(), m_SCEV(), m_Loop()))) && |
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.
This doesn't need an affine addrec, and we could also handle add with constant first operand.
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.
Added to check for SCEVAddExpr/SCEVAddRecExpr and check their first operand. Didn't cause any changes on my test set.
@@ -10892,7 +10892,11 @@ bool ScalarEvolution::SimplifyICmpOperands(CmpPredicate &Pred, const SCEV *&LHS, | |||
} | |||
break; | |||
case ICmpInst::ICMP_UGE: | |||
if (!getUnsignedRangeMin(RHS).isMinValue()) { | |||
// If RHS is an op we can fold the -1, try that first. |
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.
// If RHS is an op we can fold the -1, try that first. | |
// If RHS is an op we can fold the -1, try that first. | |
// Otherwise prefer LHS to preserve the nuw flag. |
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.
Added thanks
@@ -10901,6 +10905,10 @@ bool ScalarEvolution::SimplifyICmpOperands(CmpPredicate &Pred, const SCEV *&LHS, | |||
SCEV::FlagNUW); | |||
Pred = ICmpInst::ICMP_UGT; | |||
Changed = true; | |||
} else if (!getUnsignedRangeMin(RHS).isMinValue()) { |
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 really don't like the code structure here, but I don't have a good suggestion on improving it either...
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.
Same here, but I also didn't find anything better :(
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.
@nikic Not sure if this could be an acceptable alternative: https://gist.github.com/antoniofrighetto/83c188d5ad0a4988eec8d4c30684dafe. It started relatively well, it didn't really end up as good as originally envisioned (NFCI, as RHS is checked first for UGE, might not want this as we probably should preserve the flag).
Update SimplifyICmpOperands to only try subtracting 1 from RHS first, if RHS is an op we can fold the subtract directly into. Otherwise try adding to LHS first, as we can preserve NUW flags. This improves results in a few cases, including the modified test case from berkeley-abc and new code to be added in llvm#128061. Note that there are more cases where the results can be improved by better ordering here which I'll try to investigate as follow-up.
cfcc8f3
to
3baa310
Compare
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/123/builds/21504 Here is the relevant piece of the build log for the reference
|
…ds for UGE. (#144404) Update SimplifyICmpOperands to only try subtracting 1 from RHS first, if RHS is an op we can fold the subtract directly into. Otherwise try adding to LHS first, as we can preserve NUW flags. This improves results in a few cases, including the modified test case from berkeley-abc and new code to be added in llvm/llvm-project#128061. Note that there are more cases where the results can be improved by better ordering here which I'll try to investigate as follow-up. PR: llvm/llvm-project#144404
…llvm#144404) Update SimplifyICmpOperands to only try subtracting 1 from RHS first, if RHS is an op we can fold the subtract directly into. Otherwise try adding to LHS first, as we can preserve NUW flags. This improves results in a few cases, including the modified test case from berkeley-abc and new code to be added in llvm#128061. Note that there are more cases where the results can be improved by better ordering here which I'll try to investigate as follow-up. PR: llvm#144404
…llvm#144404) Update SimplifyICmpOperands to only try subtracting 1 from RHS first, if RHS is an op we can fold the subtract directly into. Otherwise try adding to LHS first, as we can preserve NUW flags. This improves results in a few cases, including the modified test case from berkeley-abc and new code to be added in llvm#128061. Note that there are more cases where the results can be improved by better ordering here which I'll try to investigate as follow-up. PR: llvm#144404
Update SimplifyICmpOperands to only try subtracting 1 from RHS first, if RHS is an op we can fold the subtract directly into. Otherwise try adding to LHS first, as we can preserve NUW flags.
This improves results in a few cases, including the modified test case from berkeley-abc and new code to be added in
#128061.
Note that there are more cases where the results can be improved by better ordering here which I'll try to investigate as follow-up.