[llvm] r248614 - Revert two SCEV changes that caused test failures in clang.
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 14:16:50 PDT 2015
Author: sanjoy
Date: Fri Sep 25 16:16:50 2015
New Revision: 248614
URL: http://llvm.org/viewvc/llvm-project?rev=248614&view=rev
Log:
Revert two SCEV changes that caused test failures in clang.
r248606: "[SCEV] Exploit A < B => (A+K) < (B+K) when possible"
r248608: "[SCEV] Teach isLoopBackedgeGuardedByCond to exploit trip counts."
Modified:
llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
llvm/trunk/lib/Analysis/ScalarEvolution.cpp
llvm/trunk/test/Analysis/ScalarEvolution/zext-wrap.ll
llvm/trunk/test/Transforms/IndVarSimplify/eliminate-comparison.ll
Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=248614&r1=248613&r2=248614&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Fri Sep 25 16:16:50 2015
@@ -536,17 +536,6 @@ namespace llvm {
const SCEV *FoundLHS,
const SCEV *FoundRHS);
- /// Test whether the condition described by Pred, LHS, and RHS is true
- /// whenever the condition described by Pred, FoundLHS, and FoundRHS is
- /// true.
- ///
- /// This routine tries to rule out certain kinds of integer overflow, and
- /// then tries to reason about arithmetic properties of the predicates.
- bool isImpliedCondOperandsViaNoOverflow(ICmpInst::Predicate Pred,
- const SCEV *LHS, const SCEV *RHS,
- const SCEV *FoundLHS,
- const SCEV *FoundRHS);
-
/// If we know that the specified Phi is in the header of its containing
/// loop, we know the loop executes a constant number of times, and the PHI
/// node is just a recurrence involving constants, fold it.
Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=248614&r1=248613&r2=248614&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri Sep 25 16:16:50 2015
@@ -6994,22 +6994,6 @@ ScalarEvolution::isLoopBackedgeGuardedBy
SaveAndRestore<bool> ClearOnExit(WalkingBEDominatingConds, true);
- // See if we can exploit a trip count to prove the predicate.
- const auto &BETakenInfo = getBackedgeTakenInfo(L);
- const SCEV *LatchBECount = BETakenInfo.getExact(Latch, this);
- if (LatchBECount != getCouldNotCompute()) {
- // We know that Latch branches back to the loop header exactly
- // LatchBECount times. This means the backdege condition at Latch is
- // equivalent to "{0,+,1} u< LatchBECount".
- Type *Ty = LatchBECount->getType();
- auto NoWrapFlags = SCEV::NoWrapFlags(SCEV::FlagNUW | SCEV::FlagNW);
- const SCEV *LoopCounter =
- getAddRecExpr(getZero(Ty), getOne(Ty), L, NoWrapFlags);
- if (isImpliedCond(Pred, LHS, RHS, ICmpInst::ICMP_ULT, LoopCounter,
- LatchBECount))
- return true;
- }
-
// Check conditions due to any @llvm.assume intrinsics.
for (auto &AssumeVH : AC.assumptions()) {
if (!AssumeVH)
@@ -7304,146 +7288,6 @@ bool ScalarEvolution::isImpliedCond(ICmp
return false;
}
-// Return true if More == (Less + C), where C is a constant.
-static bool IsConstDiff(ScalarEvolution &SE, const SCEV *Less, const SCEV *More,
- APInt &C) {
- // We avoid subtracting expressions here because this function is usually
- // fairly deep in the call stack (i.e. is called many times).
-
- auto SplitBinaryAdd = [](const SCEV *Expr, const SCEV *&L, const SCEV *&R) {
- const auto *AE = dyn_cast<SCEVAddExpr>(Expr);
- if (!AE || AE->getNumOperands() != 2)
- return false;
-
- L = AE->getOperand(0);
- R = AE->getOperand(1);
- return true;
- };
-
- if (isa<SCEVAddRecExpr>(Less) && isa<SCEVAddRecExpr>(More)) {
- const auto *LAR = cast<SCEVAddRecExpr>(Less);
- const auto *MAR = cast<SCEVAddRecExpr>(More);
-
- if (LAR->getLoop() != MAR->getLoop())
- return false;
-
- // We look at affine expressions only; not for correctness but to keep
- // getStepRecurrence cheap.
- if (!LAR->isAffine() || !MAR->isAffine())
- return false;
-
- if (LAR->getStepRecurrence(SE) != MAR->getStepRecurrence(SE))
- return false;
-
- Less = LAR->getStart();
- More = MAR->getStart();
-
- // fall through
- }
-
- if (isa<SCEVConstant>(Less) && isa<SCEVConstant>(More)) {
- const auto &M = cast<SCEVConstant>(More)->getValue()->getValue();
- const auto &L = cast<SCEVConstant>(Less)->getValue()->getValue();
- C = M - L;
- return true;
- }
-
- const SCEV *L, *R;
- if (SplitBinaryAdd(Less, L, R))
- if (const auto *LC = dyn_cast<SCEVConstant>(L))
- if (R == More) {
- C = -(LC->getValue()->getValue());
- return true;
- }
-
- if (SplitBinaryAdd(More, L, R))
- if (const auto *LC = dyn_cast<SCEVConstant>(L))
- if (R == Less) {
- C = LC->getValue()->getValue();
- return true;
- }
-
- return false;
-}
-
-bool ScalarEvolution::isImpliedCondOperandsViaNoOverflow(
- ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
- const SCEV *FoundLHS, const SCEV *FoundRHS) {
- if (Pred != CmpInst::ICMP_SLT && Pred != CmpInst::ICMP_ULT)
- return false;
-
- const auto *AddRecLHS = dyn_cast<SCEVAddRecExpr>(LHS);
- if (!AddRecLHS)
- return false;
-
- const auto *AddRecFoundLHS = dyn_cast<SCEVAddRecExpr>(FoundLHS);
- if (!AddRecFoundLHS)
- return false;
-
- // We'd like to let SCEV reason about control dependencies, so we constrain
- // both the inequalities to be about add recurrences on the same loop. This
- // way we can use isLoopEntryGuardedByCond later.
-
- const Loop *L = AddRecFoundLHS->getLoop();
- if (L != AddRecLHS->getLoop())
- return false;
-
- // FoundLHS u< FoundRHS u< -C => (FoundLHS + C) u< (FoundRHS + C) ... (1)
- //
- // FoundLHS s< FoundRHS s< INT_MIN - C => (FoundLHS + C) s< (FoundRHS + C)
- // ... (2)
- //
- // Informal proof for (2), assuming (1) [*]:
- //
- // We'll also assume (A s< B) <=> ((A + INT_MIN) u< (B + INT_MIN)) ... (3)[**]
- //
- // Then
- //
- // FoundLHS s< FoundRHS s< INT_MIN - C
- // <=> (FoundLHS + INT_MIN) u< (FoundRHS + INT_MIN) u< -C [ using (3) ]
- // <=> (FoundLHS + INT_MIN + C) u< (FoundRHS + INT_MIN + C) [ using (1) ]
- // <=> (FoundLHS + INT_MIN + C + INT_MIN) s<
- // (FoundRHS + INT_MIN + C + INT_MIN) [ using (3) ]
- // <=> FoundLHS + C s< FoundRHS + C
- //
- // [*]: (1) can be proved by ruling out overflow.
- //
- // [**]: This can be proved by analyzing all the four possibilities:
- // (A s< 0, B s< 0), (A s< 0, B s>= 0), (A s>= 0, B s< 0) and
- // (A s>= 0, B s>= 0).
- //
- // Note:
- // Despite (2), "FoundRHS s< INT_MIN - C" does not mean that "FoundRHS + C"
- // will not sign underflow. For instance, say FoundLHS = (i8 -128), FoundRHS
- // = (i8 -127) and C = (i8 -100). Then INT_MIN - C = (i8 -28), and FoundRHS
- // s< (INT_MIN - C). Lack of sign overflow / underflow in "FoundRHS + C" is
- // neither necessary nor sufficient to prove "(FoundLHS + C) s< (FoundRHS +
- // C)".
-
- APInt LDiff, RDiff;
- if (!IsConstDiff(*this, FoundLHS, LHS, LDiff) ||
- !IsConstDiff(*this, FoundRHS, RHS, RDiff) ||
- LDiff != RDiff)
- return false;
-
- if (LDiff == 0)
- return true;
-
- unsigned Width = cast<IntegerType>(RHS->getType())->getBitWidth();
- APInt FoundRHSLimit;
-
- if (Pred == CmpInst::ICMP_ULT) {
- FoundRHSLimit = -RDiff;
- } else {
- assert(Pred == CmpInst::ICMP_SLT && "Checked above!");
- FoundRHSLimit = APInt::getSignedMinValue(Width) - RDiff;
- }
-
- // Try to prove (1) or (2), as needed.
- return isLoopEntryGuardedByCond(L, Pred, FoundRHS,
- getConstant(FoundRHSLimit));
-}
-
/// isImpliedCondOperands - Test whether the condition described by Pred,
/// LHS, and RHS is true whenever the condition described by Pred, FoundLHS,
/// and FoundRHS is true.
@@ -7454,9 +7298,6 @@ bool ScalarEvolution::isImpliedCondOpera
if (isImpliedCondOperandsViaRanges(Pred, LHS, RHS, FoundLHS, FoundRHS))
return true;
- if (isImpliedCondOperandsViaNoOverflow(Pred, LHS, RHS, FoundLHS, FoundRHS))
- return true;
-
return isImpliedCondOperandsHelper(Pred, LHS, RHS,
FoundLHS, FoundRHS) ||
// ~x < ~y --> x > y
Modified: llvm/trunk/test/Analysis/ScalarEvolution/zext-wrap.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/zext-wrap.ll?rev=248614&r1=248613&r2=248614&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/zext-wrap.ll (original)
+++ llvm/trunk/test/Analysis/ScalarEvolution/zext-wrap.ll Fri Sep 25 16:16:50 2015
@@ -10,7 +10,7 @@ bb.i: ; preds = %bb1.i, %bb.np
; This cast shouldn't be folded into the addrec.
; CHECK: %tmp = zext i8 %l_95.0.i1 to i16
-; CHECK: --> (zext i8 {0,+,-1}<nw><%bb.i> to i16){{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: 2
+; CHECK: --> (zext i8 {0,+,-1}<%bb.i> to i16){{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: 2
%tmp = zext i8 %l_95.0.i1 to i16
Modified: llvm/trunk/test/Transforms/IndVarSimplify/eliminate-comparison.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/eliminate-comparison.ll?rev=248614&r1=248613&r2=248614&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/eliminate-comparison.ll (original)
+++ llvm/trunk/test/Transforms/IndVarSimplify/eliminate-comparison.ll Fri Sep 25 16:16:50 2015
@@ -209,189 +209,3 @@ assert77:
unrolledend: ; preds = %forcond38
ret i32 0
}
-
-declare void @side_effect()
-
-define void @func_13(i32* %len.ptr) {
-; CHECK-LABEL: @func_13(
- entry:
- %len = load i32, i32* %len.ptr, !range !0
- %len.sub.1 = add i32 %len, -1
- %len.is.zero = icmp eq i32 %len, 0
- br i1 %len.is.zero, label %leave, label %loop
-
- loop:
-; CHECK: loop:
- %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
- call void @side_effect()
- %iv.inc = add i32 %iv, 1
- %iv.cmp = icmp ult i32 %iv, %len
- br i1 %iv.cmp, label %be, label %leave
-; CHECK: br i1 true, label %be, label %leave
-
- be:
- call void @side_effect()
- %be.cond = icmp ult i32 %iv, %len.sub.1
- br i1 %be.cond, label %loop, label %leave
-
- leave:
- ret void
-}
-
-define void @func_14(i32* %len.ptr) {
-; CHECK-LABEL: @func_14(
- entry:
- %len = load i32, i32* %len.ptr, !range !0
- %len.sub.1 = add i32 %len, -1
- %len.is.zero = icmp eq i32 %len, 0
- %len.is.int_min = icmp eq i32 %len, 2147483648
- %no.entry = or i1 %len.is.zero, %len.is.int_min
- br i1 %no.entry, label %leave, label %loop
-
- loop:
-; CHECK: loop:
- %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
- call void @side_effect()
- %iv.inc = add i32 %iv, 1
- %iv.cmp = icmp slt i32 %iv, %len
- br i1 %iv.cmp, label %be, label %leave
-; CHECK: br i1 true, label %be, label %leave
-
- be:
- call void @side_effect()
- %be.cond = icmp slt i32 %iv, %len.sub.1
- br i1 %be.cond, label %loop, label %leave
-
- leave:
- ret void
-}
-
-define void @func_15(i32* %len.ptr) {
-; CHECK-LABEL: @func_15(
- entry:
- %len = load i32, i32* %len.ptr, !range !0
- %len.add.1 = add i32 %len, 1
- %len.add.1.is.zero = icmp eq i32 %len.add.1, 0
- br i1 %len.add.1.is.zero, label %leave, label %loop
-
- loop:
-; CHECK: loop:
- %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
- call void @side_effect()
- %iv.inc = add i32 %iv, 1
- %iv.cmp = icmp ult i32 %iv, %len.add.1
- br i1 %iv.cmp, label %be, label %leave
-; CHECK: br i1 true, label %be, label %leave
-
- be:
- call void @side_effect()
- %be.cond = icmp ult i32 %iv, %len
- br i1 %be.cond, label %loop, label %leave
-
- leave:
- ret void
-}
-
-define void @func_16(i32* %len.ptr) {
-; CHECK-LABEL: @func_16(
- entry:
- %len = load i32, i32* %len.ptr, !range !0
- %len.add.5 = add i32 %len, 5
- %entry.cond.0 = icmp slt i32 %len, 2147483643
- %entry.cond.1 = icmp slt i32 4, %len.add.5
- %entry.cond = and i1 %entry.cond.0, %entry.cond.1
- br i1 %entry.cond, label %loop, label %leave
-
- loop:
-; CHECK: loop:
- %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
- call void @side_effect()
- %iv.inc = add i32 %iv, 1
- %iv.add.4 = add i32 %iv, 4
- %iv.cmp = icmp slt i32 %iv.add.4, %len.add.5
- br i1 %iv.cmp, label %be, label %leave
-; CHECK: br i1 true, label %be, label %leave
-
- be:
- call void @side_effect()
- %be.cond = icmp slt i32 %iv, %len
- br i1 %be.cond, label %loop, label %leave
-
- leave:
- ret void
-}
-
-define void @func_17(i32* %len.ptr) {
-; CHECK-LABEL: @func_17(
- entry:
- %len = load i32, i32* %len.ptr
- %len.add.5 = add i32 %len, -5
- %entry.cond.0 = icmp slt i32 %len, 2147483653 ;; 2147483653 == INT_MIN - (-5)
- %entry.cond.1 = icmp slt i32 -6, %len.add.5
- %entry.cond = and i1 %entry.cond.0, %entry.cond.1
- br i1 %entry.cond, label %loop, label %leave
-
- loop:
-; CHECK: loop:
- %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.inc, %be ]
- %iv = phi i32 [ -6, %entry ], [ %iv.inc, %be ]
- call void @side_effect()
- %iv.inc = add i32 %iv, 1
- %iv.2.inc = add i32 %iv.2, 1
- %iv.cmp = icmp slt i32 %iv, %len.add.5
-
-; Deduces {-5,+,1} s< (-5 + %len) from {0,+,1} < %len
-; since %len s< INT_MIN - (-5) from the entry condition
-
-; CHECK: br i1 true, label %be, label %leave
- br i1 %iv.cmp, label %be, label %leave
-
- be:
-; CHECK: be:
- call void @side_effect()
- %be.cond = icmp slt i32 %iv.2, %len
- br i1 %be.cond, label %loop, label %leave
-
- leave:
- ret void
-}
-
-define i1 @func_18(i16* %tmp20, i32* %len.addr) {
-; CHECK-LABEL: @func_18(
-entry:
- %len = load i32, i32* %len.addr, !range !0
- %tmp18 = icmp eq i32 %len, 0
- br i1 %tmp18, label %bb2, label %bb0.preheader
-
-bb0.preheader:
- br label %bb0
-
-bb0:
-; CHECK: bb0:
- %var_0.in = phi i32 [ %var_0, %bb1 ], [ %len, %bb0.preheader ]
- %var_1 = phi i32 [ %tmp30, %bb1 ], [ 0, %bb0.preheader ]
- %var_0 = add nsw i32 %var_0.in, -1
- %tmp23 = icmp ult i32 %var_1, %len
-; CHECK: br i1 true, label %stay, label %bb2.loopexit
- br i1 %tmp23, label %stay, label %bb2
-
-stay:
-; CHECK: stay:
- %tmp25 = getelementptr inbounds i16, i16* %tmp20, i32 %var_1
- %tmp26 = load i16, i16* %tmp25
- %tmp29 = icmp eq i16 %tmp26, 0
- br i1 %tmp29, label %bb1, label %bb2
-
-bb1:
- %tmp30 = add i32 %var_1, 1
- %tmp31 = icmp eq i32 %var_0, 0
- br i1 %tmp31, label %bb3, label %bb0
-
-bb2:
- ret i1 false
-
-bb3:
- ret i1 true
-}
-
-!0 = !{i32 0, i32 2147483647}
More information about the llvm-commits
mailing list