[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