[llvm] r265983 - [LoopUtils, LV] Fix PR27246 (first-order recurrences)

Matthew Simpson via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 11 12:48:19 PDT 2016


Author: mssimpso
Date: Mon Apr 11 14:48:18 2016
New Revision: 265983

URL: http://llvm.org/viewvc/llvm-project?rev=265983&view=rev
Log:
[LoopUtils, LV] Fix PR27246 (first-order recurrences)

This patch ensures that when we detect first-order recurrences, we reject a phi
node if its previous value 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.

Differential Revision: http://reviews.llvm.org/D18971

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

Modified: llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp?rev=265983&r1=265982&r2=265983&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp Mon Apr 11 14:48:18 2016
@@ -541,7 +541,7 @@ bool RecurrenceDescriptor::isFirstOrderR
   // 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))
+  if (!Previous || !TheLoop->contains(Previous) || isa<PHINode>(Previous))
     return false;
 
   // Ensure every user of the phi node is dominated by the previous value. The

Modified: llvm/trunk/test/Transforms/LoopVectorize/AArch64/first-order-recurrence.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopVectorize/AArch64/first-order-recurrence.ll?rev=265983&r1=265982&r2=265983&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopVectorize/AArch64/first-order-recurrence.ll (original)
+++ llvm/trunk/test/Transforms/LoopVectorize/AArch64/first-order-recurrence.ll Mon Apr 11 14:48:18 2016
@@ -256,3 +256,44 @@ for.cond.for.end_crit_edge:
 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
+}




More information about the llvm-commits mailing list