[llvm] r248045 - [IndVars] Widen more comparisons for non-negative induction vars
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 19 18:55:44 PDT 2015
I think I've fixed the issue in r248107, but if you still find issues,
please feel free to revert the problematic changes directly.
-- Sanjoy
Manuel Klimek wrote:
> Note that this leads to an opt regression for us, leading to test results like 'expected: -1, actual: -1'. I don't have
> a small repro yet.
>
> On Fri, Sep 18, 2015 at 2:22 PM Sanjoy Das via llvm-commits <llvm-commits at lists.llvm.org
> <mailto:llvm-commits at lists.llvm.org>> wrote:
>
> Author: sanjoy
> Date: Fri Sep 18 16:21:02 2015
> New Revision: 248045
>
> URL: http://llvm.org/viewvc/llvm-project?rev=248045&view=rev
<http://llvm.org/viewvc/llvm-project?rev=248045&view=rev>
> Log:
> [IndVars] Widen more comparisons for non-negative induction vars
>
> Summary:
> If an induction variable is provably non-negative, its sign extension is
> equal to its zero extension. This means narrow uses like
>
> icmp slt iNarrow %indvar, %rhs
>
> can be widened into
>
> icmp slt iWide zext(%indvar), sext(%rhs)
>
> Reviewers: atrick, mcrosier, hfinkel
>
> Subscribers: hfinkel, reames, llvm-commits
>
> Differential Revision: http://reviews.llvm.org/D12745
>
> Modified:
> llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
> llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll
>
> Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
> URL:
>
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=248045&r1=248044&r2=248045&view=diff
>
<http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=248045&r1=248044&r2=248045&view=diff>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Fri Sep 18 16:21:02 2015
> @@ -849,6 +849,11 @@ class WidenIV {
> Type *WideType;
> bool IsSigned;
>
> + // True if the narrow induction variable is never negative. Tracking this
> + // information lets us use a sign extension instead of a zero extension or
> + // vice versa, when profitable and legal.
> + bool NeverNegative;
> +
> // Context
> LoopInfo *LI;
> Loop *L;
> @@ -871,6 +876,7 @@ public:
> OrigPhi(WI.NarrowIV),
> WideType(WI.WidestNativeType),
> IsSigned(WI.IsSigned),
> + NeverNegative(false),
> LI(LInfo),
> L(LI->getLoopFor(OrigPhi->getParent())),
> SE(SEv),
> @@ -1082,8 +1088,22 @@ bool WidenIV::WidenLoopCompare(NarrowIVD
> if (!Cmp)
> return false;
>
> - // Sign of IV user and compare must match.
> - if (IsSigned != CmpInst::isSigned(Cmp->getPredicate()))
> + // We can legally widen the comparison in the following two cases:
> + //
> + // - The signedness of the IV extension and comparison match
> + //
> + // - The narrow IV is always positive (and thus its sign extension is equal
> + // to its zero extension). For instance, let's say we're zero extending
> + // %narrow for the following use
> + //
> + // icmp slt i32 %narrow, %val ... (A)
> + //
> + // and %narrow is always positive. Then
> + //
> + // (A) == icmp slt i32 sext(%narrow), sext(%val)
> + // == icmp slt i32 zext(%narrow), sext(%val)
> +
> + if (!(NeverNegative || IsSigned == Cmp->isSigned()))
> return false;
>
> Value *Op = Cmp->getOperand(Cmp->getOperand(0) == DU.NarrowDef ? 1 : 0);
> @@ -1097,7 +1117,7 @@ bool WidenIV::WidenLoopCompare(NarrowIVD
>
> // Widen the other operand of the compare, if necessary.
> if (CastWidth < IVWidth) {
> - Value *ExtOp = getExtend(Op, WideType, IsSigned, Cmp);
> + Value *ExtOp = getExtend(Op, WideType, Cmp->isSigned(), Cmp);
> DU.NarrowUse->replaceUsesOfWith(Op, ExtOp);
> }
> return true;
> @@ -1247,6 +1267,9 @@ PHINode *WidenIV::CreateWideIV(SCEVExpan
> if (!AddRec)
> return nullptr;
>
> + NeverNegative = SE->isKnownPredicate(ICmpInst::ICMP_SGE, AddRec,
> + SE->getConstant(AddRec->getType(), 0));
> +
> // Widen the induction variable expression.
> const SCEV *WideIVExpr = IsSigned ?
> SE->getSignExtendExpr(AddRec, WideType) :
>
> Modified: llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll
> URL:
>
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll?rev=248045&r1=248044&r2=248045&view=diff
>
<http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll?rev=248045&r1=248044&r2=248045&view=diff>
> ==============================================================================
> --- llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll (original)
> +++ llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll Fri Sep 18 16:21:02 2015
> @@ -193,3 +193,131 @@ for.body:
> for.end:
> ret i32 %sum.0
> }
> +
> +define i32 @test6(i32* %a, i32 %b) {
> +; CHECK-LABEL: @test6(
> +; CHECK: [[B_SEXT:%[a-z0-9]+]] = sext i32 %b to i64
> +; CHECK: for.cond:
> +; CHECK: icmp sle i64 %indvars.iv, [[B_SEXT]]
> +
> +entry:
> + br label %for.cond
> +
> +for.cond:
> + %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
> + %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
> + %cmp = icmp sle i32 %i.0, %b
> + br i1 %cmp, label %for.body, label %for.end
> +
> +for.body:
> + %idxprom = zext i32 %i.0 to i64
> + %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
> + %0 = load i32, i32* %arrayidx, align 4
> + %add = add nsw i32 %sum.0, %0
> + %inc = add nsw i32 %i.0, 1
> + br label %for.cond
> +
> +for.end:
> + ret i32 %sum.0
> +}
> +
> +define i32 @test7(i32* %a, i32 %b) {
> +; CHECK-LABEL: @test7(
> +; CHECK: [[B_ZEXT:%[a-z0-9]+]] = zext i32 %b to i64
> +; CHECK: [[B_SEXT:%[a-z0-9]+]] = sext i32 %b to i64
> +; CHECK: for.cond:
> +; CHECK: icmp ule i64 %indvars.iv, [[B_ZEXT]]
> +; CHECK: for.body:
> +; CHECK: icmp sle i64 %indvars.iv, [[B_SEXT]]
> +
> +entry:
> + br label %for.cond
> +
> +for.cond:
> + %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
> + %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
> + %cmp = icmp ule i32 %i.0, %b
> + br i1 %cmp, label %for.body, label %for.end
> +
> +for.body:
> + %idxprom = sext i32 %i.0 to i64
> + %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
> + %0 = load i32, i32* %arrayidx, align 4
> + %add = add nsw i32 %sum.0, %0
> + %inc = add nsw i32 %i.0, 1
> + %cmp2 = icmp sle i32 %i.0, %b
> + br i1 %cmp2, label %for.cond, label %for.end
> +
> +for.end:
> + ret i32 %sum.0
> +}
> +
> +define i32 @test8(i32* %a, i32 %b, i32 %init) {
> +; CHECK-LABEL: @test8(
> +; CHECK: [[INIT_SEXT:%[a-z0-9]+]] = sext i32 %init to i64
> +; CHECK: [[B_ZEXT:%[a-z0-9]+]] = zext i32 %b to i64
> +; CHECK: for.cond:
> +; Note: %indvars.iv is the sign extension of %i.0
> +; CHECK: %indvars.iv = phi i64 [ [[INIT_SEXT]], %for.cond.preheader ], [ %indvars.iv.next, %for.body ]
> +; CHECK: icmp ule i64 %indvars.iv, [[B_ZEXT]]
> +
> +entry:
> + %e = icmp sgt i32 %init, 0
> + br i1 %e, label %for.cond, label %leave
> +
> +for.cond:
> + %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
> + %i.0 = phi i32 [ %init, %entry ], [ %inc, %for.body ]
> + %cmp = icmp ule i32 %i.0, %b
> + br i1 %cmp, label %for.body, label %for.end
> +
> +for.body:
> + %idxprom = sext i32 %i.0 to i64
> + %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
> + %0 = load i32, i32* %arrayidx, align 4
> + %add = add nsw i32 %sum.0, %0
> + %inc = add nsw i32 %i.0, 1
> + %cmp2 = icmp slt i32 0, %inc
> + br i1 %cmp2, label %for.cond, label %for.end
> +
> +for.end:
> + ret i32 %sum.0
> +
> +leave:
> + ret i32 0
> +}
> +
> +define i32 @test9(i32* %a, i32 %b, i32 %init) {
> +; CHECK-LABEL: @test9(
> +; CHECK: [[INIT_ZEXT:%[a-z0-9]+]] = zext i32 %init to i64
> +; CHECK: [[B_SEXT:%[a-z0-9]+]] = sext i32 %b to i64
> +; CHECK: for.cond:
> +; Note: %indvars.iv is the zero extension of %i.0
> +; CHECK: %indvars.iv = phi i64 [ [[INIT_ZEXT]], %for.cond.preheader ], [ %indvars.iv.next, %for.body ]
> +; CHECK: icmp slt i64 %indvars.iv, [[B_SEXT]]
> +
> +entry:
> + %e = icmp sgt i32 %init, 0
> + br i1 %e, label %for.cond, label %leave
> +
> +for.cond:
> + %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.body ]
> + %i.0 = phi i32 [ %init, %entry ], [ %inc, %for.body ]
> + %cmp = icmp slt i32 %i.0, %b
> + br i1 %cmp, label %for.body, label %for.end
> +
> +for.body:
> + %idxprom = zext i32 %i.0 to i64
> + %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
> + %0 = load i32, i32* %arrayidx, align 4
> + %add = add nsw i32 %sum.0, %0
> + %inc = add nsw i32 %i.0, 1
> + %cmp2 = icmp slt i32 0, %inc
> + br i1 %cmp2, label %for.cond, label %for.end
> +
> +for.end:
> + ret i32 %sum.0
> +
> +leave:
> + ret i32 0
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list