From abc8f344d68534864b43420fc0e097ba3340cd3f Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Wed, 3 Jul 2019 18:41:03 +0000 Subject: [PATCH] [LFTR] Sink the decision not use truncate scheme for constants into genLoopLimit [NFC] We might as well just evaluate the constants using SCEV, and having the cases grouped makes the logic slightly easier to read anyway. llvm-svn: 365070 --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 89 +++++++++++++-------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index 0566a15..e3eb179 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -2361,10 +2361,18 @@ static Value *genLoopLimit(PHINode *IndVar, BasicBlock *ExitingBB, // overflow. const SCEV *IVInit = AR->getStart(); - // For integer IVs, truncate the IV before computing IVInit + BECount. + // For integer IVs, truncate the IV before computing IVInit + BECount, + // unless we know apriori that the limit must be a constant when evaluated + // in the bitwidth of the IV. We prefer (potentially) keeping a truncate + // of the IV in the loop over a (potentially) expensive expansion of the + // widened exit count computation. if (SE->getTypeSizeInBits(IVInit->getType()) - > SE->getTypeSizeInBits(ExitCount->getType())) - IVInit = SE->getTruncateExpr(IVInit, ExitCount->getType()); + > SE->getTypeSizeInBits(ExitCount->getType())) { + if (isa(IVInit) && isa(ExitCount)) + ExitCount = SE->getZeroExtendExpr(ExitCount, IVInit->getType()); + else + IVInit = SE->getTruncateExpr(IVInit, ExitCount->getType()); + } const SCEV *IVLimit = SE->getAddExpr(IVInit, ExitCount); @@ -2467,54 +2475,43 @@ linearFunctionTestReplace(Loop *L, BasicBlock *ExitingBB, unsigned CmpIndVarSize = SE->getTypeSizeInBits(CmpIndVar->getType()); unsigned ExitCntSize = SE->getTypeSizeInBits(ExitCnt->getType()); if (CmpIndVarSize > ExitCntSize) { - const SCEVAddRecExpr *AR = cast(SE->getSCEV(IndVar)); - const SCEV *ARStart = AR->getStart(); - const SCEV *ARStep = AR->getStepRecurrence(*SE); - // For constant ExitCount, avoid truncation. - if (isa(ARStart) && isa(ExitCount)) { - const APInt &Start = cast(ARStart)->getAPInt(); - APInt Count = cast(ExitCount)->getAPInt(); - Count = Count.zext(CmpIndVarSize); - if (UsePostInc) - ++Count; - assert(cast(ARStep)->getValue()->isOne()); - APInt NewLimit = Start + Count; - ExitCnt = ConstantInt::get(CmpIndVar->getType(), NewLimit); + // The constant case was handled in the IV width to start with! + assert(!isa(cast(SE->getSCEV(IndVar))->getStart()) || + !isa(ExitCount)); + + // We try to extend trip count first. If that doesn't work we truncate IV. + // Zext(trunc(IV)) == IV implies equivalence of the following two: + // Trunc(IV) == ExitCnt and IV == zext(ExitCnt). Similarly for sext. If + // one of the two holds, extend the trip count, otherwise we truncate IV. + bool Extended = false; + const SCEV *IV = SE->getSCEV(CmpIndVar); + const SCEV *ZExtTrunc = + SE->getZeroExtendExpr(SE->getTruncateExpr(SE->getSCEV(CmpIndVar), + ExitCnt->getType()), + CmpIndVar->getType()); + + if (ZExtTrunc == IV) { + Extended = true; + ExitCnt = Builder.CreateZExt(ExitCnt, IndVar->getType(), + "wide.trip.count"); } else { - // We try to extend trip count first. If that doesn't work we truncate IV. - // Zext(trunc(IV)) == IV implies equivalence of the following two: - // Trunc(IV) == ExitCnt and IV == zext(ExitCnt). Similarly for sext. If - // one of the two holds, extend the trip count, otherwise we truncate IV. - bool Extended = false; - const SCEV *IV = SE->getSCEV(CmpIndVar); - const SCEV *ZExtTrunc = - SE->getZeroExtendExpr(SE->getTruncateExpr(SE->getSCEV(CmpIndVar), - ExitCnt->getType()), - CmpIndVar->getType()); - - if (ZExtTrunc == IV) { + const SCEV *SExtTrunc = + SE->getSignExtendExpr(SE->getTruncateExpr(SE->getSCEV(CmpIndVar), + ExitCnt->getType()), + CmpIndVar->getType()); + if (SExtTrunc == IV) { Extended = true; - ExitCnt = Builder.CreateZExt(ExitCnt, IndVar->getType(), + ExitCnt = Builder.CreateSExt(ExitCnt, IndVar->getType(), "wide.trip.count"); - } else { - const SCEV *SExtTrunc = - SE->getSignExtendExpr(SE->getTruncateExpr(SE->getSCEV(CmpIndVar), - ExitCnt->getType()), - CmpIndVar->getType()); - if (SExtTrunc == IV) { - Extended = true; - ExitCnt = Builder.CreateSExt(ExitCnt, IndVar->getType(), - "wide.trip.count"); - } } - - if (Extended) { - bool Discard; - L->makeLoopInvariant(ExitCnt, Discard); - } else - CmpIndVar = Builder.CreateTrunc(CmpIndVar, ExitCnt->getType(), - "lftr.wideiv"); } + + if (Extended) { + bool Discard; + L->makeLoopInvariant(ExitCnt, Discard); + } else + CmpIndVar = Builder.CreateTrunc(CmpIndVar, ExitCnt->getType(), + "lftr.wideiv"); } LLVM_DEBUG(dbgs() << "INDVARS: Rewriting loop exit condition to:\n" << " LHS:" << *CmpIndVar << '\n' -- 2.7.4