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 ExitBlocks; + L->getExitBlocks(ExitBlocks); + for (Instruction &I : *NewBB) { + PHINode *PN = dyn_cast(&I); + if (!PN) + break; + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + Instruction *V = dyn_cast(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; } 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 +}