[SCEV] Better preserve wrapping info in SimplifyICmpOperands 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 https://github.com/llvm/llvm-project/pull/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: https://github.com/llvm/llvm-project/pull/144404
This commit is contained in:
@@ -10892,7 +10892,12 @@ 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.
|
||||
// Otherwise prefer LHS to preserve the nuw flag.
|
||||
if ((isa<SCEVConstant>(RHS) ||
|
||||
(isa<SCEVAddExpr, SCEVAddRecExpr>(RHS) &&
|
||||
isa<SCEVConstant>(cast<SCEVNAryExpr>(RHS)->getOperand(0)))) &&
|
||||
!getUnsignedRangeMin(RHS).isMinValue()) {
|
||||
RHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), RHS);
|
||||
Pred = ICmpInst::ICMP_UGT;
|
||||
Changed = true;
|
||||
@@ -10901,6 +10906,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:
|
||||
|
||||
@@ -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
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user