Index: lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- lib/Transforms/Scalar/IndVarSimplify.cpp +++ lib/Transforms/Scalar/IndVarSimplify.cpp @@ -936,13 +936,20 @@ if (!Cmp) return false; - // Must be a signed compare. - if (!CmpInst::isSigned(Cmp->getPredicate())) + // Sign of IV user and compare must match. + if (IsSigned != CmpInst::isSigned(Cmp->getPredicate())) return false; - // Must be a signed IV user. - if (!IsSigned) - return false; + // IV of unsigned compare must be uniform step by one. + if (!IsSigned) { + const SCEV *NarrowExpr = SE->getSCEV(DU.NarrowDef); + const SCEVAddRecExpr *AR = dyn_cast(NarrowExpr); + if (!AR) + return false; + const SCEV *Step = dyn_cast(AR->getStepRecurrence(*SE)); + if (!Step || !Step->isOne()) + return false; + } Value *Op = Cmp->getOperand(Cmp->getOperand(0) == DU.NarrowDef ? 1 : 0); unsigned CastWidth = SE->getTypeSizeInBits(Op->getType()); Index: test/Transforms/IndVarSimplify/widen-loop-comp.ll =================================================================== --- test/Transforms/IndVarSimplify/widen-loop-comp.ll +++ test/Transforms/IndVarSimplify/widen-loop-comp.ll @@ -162,3 +162,31 @@ for.end: ret i32 0 } + +; CHECK-LABEL: @test5 +; CHECK: zext i32 %b +; CHECK: for.cond: +; CHECK: phi i64 +; CHECK: icmp ule i64 + +define i32 @test5(i32* %a, i32 %b) { +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 = zext i32 %i.0 to i64 + %arrayidx = getelementptr inbounds i32* %a, i64 %idxprom + %0 = load 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 +}