[PATCH] D21665: [LoopSimplify] Update LCSSA after separating nested loops.

Michael Zolotukhin via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 23 15:15:24 PDT 2016


mzolotukhin created this revision.
mzolotukhin added reviewers: sanjoy, hfinkel, chandlerc.
mzolotukhin added a subscriber: llvm-commits.

Usually LCSSA survives this transformation, but in some cases (see
attached test) it doesn't: values from the original loop after
separating might be used from the outer loop. Before the transformation
it was the same loop, so LCSSA phis were not required.

We might move this logic, along with the logic for updating LoopInfo, to
BasicBlockUtils (routine SplitBlockPredecessors), but I now see this
pretty independent on the fix in question.

This fixes PR28272.

http://reviews.llvm.org/D21665

Files:
  lib/Transforms/Utils/LoopSimplify.cpp
  test/Transforms/LoopSimplify/pr28272.ll

Index: test/Transforms/LoopSimplify/pr28272.ll
===================================================================
--- /dev/null
+++ test/Transforms/LoopSimplify/pr28272.ll
@@ -0,0 +1,31 @@
+; RUN: opt < %s -lcssa -loop-unroll -S | FileCheck %s
+target triple = "x86_64-unknown-linux-gnu"
+
+; Check that we don't crash on this test.
+; LoopSimplify is invoked by LoopUnroll.
+; CHECK-LABEL: @foo
+define void @foo() {
+entry:
+  br label %bb29
+
+bb29:
+  br label %bb40
+
+bb40:
+  br i1 true, label %bb40, label %bb43
+
+bb43:
+  %a = phi i32 [ undef, %bb40 ], [ 0, %bb45 ], [ %a, %bb54 ]
+  %b = phi i32 [ 0, %bb40 ], [ 1, %bb54 ], [ %c, %bb45 ]
+  br i1 true, label %bb114, label %bb29
+
+bb114:
+  %c = add i32 0, 1
+  br i1 true, label %bb45, label %bb54
+
+bb45:
+  br label %bb43
+
+bb54:
+  br label %bb43
+}
Index: lib/Transforms/Utils/LoopSimplify.cpp
===================================================================
--- lib/Transforms/Utils/LoopSimplify.cpp
+++ lib/Transforms/Utils/LoopSimplify.cpp
@@ -339,6 +339,41 @@
     }
   }
 
+  if (PreserveLCSSA) {
+    // Fix LCSSA form for L. Some values, which previously were only used inside
+    // L, can now be used in NewOuter loop. We need to insert phi-nodes for them
+    // in corresponding exit blocks.
+    SmallVector<BasicBlock *, 8> ExitBlocks;
+    L->getExitBlocks(ExitBlocks);
+    for (Instruction &I : *NewBB) {
+      PHINode *PN = dyn_cast<PHINode>(&I);
+      if (!PN)
+        break;
+      for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+        Instruction *V = dyn_cast<Instruction>(PN->getIncomingValue(i));
+        if (!V || !L->contains(V))
+          continue;
+
+        // We've found a value from L used in OuterL. Let's find a spot where
+        // we need to insert a phi node to preserve LCSSA form.
+        BasicBlock *IncomingBB = PN->getIncomingBlock(i);
+        for (BasicBlock *ExitBB : ExitBlocks) {
+          if (!DT->dominates(ExitBB, IncomingBB))
+            continue;
+
+          // We've found the exit block where we need to insert the phi-node.
+          // Create and start using it instead of previous def.
+          PHINode *NewPN = PHINode::Create(
+              PN->getType(), 1, V->getName() + ".lcssa", &ExitBB->front());
+          for (BasicBlock *PredBB : predecessors(ExitBB))
+            NewPN->addIncoming(V, PredBB);
+          PN->setIncomingValue(i, NewPN);
+          break;
+        }
+      }
+    }
+  }
+
   return NewOuter;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21665.61735.patch
Type: text/x-patch
Size: 2496 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160623/30a32ae9/attachment.bin>


More information about the llvm-commits mailing list