[llvm] r251050 - [SCEV] Teach SCEV some axioms about non-wrapping arithmetic
Richard Trieu via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 5 15:24:14 PST 2015
This has been reverted in r252231 to fix a miscompile. See bug:
https://llvm.org/bugs/show_bug.cgi?id=25421
On Thu, Oct 22, 2015 at 12:57 PM, Sanjoy Das via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: sanjoy
> Date: Thu Oct 22 14:57:29 2015
> New Revision: 251050
>
> URL: http://llvm.org/viewvc/llvm-project?rev=251050&view=rev
> Log:
> [SCEV] Teach SCEV some axioms about non-wrapping arithmetic
>
> Summary:
> - A s< (A + C)<nsw> if C > 0
> - A s<= (A + C)<nsw> if C >= 0
> - (A + C)<nsw> s< A if C < 0
> - (A + C)<nsw> s<= A if C <= 0
>
> Right now `C` needs to be a constant, but we can later generalize it to
> be a non-constant if needed.
>
> Reviewers: atrick, hfinkel, reames, nlewycky
>
> Subscribers: sanjoy, llvm-commits
>
> Differential Revision: http://reviews.llvm.org/D13686
>
> Modified:
> llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
> llvm/trunk/lib/Analysis/ScalarEvolution.cpp
> 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=251050&r1=251049&r2=251050&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
> +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Thu Oct 22 14:57:29
> 2015
> @@ -576,6 +576,14 @@ namespace llvm {
> bool isKnownPredicateWithRanges(ICmpInst::Predicate Pred,
> const SCEV *LHS, const SCEV *RHS);
>
> + /// Try to prove the condition described by "LHS Pred RHS" by ruling
> out
> + /// integer overflow.
> + ///
> + /// For instance, this will return true for "A s< (A + C)<nsw>" if C
> is
> + /// positive.
> + bool isKnownPredicateViaNoOverflow(ICmpInst::Predicate Pred,
> + const SCEV *LHS, const SCEV *RHS);
> +
> /// Try to split Pred LHS RHS into logical conjunctions (and's) and
> try to
> /// prove them individually.
> bool isKnownPredicateViaSplitting(ICmpInst::Predicate Pred, const
> SCEV *LHS,
>
> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=251050&r1=251049&r2=251050&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Thu Oct 22 14:57:29 2015
> @@ -7162,6 +7162,60 @@ ScalarEvolution::isKnownPredicateWithRan
> return false;
> }
>
> +bool ScalarEvolution::isKnownPredicateViaNoOverflow(ICmpInst::Predicate
> Pred,
> + const SCEV *LHS,
> + const SCEV *RHS) {
> +
> + // Match Result to (X + Y)<ExpectedFlags> where Y is a constant integer.
> + // Return Y via OutY.
> + auto MatchBinaryAddToConst =
> + [this](const SCEV *Result, const SCEV *X, APInt &OutY,
> + SCEV::NoWrapFlags ExpectedFlags) {
> + const SCEV *NonConstOp, *ConstOp;
> + SCEV::NoWrapFlags FlagsPresent;
> +
> + if (!splitBinaryAdd(Result, ConstOp, NonConstOp, FlagsPresent) ||
> + !isa<SCEVConstant>(ConstOp) || NonConstOp != X)
> + return false;
> +
> + OutY = cast<SCEVConstant>(ConstOp)->getValue()->getValue();
> + return (FlagsPresent & ExpectedFlags) != 0;
> + };
> +
> + APInt C;
> +
> + switch (Pred) {
> + default:
> + break;
> +
> + case ICmpInst::ICMP_SGE:
> + std::swap(LHS, RHS);
> + case ICmpInst::ICMP_SLE:
> + // X s<= (X + C)<nsw> if C >= 0
> + if (MatchBinaryAddToConst(RHS, LHS, C, SCEV::FlagNSW) &&
> C.isNonNegative())
> + return true;
> +
> + // (X + C)<nsw> s<= X if C <= 0
> + if (MatchBinaryAddToConst(LHS, RHS, C, SCEV::FlagNSW) &&
> + !C.isStrictlyPositive())
> + return true;
> +
> + case ICmpInst::ICMP_SGT:
> + std::swap(LHS, RHS);
> + case ICmpInst::ICMP_SLT:
> + // X s< (X + C)<nsw> if C > 0
> + if (MatchBinaryAddToConst(RHS, LHS, C, SCEV::FlagNSW) &&
> + C.isStrictlyPositive())
> + return true;
> +
> + // (X + C)<nsw> s< X if C < 0
> + if (MatchBinaryAddToConst(LHS, RHS, C, SCEV::FlagNSW) &&
> C.isNegative())
> + return true;
> + }
> +
> + return false;
> +}
> +
> bool ScalarEvolution::isKnownPredicateViaSplitting(ICmpInst::Predicate
> Pred,
> const SCEV *LHS,
> const SCEV *RHS) {
> @@ -7811,8 +7865,9 @@ ScalarEvolution::isImpliedCondOperandsHe
> auto IsKnownPredicateFull =
> [this](ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS) {
> return isKnownPredicateWithRanges(Pred, LHS, RHS) ||
> - IsKnownPredicateViaMinOrMax(*this, Pred, LHS, RHS) ||
> - IsKnownPredicateViaAddRecStart(*this, Pred, LHS, RHS);
> + IsKnownPredicateViaMinOrMax(*this, Pred, LHS, RHS) ||
> + IsKnownPredicateViaAddRecStart(*this, Pred, LHS, RHS) ||
> + isKnownPredicateViaNoOverflow(Pred, LHS, RHS);
> };
>
> switch (Pred) {
>
> 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=251050&r1=251049&r2=251050&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/Transforms/IndVarSimplify/eliminate-comparison.ll
> (original)
> +++ llvm/trunk/test/Transforms/IndVarSimplify/eliminate-comparison.ll Thu
> Oct 22 14:57:29 2015
> @@ -477,4 +477,63 @@ define void @func_21(i32* %length.ptr, i
> ret void
> }
>
> +define void @func_22(i32* %length.ptr) {
> +; CHECK-LABEL: @func_22(
> +
> +; This checks that the backedge condition, (I + 1) < Length - 1 implies
> +; (I + 1) < Length
> + entry:
> + %length = load i32, i32* %length.ptr, !range !0
> + %lim = sub i32 %length, 1
> + %entry.cond = icmp sgt i32 %length, 1
> + br i1 %entry.cond, label %loop, label %leave
> +
> + loop:
> +; CHECK: loop:
> + %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
> + %iv.inc = add i32 %iv, 1
> + %range.check = icmp slt i32 %iv, %length
> + br i1 %range.check, label %be, label %leave
> +; CHECK: br i1 true, label %be, label %leave.loopexit
> +; CHECK: be:
> +
> + be:
> + call void @side_effect()
> + %be.cond = icmp slt i32 %iv.inc, %lim
> + br i1 %be.cond, label %loop, label %leave
> +
> + leave:
> + ret void
> +}
> +
> +define void @func_23(i32* %length.ptr) {
> +; CHECK-LABEL: @func_23(
> +
> +; This checks that the backedge condition, (I + 1) < Length - 1 implies
> +; (I + 1) < Length
> + entry:
> + %length = load i32, i32* %length.ptr, !range !0
> + %lim = sub i32 %length, 1
> + %entry.cond = icmp sgt i32 %length, 1
> + br i1 %entry.cond, label %loop, label %leave
> +
> + loop:
> +; CHECK: loop:
> + %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
> + %iv.inc = add i32 %iv, 1
> + %range.check = icmp sle i32 %iv, %length
> + br i1 %range.check, label %be, label %leave
> +; CHECK: br i1 true, label %be, label %leave.loopexit
> +; CHECK: be:
> +
> + be:
> + call void @side_effect()
> + %be.cond = icmp sle i32 %iv.inc, %lim
> + br i1 %be.cond, label %loop, label %leave
> +
> + leave:
> + ret void
> +}
> +
> +
> !0 = !{i32 0, i32 2147483647}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151105/51eb7f66/attachment.html>
More information about the llvm-commits
mailing list