[PATCH] D18971: [LoopUtils, LV] Fix PR27246 (first-order recurrences)

Matthew Simpson via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 11 10:32:17 PDT 2016


mssimpso created this revision.
mssimpso added a reviewer: mcrosier.
mssimpso added a subscriber: llvm-commits.
Herald added a subscriber: mcrosier.

This patch ensures that when we detect first-order recurrences, we reject a phi node if its previous is also a phi node. During vectorization the initial and previous values of the recurrence are shuffled together to create the value for the current iteration. However, phi nodes are not widened like other instructions. This fixes PR27246.

http://reviews.llvm.org/D18971

Files:
  lib/Transforms/Utils/LoopUtils.cpp
  test/Transforms/LoopVectorize/AArch64/first-order-recurrence.ll

Index: test/Transforms/LoopVectorize/AArch64/first-order-recurrence.ll
===================================================================
--- test/Transforms/LoopVectorize/AArch64/first-order-recurrence.ll
+++ test/Transforms/LoopVectorize/AArch64/first-order-recurrence.ll
@@ -256,3 +256,44 @@
 for.end:
   ret void
 }
+
+; CHECK-LABEL: @PR27246
+;
+; int PR27246() {
+;   unsigned int e, n;
+;   for (int i = 1; i < 49; ++i) {
+;     for (int k = i; k > 1; --k)
+;       e = k;
+;     n = e;
+;   }
+;   return n;
+; }
+;
+; CHECK-NOT: vector.ph:
+;
+define i32 @PR27246() {
+entry:
+  br label %for.cond1.preheader
+
+for.cond1.preheader:
+  %i.016 = phi i32 [ 1, %entry ], [ %inc, %for.cond.cleanup3 ]
+  %e.015 = phi i32 [ undef, %entry ], [ %e.1.lcssa, %for.cond.cleanup3 ]
+  br label %for.cond1
+
+for.cond.cleanup:
+  %e.1.lcssa.lcssa = phi i32 [ %e.1.lcssa, %for.cond.cleanup3 ]
+  ret i32 %e.1.lcssa.lcssa
+
+for.cond1:
+  %e.1 = phi i32 [ %k.0, %for.cond1 ], [ %e.015, %for.cond1.preheader ]
+  %k.0 = phi i32 [ %dec, %for.cond1 ], [ %i.016, %for.cond1.preheader ]
+  %cmp2 = icmp sgt i32 %k.0, 1
+  %dec = add nsw i32 %k.0, -1
+  br i1 %cmp2, label %for.cond1, label %for.cond.cleanup3
+
+for.cond.cleanup3:
+  %e.1.lcssa = phi i32 [ %e.1, %for.cond1 ]
+  %inc = add nuw nsw i32 %i.016, 1
+  %exitcond = icmp eq i32 %inc, 49
+  br i1 %exitcond, label %for.cond.cleanup, label %for.cond1.preheader
+}
Index: lib/Transforms/Utils/LoopUtils.cpp
===================================================================
--- lib/Transforms/Utils/LoopUtils.cpp
+++ lib/Transforms/Utils/LoopUtils.cpp
@@ -540,16 +540,16 @@
 
   // Get the previous value. The previous value comes from the latch edge while
   // the initial value comes form the preheader edge.
-  auto *Previous = dyn_cast<Instruction>(Phi->getIncomingValueForBlock(Latch));
-  if (!Previous || !TheLoop->contains(Previous))
+  auto *Previous = Phi->getIncomingValueForBlock(Latch);
+  if (TheLoop->isLoopInvariant(Previous) || isa<PHINode>(Previous))
     return false;
 
   // Ensure every user of the phi node is dominated by the previous value. The
   // dominance requirement ensures the loop vectorizer will not need to
   // vectorize the initial value prior to the first iteration of the loop.
   for (User *U : Phi->users())
     if (auto *I = dyn_cast<Instruction>(U))
-      if (!DT->dominates(Previous, I))
+      if (!DT->dominates(cast<Instruction>(Previous), I))
         return false;
 
   return true;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18971.53275.patch
Type: text/x-patch
Size: 2487 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160411/7c193565/attachment.bin>


More information about the llvm-commits mailing list