summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Scalar/IndVarSimplify.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/IndVarSimplify.cpp32
1 files changed, 30 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
index 4cb2d0d1bf9..ddd5cdc6bcc 100644
--- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -1989,8 +1989,36 @@ linearFunctionTestReplace(Loop *L,
DEBUG(dbgs() << " Widen RHS:\t" << *ExitCnt << "\n");
} else {
- CmpIndVar = Builder.CreateTrunc(CmpIndVar, ExitCnt->getType(),
- "lftr.wideiv");
+ // 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 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 {
+ 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)
+ CmpIndVar = Builder.CreateTrunc(CmpIndVar, ExitCnt->getType(),
+ "lftr.wideiv");
}
}
Value *Cond = Builder.CreateICmp(P, CmpIndVar, ExitCnt, "exitcond");
OpenPOWER on IntegriCloud