From 1ade0f0faa98877b688e0b9da58e876052c1e04e Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 18 Nov 2014 02:20:58 +0000 Subject: [PATCH] IndVarSimplify: Allow LFTR to fire more often I added a pessimization in r217102 to prevent miscompiles when the incremented induction variable was used in a comparison; it would be poison. Try to use the incremented induction variable more often when we can be sure that the increment won't end in poison. Differential Revision: http://reviews.llvm.org/D6222 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222213 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/IndVarSimplify.cpp | 23 ++++++++++++++++++- .../IndVarSimplify/lftr-extend-const.ll | 2 +- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index bf90912ebd0..fc6d1837060 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -1719,8 +1719,29 @@ LinearFunctionTestReplace(Loop *L, // FIXME: In theory, SCEV could drop flags even though they exist in IR. // A more robust solution would involve getting a new expression for // CmpIndVar by applying non-NSW/NUW AddExprs. + auto WrappingFlags = + ScalarEvolution::setFlags(SCEV::FlagNUW, SCEV::FlagNSW); + const SCEV *IVInit = IncrementedIndvarSCEV->getStart(); + if (SE->getTypeSizeInBits(IVInit->getType()) > + SE->getTypeSizeInBits(IVCount->getType())) + IVInit = SE->getTruncateExpr(IVInit, IVCount->getType()); + unsigned BitWidth = SE->getTypeSizeInBits(IVCount->getType()); + Type *WideTy = IntegerType::get(SE->getContext(), BitWidth + 1); + // Check if InitIV + BECount+1 requires sign/zero extension. + // If not, clear the corresponding flag from WrappingFlags because it is not + // necessary for those flags in the IncrementedIndvarSCEV expression. + if (SE->getSignExtendExpr(SE->getAddExpr(IVInit, BackedgeTakenCount), + WideTy) == + SE->getAddExpr(SE->getSignExtendExpr(IVInit, WideTy), + SE->getSignExtendExpr(BackedgeTakenCount, WideTy))) + WrappingFlags = ScalarEvolution::clearFlags(WrappingFlags, SCEV::FlagNSW); + if (SE->getZeroExtendExpr(SE->getAddExpr(IVInit, BackedgeTakenCount), + WideTy) == + SE->getAddExpr(SE->getZeroExtendExpr(IVInit, WideTy), + SE->getZeroExtendExpr(BackedgeTakenCount, WideTy))) + WrappingFlags = ScalarEvolution::clearFlags(WrappingFlags, SCEV::FlagNUW); if (!ScalarEvolution::maskFlags(IncrementedIndvarSCEV->getNoWrapFlags(), - SCEV::FlagNUW | SCEV::FlagNSW)) { + WrappingFlags)) { // Add one to the "backedge-taken" count to get the trip count. // This addition may overflow, which is valid as long as the comparison is // truncated to BackedgeTakenCount->getType(). diff --git a/test/Transforms/IndVarSimplify/lftr-extend-const.ll b/test/Transforms/IndVarSimplify/lftr-extend-const.ll index eeffd0f5502..f12c68cacb6 100644 --- a/test/Transforms/IndVarSimplify/lftr-extend-const.ll +++ b/test/Transforms/IndVarSimplify/lftr-extend-const.ll @@ -2,7 +2,7 @@ ; CHECK-LABEL: @foo( ; CHECK-NOT: %lftr.wideiv = trunc i32 %indvars.iv.next to i16 -; CHECK: %exitcond = icmp ne i32 %indvars.iv, 511 +; CHECK: %exitcond = icmp ne i32 %indvars.iv.next, 512 define void @foo() #0 { entry: br label %for.body -- 2.34.1