[llvm] r292854 - [LoopUnroll] First form LCSSA, then loop-simplify

Michael Kuperstein via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 23 15:45:42 PST 2017


Author: mkuper
Date: Mon Jan 23 17:45:42 2017
New Revision: 292854

URL: http://llvm.org/viewvc/llvm-project?rev=292854&view=rev
Log:
[LoopUnroll] First form LCSSA, then loop-simplify

Running non-LCSSA-preserving LoopSimplify followed by LCSSA on (roughly) the
same loop is incorrect, since LoopSimplify may break LCSSA arbitrarily higher
in the loop nest. Instead, run LCSSA first, and then run LCSSA-preserving
LoopSimplify on the result.

This fixes PR31718.

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

Added:
    llvm/trunk/test/Transforms/LoopUnroll/pr31718.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=292854&r1=292853&r2=292854&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Mon Jan 23 17:45:42 2017
@@ -748,26 +748,25 @@ bool llvm::UnrollLoop(Loop *L, unsigned
       // OuterL includes all loops for which we can break loop-simplify, so
       // it's sufficient to simplify only it (it'll recursively simplify inner
       // loops too).
-      // TODO: That potentially might be compile-time expensive. We should try
-      // to fix the loop-simplified form incrementally.
-      // Note that we only preserve LCSSA at this stage if we need to and if we
-      // won't end up fixing it. If we end up fixing it anyways, we don't need
-      // to preserve it here and in fact we can't because it isn't correct.
-      simplifyLoop(OuterL, DT, LI, SE, AC, PreserveLCSSA && !NeedToFixLCSSA);
-
-      // LCSSA must be performed on the outermost affected loop. The unrolled
-      // loop's last loop latch is guaranteed to be in the outermost loop after
-      // LoopInfo's been updated by markAsRemoved.
-      Loop *LatchLoop = LI->getLoopFor(Latches.back());
-      if (!OuterL->contains(LatchLoop))
-        while (OuterL->getParentLoop() != LatchLoop)
-          OuterL = OuterL->getParentLoop();
+      if (NeedToFixLCSSA) {
+        // LCSSA must be performed on the outermost affected loop. The unrolled
+        // loop's last loop latch is guaranteed to be in the outermost loop
+        // after LoopInfo's been updated by markAsRemoved.
+        Loop *LatchLoop = LI->getLoopFor(Latches.back());
+        Loop *FixLCSSALoop = OuterL;
+        if (!FixLCSSALoop->contains(LatchLoop))
+          while (FixLCSSALoop->getParentLoop() != LatchLoop)
+            FixLCSSALoop = FixLCSSALoop->getParentLoop();
 
-      if (NeedToFixLCSSA)
-        formLCSSARecursively(*OuterL, *DT, LI, SE);
-      else if (PreserveLCSSA)
+        formLCSSARecursively(*FixLCSSALoop, *DT, LI, SE);
+      } else if (PreserveLCSSA) {
         assert(OuterL->isLCSSAForm(*DT) &&
                "Loops should be in LCSSA form after loop-unroll.");
+      }
+
+      // TODO: That potentially might be compile-time expensive. We should try
+      // to fix the loop-simplified form incrementally.
+      simplifyLoop(OuterL, DT, LI, SE, AC, PreserveLCSSA);
     } else {
       // Simplify loops for which we might've broken loop-simplify form.
       for (Loop *SubLoop : LoopsToSimplify)

Added: llvm/trunk/test/Transforms/LoopUnroll/pr31718.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnroll/pr31718.ll?rev=292854&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LoopUnroll/pr31718.ll (added)
+++ llvm/trunk/test/Transforms/LoopUnroll/pr31718.ll Mon Jan 23 17:45:42 2017
@@ -0,0 +1,55 @@
+; RUN: opt -loop-unroll -verify-loop-lcssa -S < %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at b = external local_unnamed_addr global i32, align 4
+
+; CHECK-LABEL: @main
+; CHECK: exit.loopexit:
+; CHECK: {{.*}} = phi i32 [ %d.0, %h3 ]
+; CHECK: br label %exit
+; CHECK: exit.loopexit1:
+; CHECK: {{.*}} = phi i32 [ %d.0, %h3.1 ]
+; CHECK: br label %exit
+
+define void @main() local_unnamed_addr #0 {
+ph1:
+  br label %h1
+
+h1:
+  %d.0 = phi i32 [ %1, %latch1 ], [ undef, %ph1 ]
+  br label %ph2
+
+ph2:
+  br label %h2
+
+h2:
+  %0 = phi i32 [ 0, %ph2 ], [ %inc, %latch2 ]
+  br label %h3
+
+h3:
+  br i1 undef, label %latch3, label %exit
+
+latch3:
+  br i1 false, label %exit3, label %h3
+
+exit3:
+  br label %latch2
+
+latch2:
+  %inc = add nuw nsw i32 %0, 1
+  %cmp = icmp slt i32 %inc, 2
+  br i1 %cmp, label %h2, label %exit2
+
+exit2:
+  br i1 undef, label %latch1, label %ph2
+
+latch1:                 ; preds = %exit2
+  %1 = load i32, i32* @b, align 4
+  br label %h1
+
+exit:
+  %d.0.lcssa = phi i32 [ %d.0, %h3 ]
+  ret void
+}




More information about the llvm-commits mailing list