Index: lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- lib/Transforms/Scalar/IndVarSimplify.cpp +++ lib/Transforms/Scalar/IndVarSimplify.cpp @@ -1984,8 +1984,33 @@ DEBUG(dbgs() << " Widen RHS:\t" << *ExitCnt << "\n"); } else { - CmpIndVar = Builder.CreateTrunc(CmpIndVar, ExitCnt->getType(), - "lftr.wideiv"); + bool Extended = false; + const SCEV *IV = SE->getSCEV(CmpIndVar); + const SCEV *ZExTrunc = + SE->getZeroExtendExpr(SE->getTruncateExpr(SE->getSCEV(CmpIndVar), + ExitCnt->getType()), + CmpIndVar->getType()); + + if (ZExTrunc == IV) { + Extended = true; + ExitCnt = Builder.CreateZExt(ExitCnt, IndVar->getType(), + "wide.trip.count"); + } else { + const SCEV *SExTrunc = + SE->getSignExtendExpr(SE->getTruncateExpr(SE->getSCEV(CmpIndVar), + ExitCnt->getType()), + CmpIndVar->getType()); + if (SExTrunc == IV) { + Extended = true; + ExitCnt = Builder.CreateSExt(ExitCnt, IndVar->getType(), + "wide.trip.count"); + } + } + + if (!Extended) { + CmpIndVar = Builder.CreateTrunc(CmpIndVar, ExitCnt->getType(), + "lftr.wideiv"); + } } } Value *Cond = Builder.CreateICmp(P, CmpIndVar, ExitCnt, "exitcond"); Index: test/Transforms/IndVarSimplify/elim-extend.ll =================================================================== --- test/Transforms/IndVarSimplify/elim-extend.ll +++ test/Transforms/IndVarSimplify/elim-extend.ll @@ -41,6 +41,8 @@ br i1 %precond, label %loop, label %return ; CHECK: loop: ; CHECK-NOT: sext +; CHECK: wide.trip.count = sext +; CHECK-NOT: sext ; CHECK: exit: loop: %iv = phi i32 [ %postiv, %loop ], [ %init, %entry ] Index: test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll =================================================================== --- test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll +++ test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -indvars -S | not grep sext +; RUN: opt < %s -indvars -S | grep -v wide.trip.count | not grep sext ; Provide legal integer types. target datalayout = "n8:16:32:64" Index: test/Transforms/IndVarSimplify/signed-trip-count.ll =================================================================== --- test/Transforms/IndVarSimplify/signed-trip-count.ll +++ test/Transforms/IndVarSimplify/signed-trip-count.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -indvars -S > %t +; RUN: opt < %s -indvars -S | grep -v wide.trip.count > %t ; RUN: not grep sext %t ; RUN: grep phi %t | count 1 Index: test/Transforms/IndVarSimplify/ult-sub-to-eq.ll =================================================================== --- test/Transforms/IndVarSimplify/ult-sub-to-eq.ll +++ test/Transforms/IndVarSimplify/ult-sub-to-eq.ll @@ -33,8 +33,9 @@ ; CHECK-LABEL: @test1( ; check that we turn the IV test into an eq. -; CHECK: %lftr.wideiv = trunc i64 %indvars.iv.next to i32 -; CHECK: %exitcond = icmp ne i32 %lftr.wideiv, %sub +; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 +; CHECK: %wide.trip.count = zext i32 %sub to i64 +; CHECK: %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count ; CHECK: br i1 %exitcond, label %for.body, label %for.end.loopexit }