summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2013-07-11 17:08:59 +0000
committerAndrew Trick <atrick@apple.com>2013-07-11 17:08:59 +0000
commit53b28f86236fc548143656929f39f38d9dc83e06 (patch)
treed7317e129df2e3231363fdc512ddb8fe5cb691ed /lib/Transforms/Scalar
parent53c86db25b5b4e163c68dc91c8ce1bc8180e6ff3 (diff)
downloadllvm-53b28f86236fc548143656929f39f38d9dc83e06.tar.gz
llvm-53b28f86236fc548143656929f39f38d9dc83e06.tar.bz2
llvm-53b28f86236fc548143656929f39f38d9dc83e06.tar.xz
indvars: Improve LFTR by eliminating truncation when comparing against a constant.
Patch by Michele Scandale! Adds a special handling of the case where, during the loop exit condition rewriting, the exit value is a constant of bitwidth lower than the type of the induction variable: instead of introducing a trunc operation in order to match correctly the operand types, it allows to convert the constant value to an equivalent constant, depending on the initial value of the induction variable and the trip count, in order have an equivalent comparison between the induction variable and the new constant. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186107 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r--lib/Transforms/Scalar/IndVarSimplify.cpp27
1 files changed, 23 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
index df11e92c9e..ddb5b270d0 100644
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -1612,10 +1612,29 @@ LinearFunctionTestReplace(Loop *L,
<< " IVCount:\t" << *IVCount << "\n");
IRBuilder<> Builder(BI);
- if (SE->getTypeSizeInBits(CmpIndVar->getType())
- > SE->getTypeSizeInBits(ExitCnt->getType())) {
- CmpIndVar = Builder.CreateTrunc(CmpIndVar, ExitCnt->getType(),
- "lftr.wideiv");
+
+ unsigned CmpIndVarSize = SE->getTypeSizeInBits(CmpIndVar->getType());
+ unsigned ExitCntSize = SE->getTypeSizeInBits(ExitCnt->getType());
+ if (CmpIndVarSize > ExitCntSize) {
+ const SCEVAddRecExpr *AR = cast<SCEVAddRecExpr>(SE->getSCEV(IndVar));
+ const SCEV *ARStart = AR->getStart();
+ const SCEV *ARStep = AR->getStepRecurrence(*SE);
+ if (isa<SCEVConstant>(ARStart) && isa<SCEVConstant>(IVCount)) {
+ const APInt &Start = cast<SCEVConstant>(ARStart)->getValue()->getValue();
+ const APInt &Count = cast<SCEVConstant>(IVCount)->getValue()->getValue();
+
+ APInt NewLimit;
+ if (cast<SCEVConstant>(ARStep)->getValue()->isNegative())
+ NewLimit = Start - Count.zext(CmpIndVarSize);
+ else
+ NewLimit = Start + Count.zext(CmpIndVarSize);
+ ExitCnt = ConstantInt::get(CmpIndVar->getType(), NewLimit);
+
+ DEBUG(dbgs() << " Widen RHS:\t" << *ExitCnt << "\n");
+ } else {
+ CmpIndVar = Builder.CreateTrunc(CmpIndVar, ExitCnt->getType(),
+ "lftr.wideiv");
+ }
}
Value *Cond = Builder.CreateICmp(P, CmpIndVar, ExitCnt, "exitcond");