diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 2dfe625eb0dcc..dd309bc2c54a8 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -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(RHS) || + (isa(RHS) && + isa(cast(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: 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 ;