[llvm] r198338 - indvars: insert truncate at loop boundary to avoid redundant IVs.

Andrew Trick atrick at apple.com
Thu Jan 2 11:29:38 PST 2014


Author: atrick
Date: Thu Jan  2 13:29:38 2014
New Revision: 198338

URL: http://llvm.org/viewvc/llvm-project?rev=198338&view=rev
Log:
indvars: insert truncate at loop boundary to avoid redundant IVs.

When widening an IV to remove s/zext, we generally try to eliminate
the original narrow IV. However, LCSSA phi nodes outside the loop were
still using the original IV. Clean this up more aggressively to avoid
redundancy in generated code.

Added:
    llvm/trunk/test/Transforms/IndVarSimplify/iv-widen.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=198338&r1=198337&r2=198338&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Thu Jan  2 13:29:38 2014
@@ -897,15 +897,24 @@ const SCEVAddRecExpr *WidenIV::GetWideRe
   return AddRec;
 }
 
+/// 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) {
+  IRBuilder<> Builder(getInsertPointForUses(DU.NarrowUse, DU.NarrowDef, DT));
+  Value *Trunc = Builder.CreateTrunc(DU.WideDef, DU.NarrowDef->getType());
+  DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, Trunc);
+}
+
 /// WidenIVUse - Determine whether an individual user of the narrow IV can be
 /// widened. If so, return the wide clone of the user.
 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)
+      LI->getLoopFor(DU.NarrowUse->getParent()) != L) {
+    truncateIVUse(DU, DT);
     return 0;
-
+  }
   // Our raison d'etre! Eliminate sign and zero extension.
   if (IsSigned ? isa<SExtInst>(DU.NarrowUse) : isa<ZExtInst>(DU.NarrowUse)) {
     Value *NewDef = DU.WideDef;
@@ -953,9 +962,7 @@ Instruction *WidenIV::WidenIVUse(NarrowI
     // This user does not evaluate to a recurence after widening, so don't
     // follow it. Instead insert a Trunc to kill off the original use,
     // eventually isolating the original narrow IV so it can be removed.
-    IRBuilder<> Builder(getInsertPointForUses(DU.NarrowUse, DU.NarrowDef, DT));
-    Value *Trunc = Builder.CreateTrunc(DU.WideDef, DU.NarrowDef->getType());
-    DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, Trunc);
+    truncateIVUse(DU, DT);
     return 0;
   }
   // Assume block terminators cannot evaluate to a recurrence. We can't to

Added: llvm/trunk/test/Transforms/IndVarSimplify/iv-widen.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/iv-widen.ll?rev=198338&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/iv-widen.ll (added)
+++ llvm/trunk/test/Transforms/IndVarSimplify/iv-widen.ll Thu Jan  2 13:29:38 2014
@@ -0,0 +1,39 @@
+; RUN: opt < %s -indvars -S | FileCheck %s
+
+target triple = "x86_64-apple-darwin"
+
+; CHECK-LABEL: @sloop
+; CHECK-LABEL: B18:
+; Only one phi now.
+; CHECK: phi
+; CHECK-NOT: phi
+; We now get 2 trunc, one for the gep and one for the lcssa phi.
+; CHECK: trunc i64 %indvars.iv to i32
+; CHECK: trunc i64 %indvars.iv to i32
+; CHECK-LABEL: B24:
+define void @sloop(i32* %a) {
+Prologue:
+  br i1 undef, label %B18, label %B6
+
+B18:                                        ; preds = %B24, %Prologue
+  %.02 = phi i32 [ 0, %Prologue ], [ %tmp33, %B24 ]
+  %tmp23 = zext i32 %.02 to i64
+  %tmp33 = add i32 %.02, 1
+  %o = getelementptr i32* %a, i32 %.02
+  %v = load i32* %o
+  %t = icmp eq i32 %v, 0
+  br i1 %t, label %exit24, label %B24
+
+B24:                                        ; preds = %B18
+  %t2 = icmp eq i32 %tmp33, 20
+  br i1 %t2, label %B6, label %B18
+
+B6:                                       ; preds = %Prologue
+  ret void
+
+exit24:                      ; preds = %B18
+  call void @dummy(i32 %.02)
+  unreachable
+}
+
+declare void @dummy(i32)





More information about the llvm-commits mailing list