[llvm] r301239 - [LoopUnroll] Don't try to unroll non canonical loops.

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 24 13:14:11 PDT 2017


Author: davide
Date: Mon Apr 24 15:14:11 2017
New Revision: 301239

URL: http://llvm.org/viewvc/llvm-project?rev=301239&view=rev
Log:
[LoopUnroll] Don't try to unroll non canonical loops.

The current Loop Unroll implementation works with loops having a
single latch that contains a conditional branch to a block outside
the loop (the other successor is, by defition of latch, the header).
If this precondition doesn't hold, avoid unrolling the loop as
the code is not ready to handle such circumstances.

Differential Revision:  https://reviews.llvm.org/D32261

Added:
    llvm/trunk/test/Transforms/LoopUnroll/not-rotated.ll
Modified:
    llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp

Modified: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp?rev=301239&r1=301238&r2=301239&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Mon Apr 24 15:14:11 2017
@@ -318,6 +318,10 @@ bool llvm::UnrollLoop(Loop *L, unsigned
     return false;
   }
 
+  // The current loop unroll pass can only unroll loops with a single latch
+  // that's a conditional branch exiting the loop.
+  // FIXME: The implementation can be extended to work with more complicated
+  // cases, e.g. loops with multiple latches.
   BasicBlock *Header = L->getHeader();
   BranchInst *BI = dyn_cast<BranchInst>(LatchBlock->getTerminator());
 
@@ -328,6 +332,17 @@ bool llvm::UnrollLoop(Loop *L, unsigned
     return false;
   }
 
+  auto CheckSuccessors = [&](unsigned S1, unsigned S2) {
+    return BI->getSuccessor(S1) == Header && !L->contains(BI->getSuccessor(S2));
+
+  };
+
+  if (!CheckSuccessors(0, 1) && !CheckSuccessors(1, 0)) {
+    DEBUG(dbgs() << "Can't unroll; only loops with one conditional latch"
+                    " exiting the loop can be unrolled\n");
+    return false;
+  }
+
   if (Header->hasAddressTaken()) {
     // The loop-rotate pass can be helpful to avoid this in many cases.
     DEBUG(dbgs() <<

Added: llvm/trunk/test/Transforms/LoopUnroll/not-rotated.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnroll/not-rotated.ll?rev=301239&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LoopUnroll/not-rotated.ll (added)
+++ llvm/trunk/test/Transforms/LoopUnroll/not-rotated.ll Mon Apr 24 15:14:11 2017
@@ -0,0 +1,26 @@
+; PR28103
+; Bail out if the two successors are not the header
+; and another bb outside of the loop. This case is not
+; properly handled by LoopUnroll, currently.
+
+; RUN: opt -loop-unroll -verify-dom-info %s
+; REQUIRE: asserts
+
+define void @tinkywinky(i1 %patatino) {
+entry:
+  br label %header1
+header1:
+  %indvars.iv = phi i64 [ 1, %body2 ], [ 0, %entry ]
+  %exitcond = icmp ne i64 %indvars.iv, 1
+  br i1 %exitcond, label %body1, label %exit
+body1:
+  br i1 %patatino, label %body2, label %sink
+body2:
+  br i1 %patatino, label %header1, label %body3
+body3:
+  br label %sink
+sink:
+  br label %body2
+exit:
+  ret void
+}




More information about the llvm-commits mailing list