summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2014-01-07 06:59:12 +0000
committerAndrew Trick <atrick@apple.com>2014-01-07 06:59:12 +0000
commitb4e0c9b85d7a6c5adc05059c85e4cc52dd2d92b2 (patch)
treec8b16585c3a5a3b28dd9709ab2cadbc6023b4e80
parenta4d123f4610be7603767629c793614bd4ec15907 (diff)
downloadllvm-b4e0c9b85d7a6c5adc05059c85e4cc52dd2d92b2.tar.gz
llvm-b4e0c9b85d7a6c5adc05059c85e4cc52dd2d92b2.tar.bz2
llvm-b4e0c9b85d7a6c5adc05059c85e4cc52dd2d92b2.tar.xz
Reapply r198654 "indvars: sink truncates outside the loop."
This doesn't seem to have actually broken anything. It was paranoia on my part. Trying again now that bots are more stable. This is a follow up of the r198338 commit that added truncates for lcssa phi nodes. Sinking the truncates below the phis cleans up the loop and simplifies subsequent analysis within the indvars pass. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198678 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/IndVarSimplify.cpp27
-rw-r--r--test/Transforms/IndVarSimplify/iv-widen.ll7
2 files changed, 27 insertions, 7 deletions
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
index 1076e50bc2..08df9533f1 100644
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -883,6 +883,8 @@ const SCEVAddRecExpr *WidenIV::GetWideRecurrence(Instruction *NarrowUse) {
/// This IV user cannot be widen. Replace this use of the original narrow IV
/// with a truncation of the new wide IV to isolate and eliminate the narrow IV.
static void truncateIVUse(NarrowIVDefUse DU, DominatorTree *DT) {
+ DEBUG(dbgs() << "INDVARS: Truncate IV " << *DU.WideDef
+ << " for user " << *DU.NarrowUse << "\n");
IRBuilder<> Builder(getInsertPointForUses(DU.NarrowUse, DU.NarrowDef, DT));
Value *Trunc = Builder.CreateTrunc(DU.WideDef, DU.NarrowDef->getType());
DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, Trunc);
@@ -893,10 +895,27 @@ static void truncateIVUse(NarrowIVDefUse DU, DominatorTree *DT) {
Instruction *WidenIV::WidenIVUse(NarrowIVDefUse DU, SCEVExpander &Rewriter) {
// Stop traversing the def-use chain at inner-loop phis or post-loop phis.
- if (isa<PHINode>(DU.NarrowUse) &&
- LI->getLoopFor(DU.NarrowUse->getParent()) != L) {
- truncateIVUse(DU, DT);
- return 0;
+ if (PHINode *UsePhi = dyn_cast<PHINode>(DU.NarrowUse)) {
+ if (LI->getLoopFor(UsePhi->getParent()) != L) {
+ // For LCSSA phis, sink the truncate outside the loop.
+ // After SimplifyCFG most loop exit targets have a single predecessor.
+ // Otherwise fall back to a truncate within the loop.
+ if (UsePhi->getNumOperands() != 1)
+ truncateIVUse(DU, DT);
+ else {
+ PHINode *WidePhi =
+ PHINode::Create(DU.WideDef->getType(), 1, UsePhi->getName() + ".wide",
+ UsePhi);
+ WidePhi->addIncoming(DU.WideDef, UsePhi->getIncomingBlock(0));
+ IRBuilder<> Builder(WidePhi->getParent()->getFirstInsertionPt());
+ Value *Trunc = Builder.CreateTrunc(WidePhi, DU.NarrowDef->getType());
+ UsePhi->replaceAllUsesWith(Trunc);
+ DeadInsts.push_back(UsePhi);
+ DEBUG(dbgs() << "INDVARS: Widen lcssa phi " << *UsePhi
+ << " to " << *WidePhi << "\n");
+ }
+ return 0;
+ }
}
// Our raison d'etre! Eliminate sign and zero extension.
if (IsSigned ? isa<SExtInst>(DU.NarrowUse) : isa<ZExtInst>(DU.NarrowUse)) {
diff --git a/test/Transforms/IndVarSimplify/iv-widen.ll b/test/Transforms/IndVarSimplify/iv-widen.ll
index 12067ab6fe..c899e2f0a5 100644
--- a/test/Transforms/IndVarSimplify/iv-widen.ll
+++ b/test/Transforms/IndVarSimplify/iv-widen.ll
@@ -7,10 +7,11 @@ target triple = "x86_64-apple-darwin"
; Only one phi now.
; CHECK: phi
; CHECK-NOT: phi
-; We now get 2 trunc, one for the gep and one for the lcssa phi.
+; One trunc for the gep.
; CHECK: trunc i64 %indvars.iv to i32
-; CHECK: trunc i64 %indvars.iv to i32
-; CHECK-LABEL: B24:
+; One trunc for the dummy() call.
+; CHECK-LABEL: exit24:
+; CHECK: trunc i64 {{.*}}lcssa.wide to i32
define void @sloop(i32* %a) {
Prologue:
br i1 undef, label %B18, label %B6