diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index c258837d030cb4..0de9ba7a4b8f39 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -1091,8 +1091,7 @@ class ScalarEvolution { /// invariants, available at L's entry. Otherwise, return None. Optional getLoopInvariantPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, - const SCEV *RHS, const Loop *L, - const Instruction *CtxI = nullptr); + const SCEV *RHS, const Loop *L); /// If the result of the predicate LHS `Pred` RHS is loop invariant with /// respect to L at given Context during at least first MaxIter iterations, diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index c09437afae4b2b..5bd110942597e1 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -10756,8 +10756,8 @@ ScalarEvolution::getMonotonicPredicateTypeImpl(const SCEVAddRecExpr *LHS, Optional ScalarEvolution::getLoopInvariantPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, - const Loop *L, - const Instruction *CtxI) { + const Loop *L) { + // If there is a loop-invariant, force it into the RHS, otherwise bail out. if (!isLoopInvariant(RHS, L)) { if (!isLoopInvariant(LHS, L)) @@ -10794,43 +10794,10 @@ ScalarEvolution::getLoopInvariantPredicate(ICmpInst::Predicate Pred, bool Increasing = *MonotonicType == ScalarEvolution::MonotonicallyIncreasing; auto P = Increasing ? Pred : ICmpInst::getInversePredicate(Pred); - if (isLoopBackedgeGuardedByCond(L, P, LHS, RHS)) - return ScalarEvolution::LoopInvariantPredicate(Pred, ArLHS->getStart(), - RHS); - - if (!CtxI) + if (!isLoopBackedgeGuardedByCond(L, P, LHS, RHS)) return None; - // Try to prove via context. - // TODO: Support other cases. - switch (Pred) { - default: - break; - case ICmpInst::ICMP_ULE: - case ICmpInst::ICMP_ULT: { - assert(ArLHS->hasNoUnsignedWrap() && "Is a requirement of monotonicity!"); - // Given preconditions - // (1) ArLHS does not cross 0 (due to NoUnsignedWrap) - // (2) ArLHS =s 0 - // we can replace the loop variant ArLHS ArLHS Start(ArLHS) >=s 0. - // We can strengthen this to Start(ArLHS) getStart(), - RHS); - } - } - return None; + return ScalarEvolution::LoopInvariantPredicate(Pred, ArLHS->getStart(), RHS); } Optional diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp index 08c48b02e591d6..0a856eec3e12a8 100644 --- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -213,8 +213,7 @@ bool SimplifyIndvar::makeIVComparisonInvariant(ICmpInst *ICmp, auto *PN = dyn_cast(IVOperand); if (!PN) return false; - - auto LIP = SE->getLoopInvariantPredicate(Pred, S, X, L, ICmp); + auto LIP = SE->getLoopInvariantPredicate(Pred, S, X, L); if (!LIP) return false; ICmpInst::Predicate InvariantPredicate = LIP->Pred; diff --git a/llvm/test/Transforms/IndVarSimplify/cycled_phis.ll b/llvm/test/Transforms/IndVarSimplify/cycled_phis.ll index 809ec68d483f86..419844d0591949 100644 --- a/llvm/test/Transforms/IndVarSimplify/cycled_phis.ll +++ b/llvm/test/Transforms/IndVarSimplify/cycled_phis.ll @@ -320,8 +320,6 @@ done: ; Slightly more complex version of previous one (cycled phis). ; TODO: remove unsigned comparison by proving non-negativity of iv.start. -; TODO: When we check against IV_START, for some reason we then cannot infer nuw for IV.next. -; It was possible while checking against IV. Missing inference logic somewhere. define i32 @start.from.sibling.iv.wide.cycled.phis(i32* %len.ptr, i32* %sibling.len.ptr) { ; CHECK-LABEL: @start.from.sibling.iv.wide.cycled.phis( ; CHECK-NEXT: entry: @@ -351,10 +349,10 @@ define i32 @start.from.sibling.iv.wide.cycled.phis(i32* %len.ptr, i32* %sibling. ; CHECK-NEXT: [[SIGNED_CMP:%.*]] = icmp slt i32 [[IV]], [[LEN]] ; CHECK-NEXT: br i1 [[SIGNED_CMP]], label [[SIGNED_PASSED:%.*]], label [[FAILED_SIGNED:%.*]] ; CHECK: signed.passed: -; CHECK-NEXT: [[UNSIGNED_CMP:%.*]] = icmp ult i32 [[IV_START]], [[LEN]] +; CHECK-NEXT: [[UNSIGNED_CMP:%.*]] = icmp ult i32 [[IV]], [[LEN]] ; CHECK-NEXT: br i1 [[UNSIGNED_CMP]], label [[BACKEDGE]], label [[FAILED_UNSIGNED:%.*]] ; CHECK: backedge: -; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1 +; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 ; CHECK-NEXT: [[COND:%.*]] = call i1 @cond() ; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[OUTER_LOOP_BACKEDGE]] ; CHECK: outer.loop.backedge: @@ -469,10 +467,10 @@ define i32 @start.from.sibling.iv.wide.cycled.phis.complex.phis(i32* %len.ptr, i ; CHECK-NEXT: [[SIGNED_CMP:%.*]] = icmp slt i32 [[IV]], [[LEN]] ; CHECK-NEXT: br i1 [[SIGNED_CMP]], label [[SIGNED_PASSED:%.*]], label [[FAILED_SIGNED:%.*]] ; CHECK: signed.passed: -; CHECK-NEXT: [[UNSIGNED_CMP:%.*]] = icmp ult i32 [[IV_START]], [[LEN]] +; CHECK-NEXT: [[UNSIGNED_CMP:%.*]] = icmp ult i32 [[IV]], [[LEN]] ; CHECK-NEXT: br i1 [[UNSIGNED_CMP]], label [[BACKEDGE]], label [[FAILED_UNSIGNED:%.*]] ; CHECK: backedge: -; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1 +; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 ; CHECK-NEXT: [[COND:%.*]] = call i1 @cond() ; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[OUTER_LOOP_SELECTION:%.*]] ; CHECK: outer.loop.selection: diff --git a/llvm/test/Transforms/IndVarSimplify/outer_phi.ll b/llvm/test/Transforms/IndVarSimplify/outer_phi.ll index 19ea0a839056c8..8da1648f64e5d3 100644 --- a/llvm/test/Transforms/IndVarSimplify/outer_phi.ll +++ b/llvm/test/Transforms/IndVarSimplify/outer_phi.ll @@ -412,7 +412,7 @@ define i32 @test_05(i32 %a, i32* %bp) { ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] ; CHECK: inner.1: -; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]] +; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]] ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] ; CHECK: inner.backedge: ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 @@ -974,7 +974,7 @@ define i32 @test_06(i32 %a, i32* %bp) { ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] ; CHECK: inner.1: -; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]] +; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]] ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] ; CHECK: inner.backedge: ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 @@ -1045,7 +1045,7 @@ define i32 @test_07(i32 %a, i32* %bp) { ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] ; CHECK: inner.1: -; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]] +; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]] ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] ; CHECK: inner.backedge: ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 @@ -1128,7 +1128,7 @@ define i32 @test_08(i32 %a, i32* %bp) { ; CHECK-NEXT: [[SIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]] ; CHECK-NEXT: br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]] ; CHECK: inner.1: -; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[B]] +; CHECK-NEXT: [[UNSIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]] ; CHECK-NEXT: br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]] ; CHECK: inner.backedge: ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1