From 69246ca7879d81dc3f07d52f768f7550519fbcb6 Mon Sep 17 00:00:00 2001 From: Serguei Katkov Date: Wed, 7 Feb 2018 09:10:08 +0000 Subject: [PATCH] Revert [SCEV] Make isLoopEntryGuardedByCond a bit smarter Revert rL324453 commit which causes buildbot failures. Differential Revision: https://reviews.llvm.org/D42835 llvm-svn: 324462 --- llvm/include/llvm/IR/InstrTypes.h | 13 --- llvm/lib/Analysis/ScalarEvolution.cpp | 62 ++----------- llvm/lib/IR/Instructions.cpp | 14 --- .../Transforms/IRCE/conjunctive-checks.ll | 6 +- .../test/Transforms/IRCE/decrementing-loop.ll | 86 +------------------ .../IRCE/single-access-no-preloop.ll | 6 +- .../loop-invariant-conditions.ll | 30 ------- 7 files changed, 12 insertions(+), 205 deletions(-) diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index 9e938a462cf2..871f702f95f2 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -973,19 +973,6 @@ public: /// @brief Return the predicate as if the operands were swapped. static Predicate getSwappedPredicate(Predicate pred); - /// For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE. - /// @brief Returns the non-strict version of strict comparisons. - Predicate getNonStrictPredicate() const { - return getNonStrictPredicate(getPredicate()); - } - - /// This is a static version that you can use without an instruction - /// available. - /// @returns the non-strict version of comparison provided in \p pred. - /// If \p pred is not a strict comparison predicate, returns \p pred. - /// @brief Returns the non-strict version of strict comparisons. - static Predicate getNonStrictPredicate(Predicate pred); - /// @brief Provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 8f5e0bc51df2..f44bb8d447ef 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -9073,59 +9073,6 @@ ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L, if (isKnownPredicateViaConstantRanges(Pred, LHS, RHS)) return true; - // If we cannot prove strict comparison (e.g. a > b), maybe we can prove - // the facts (a >= b && a != b) separately. A typical situation is when the - // non-strict comparison is known from ranges and non-equality is known from - // dominating predicates. If we are proving strict comparison, we always try - // to prove non-equality and non-strict comparison separately. - auto NonStrictPredicate = ICmpInst::getNonStrictPredicate(Pred); - const bool ProvingStrictComparison = (Pred != NonStrictPredicate); - bool ProvedNonStrictComparison = false; - bool ProvedNonEquality = false; - - if (ProvingStrictComparison) { - ProvedNonStrictComparison = - isKnownPredicateViaConstantRanges(NonStrictPredicate, LHS, RHS); - ProvedNonEquality = - isKnownPredicateViaConstantRanges(ICmpInst::ICMP_NE, LHS, RHS); - assert((!ProvedNonStrictComparison || !ProvedNonEquality) && - "Why we were unable to prove (Pred, LHS, RHS) via constant ranges?"); - } - - // Try to prove (Pred, LHS, RHS) using isImpliedViaGuard. - auto ProveViaGuard = [&](BasicBlock *Block) { - if (isImpliedViaGuard(Block, Pred, LHS, RHS)) - return true; - if (ProvingStrictComparison) { - if (!ProvedNonStrictComparison) - ProvedNonStrictComparison = - isImpliedViaGuard(Block, NonStrictPredicate, LHS, RHS); - if (!ProvedNonEquality) - ProvedNonEquality = - isImpliedViaGuard(Block, ICmpInst::ICMP_NE, LHS, RHS); - if (ProvedNonStrictComparison && ProvedNonEquality) - return true; - } - return false; - }; - - // Try to prove (Pred, LHS, RHS) using isImpliedCond. - auto ProveViaCond = [&](Value *Condition, bool Inverse) { - if (isImpliedCond(Pred, LHS, RHS, Condition, Inverse)) - return true; - if (ProvingStrictComparison) { - if (!ProvedNonStrictComparison) - ProvedNonStrictComparison = - isImpliedCond(NonStrictPredicate, LHS, RHS, Condition, Inverse); - if (!ProvedNonEquality) - ProvedNonEquality = - isImpliedCond(ICmpInst::ICMP_NE, LHS, RHS, Condition, Inverse); - if (ProvedNonStrictComparison && ProvedNonEquality) - return true; - } - return false; - }; - // Starting at the loop predecessor, climb up the predecessor chain, as long // as there are predecessors that can be found that have unique successors // leading to the original header. @@ -9134,7 +9081,7 @@ ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L, Pair.first; Pair = getPredecessorWithUniqueSuccessorForBB(Pair.first)) { - if (ProveViaGuard(Pair.first)) + if (isImpliedViaGuard(Pair.first, Pred, LHS, RHS)) return true; BranchInst *LoopEntryPredicate = @@ -9143,8 +9090,9 @@ ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L, LoopEntryPredicate->isUnconditional()) continue; - if (ProveViaCond(LoopEntryPredicate->getCondition(), - LoopEntryPredicate->getSuccessor(0) != Pair.second)) + if (isImpliedCond(Pred, LHS, RHS, + LoopEntryPredicate->getCondition(), + LoopEntryPredicate->getSuccessor(0) != Pair.second)) return true; } @@ -9156,7 +9104,7 @@ ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L, if (!DT.dominates(CI, L->getHeader())) continue; - if (ProveViaCond(CI->getArgOperand(0), false)) + if (isImpliedCond(Pred, LHS, RHS, CI->getArgOperand(0), false)) return true; } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 7fa4b06c566a..490fcbce7439 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -3467,20 +3467,6 @@ CmpInst::Predicate CmpInst::getSwappedPredicate(Predicate pred) { } } -CmpInst::Predicate CmpInst::getNonStrictPredicate(Predicate pred) { - switch (pred) { - case ICMP_SGT: return ICMP_SGE; - case ICMP_SLT: return ICMP_SLE; - case ICMP_UGT: return ICMP_UGE; - case ICMP_ULT: return ICMP_ULE; - case FCMP_OGT: return FCMP_OGE; - case FCMP_OLT: return FCMP_OLE; - case FCMP_UGT: return FCMP_UGE; - case FCMP_ULT: return FCMP_ULE; - default: return pred; - } -} - CmpInst::Predicate CmpInst::getSignedPredicate(Predicate pred) { assert(CmpInst::isUnsigned(pred) && "Call only with signed predicates!"); diff --git a/llvm/test/Transforms/IRCE/conjunctive-checks.ll b/llvm/test/Transforms/IRCE/conjunctive-checks.ll index b1a7063523d3..f6a909e432c4 100644 --- a/llvm/test/Transforms/IRCE/conjunctive-checks.ll +++ b/llvm/test/Transforms/IRCE/conjunctive-checks.ll @@ -4,10 +4,10 @@ define void @f_0(i32 *%arr, i32 *%a_len_ptr, i32 %n, i1* %cond_buf) { ; CHECK-LABEL: @f_0( ; CHECK: loop.preheader: -; CHECK: [[not_safe_range_end:[^ ]+]] = sub i32 3, %len ; CHECK: [[not_n:[^ ]+]] = sub i32 -1, %n -; CHECK: [[not_exit_main_loop_at_hiclamp_cmp:[^ ]+]] = icmp sgt i32 [[not_safe_range_end]], [[not_n]] -; CHECK: [[not_exit_main_loop_at_hiclamp:[^ ]+]] = select i1 [[not_exit_main_loop_at_hiclamp_cmp]], i32 [[not_safe_range_end]], i32 [[not_n]] +; CHECK: [[not_safe_range_end:[^ ]+]] = sub i32 3, %len +; CHECK: [[not_exit_main_loop_at_hiclamp_cmp:[^ ]+]] = icmp sgt i32 [[not_n]], [[not_safe_range_end]] +; CHECK: [[not_exit_main_loop_at_hiclamp:[^ ]+]] = select i1 [[not_exit_main_loop_at_hiclamp_cmp]], i32 [[not_n]], i32 [[not_safe_range_end]] ; CHECK: [[exit_main_loop_at_hiclamp:[^ ]+]] = sub i32 -1, [[not_exit_main_loop_at_hiclamp]] ; CHECK: [[exit_main_loop_at_loclamp_cmp:[^ ]+]] = icmp sgt i32 [[exit_main_loop_at_hiclamp]], 0 ; CHECK: [[exit_main_loop_at_loclamp:[^ ]+]] = select i1 [[exit_main_loop_at_loclamp_cmp]], i32 [[exit_main_loop_at_hiclamp]], i32 0 diff --git a/llvm/test/Transforms/IRCE/decrementing-loop.ll b/llvm/test/Transforms/IRCE/decrementing-loop.ll index 395e73c5566c..fac873b4a24f 100644 --- a/llvm/test/Transforms/IRCE/decrementing-loop.ll +++ b/llvm/test/Transforms/IRCE/decrementing-loop.ll @@ -1,8 +1,4 @@ -; RUN: opt -verify-loop-info -irce -debug-only=irce -S < %s 2>&1 | FileCheck %s - -; CHECK-LABEL: irce: in function decrementing_loop: constrained Loop at depth 1 -; CHECK-LABEL: irce: in function test_01: constrained Loop at depth 1 -; CHECK-LABEL: irce: in function test_02: constrained Loop at depth 1 +; RUN: opt -verify-loop-info -irce -S < %s | FileCheck %s define void @decrementing_loop(i32 *%arr, i32 *%a_len_ptr, i32 %n) { entry: @@ -42,85 +38,5 @@ define void @decrementing_loop(i32 *%arr, i32 *%a_len_ptr, i32 %n) { ; CHECK: %exit.preloop.at = add i32 [[not_exit_preloop_at]], -1 } -; Make sure that we can eliminate the range check when the loop looks like: -; for (i = len.a - 1; i >= 0; --i) -; b[i] = a[i]; -define void @test_01(i32* %a, i32* %b, i32* %a_len_ptr, i32* %b_len_ptr) { - -; CHECK-LABEL: test_01 -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK: %rc = and i1 true, true -; CHECK: loop.preloop: - - entry: - %len.a = load i32, i32* %a_len_ptr, !range !0 - %len.b = load i32, i32* %b_len_ptr, !range !0 - %first.itr.check = icmp ne i32 %len.a, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ %len.a, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = sub i32 %idx, 1 - %rca = icmp ult i32 %idx.next, %len.a - %rcb = icmp ult i32 %idx.next, %len.b - %rc = and i1 %rca, %rcb - br i1 %rc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %el.a = getelementptr i32, i32* %a, i32 %idx.next - %el.b = getelementptr i32, i32* %b, i32 %idx.next - %v = load i32, i32* %el.a - store i32 %v, i32* %el.b - %loop.cond = icmp slt i32 %idx, 2 - br i1 %loop.cond, label %exit, label %loop - - out.of.bounds: - ret void - - exit: - ret void -} - -; Same as test_01, but the latch condition is unsigned -define void @test_02(i32* %a, i32* %b, i32* %a_len_ptr, i32* %b_len_ptr) { - -; CHECK-LABEL: test_02 -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK: %rc = and i1 true, true -; CHECK: loop.preloop: - - entry: - %len.a = load i32, i32* %a_len_ptr, !range !0 - %len.b = load i32, i32* %b_len_ptr, !range !0 - %first.itr.check = icmp ne i32 %len.a, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ %len.a, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = sub i32 %idx, 1 - %rca = icmp ult i32 %idx.next, %len.a - %rcb = icmp ult i32 %idx.next, %len.b - %rc = and i1 %rca, %rcb - br i1 %rc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %el.a = getelementptr i32, i32* %a, i32 %idx.next - %el.b = getelementptr i32, i32* %b, i32 %idx.next - %v = load i32, i32* %el.a - store i32 %v, i32* %el.b - %loop.cond = icmp ult i32 %idx, 2 - br i1 %loop.cond, label %exit, label %loop - - out.of.bounds: - ret void - - exit: - ret void -} - !0 = !{i32 0, i32 2147483647} !1 = !{!"branch_weights", i32 64, i32 4} diff --git a/llvm/test/Transforms/IRCE/single-access-no-preloop.ll b/llvm/test/Transforms/IRCE/single-access-no-preloop.ll index c9da4e289505..53f430d0ba3d 100644 --- a/llvm/test/Transforms/IRCE/single-access-no-preloop.ll +++ b/llvm/test/Transforms/IRCE/single-access-no-preloop.ll @@ -85,10 +85,10 @@ define void @single_access_no_preloop_with_offset(i32 *%arr, i32 *%a_len_ptr, i3 ; CHECK-LABEL: @single_access_no_preloop_with_offset( ; CHECK: loop.preheader: -; CHECK: [[not_safe_range_end:[^ ]+]] = sub i32 3, %len ; CHECK: [[not_n:[^ ]+]] = sub i32 -1, %n -; CHECK: [[not_exit_main_loop_at_hiclamp_cmp:[^ ]+]] = icmp sgt i32 [[not_safe_range_end]], [[not_n]] -; CHECK: [[not_exit_main_loop_at_hiclamp:[^ ]+]] = select i1 [[not_exit_main_loop_at_hiclamp_cmp]], i32 [[not_safe_range_end]], i32 [[not_n]] +; CHECK: [[not_safe_range_end:[^ ]+]] = sub i32 3, %len +; CHECK: [[not_exit_main_loop_at_hiclamp_cmp:[^ ]+]] = icmp sgt i32 [[not_n]], [[not_safe_range_end]] +; CHECK: [[not_exit_main_loop_at_hiclamp:[^ ]+]] = select i1 [[not_exit_main_loop_at_hiclamp_cmp]], i32 [[not_n]], i32 [[not_safe_range_end]] ; CHECK: [[exit_main_loop_at_hiclamp:[^ ]+]] = sub i32 -1, [[not_exit_main_loop_at_hiclamp]] ; CHECK: [[exit_main_loop_at_loclamp_cmp:[^ ]+]] = icmp sgt i32 [[exit_main_loop_at_hiclamp]], 0 ; CHECK: [[exit_main_loop_at_loclamp:[^ ]+]] = select i1 [[exit_main_loop_at_loclamp_cmp]], i32 [[exit_main_loop_at_hiclamp]], i32 0 diff --git a/llvm/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll b/llvm/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll index 30249828107f..70cf714ba9f2 100644 --- a/llvm/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll +++ b/llvm/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll @@ -325,36 +325,6 @@ exit: ret void } -; check that we can figure out that iv.next > 1 from the facts that iv >= 0 and -; iv.start != 0. -define void @test11(i64* %inc_ptr) { -; CHECK-LABEL: @test11 -entry: - %inc = load i64, i64* %inc_ptr, !range !0 - %ne.cond = icmp ne i64 %inc, 0 - br i1 %ne.cond, label %loop, label %exit - -loop: - %iv = phi i64 [ %inc, %entry ], [ %iv.next, %backedge ] - %iv.next = add i64 %iv, 1 - %brcond = icmp sgt i64 %iv.next, 1 - ; CHECK: br i1 true, label %if.true, label %if.false - br i1 %brcond, label %if.true, label %if.false - -if.true: - br label %backedge - -if.false: - br label %backedge - -backedge: - %loopcond = icmp slt i64 %iv, 200 - br i1 %loopcond, label %loop, label %exit - -exit: - ret void -} - !1 = !{i64 -1, i64 100}