Index: llvm/lib/Transforms/Utils/BasicBlockUtils.cpp =================================================================== --- llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -579,24 +579,33 @@ // The new block unconditionally branches to the old block. BranchInst *BI = BranchInst::Create(BB, NewBB); + bool IsBBHeader = LI && LI->isLoopHeader(BB); + Loop *BBLoop = LI ? LI->getLoopFor(BB) : nullptr; // Splitting the predecessors of a loop header creates a preheader block. - if (LI && LI->isLoopHeader(BB)) + if (IsBBHeader) // Using the loop start line number prevents debuggers stepping into the // loop body for this instruction. - BI->setDebugLoc(LI->getLoopFor(BB)->getStartLoc()); + BI->setDebugLoc(BBLoop->getStartLoc()); else BI->setDebugLoc(BB->getFirstNonPHIOrDbg()->getDebugLoc()); // Move the edges from Preds to point to NewBB instead of BB. - for (unsigned i = 0, e = Preds.size(); i != e; ++i) { + for (BasicBlock *Pred : Preds) { + Instruction *PI = Pred->getTerminator(); // This is slightly more strict than necessary; the minimum requirement // is that there be no more than one indirectbr branching to BB. And // all BlockAddress uses would need to be updated. - assert(!isa(Preds[i]->getTerminator()) && + assert(!isa(PI) && "Cannot split an edge from an IndirectBrInst"); - assert(!isa(Preds[i]->getTerminator()) && - "Cannot split an edge from a CallBrInst"); - Preds[i]->getTerminator()->replaceUsesOfWith(BB, NewBB); + assert(!isa(PI) && "Cannot split an edge from a CallBrInst"); + if (IsBBHeader && BBLoop->contains(Pred) && BBLoop->isLoopLatch(Pred)) { + // Update loop metadata if it exists. + if (MDNode *LoopMD = PI->getMetadata(LLVMContext::MD_loop)) { + BI->setMetadata(LLVMContext::MD_loop, LoopMD); + PI->setMetadata(LLVMContext::MD_loop, nullptr); + } + } + PI->replaceUsesOfWith(BB, NewBB); } // Insert a new PHI node into NewBB for every PHI node in BB and that new PHI Index: llvm/test/Transforms/LoopSimplify/loop_metadata.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopSimplify/loop_metadata.ll @@ -0,0 +1,36 @@ +; RUN: opt -S -loop-simplify < %s | FileCheck %s + +; CHECK: for.cond.loopexit: +; CHECK: br label %for.cond, !llvm.loop !0 +; CHECK: br i1 %cmp1, label %for.body1, label %for.cond.loopexit + +define void @foo() { +entry: + br label %for.cond + +for.cond: ; preds = %for.cond1, %entry + %j = phi i32 [ 0, %entry ], [ %add, %for.cond1 ] + %cmp = icmp ult i32 %j, 8 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %dummy1 = add i32 1, 1 + %add = add nuw nsw i32 %j, 1 + br label %for.cond1 + +for.cond1: ; preds = %for.body1, %for.body + %i.0 = phi i32 [ 1, %for.body ], [ %inc, %for.body1 ] + %cmp1 = icmp ult i32 %i.0, 8 + br i1 %cmp1, label %for.body1, label %for.cond, !llvm.loop !0 + +for.body1: ; preds = %for.cond1 + %dummy2 = add i32 1, 1 + %inc = add nuw nsw i32 %i.0, 1 + br label %for.cond1 + +for.end: ; preds = %for.cond + ret void +} + +!0 = distinct !{!0, !1} +!1 = !{!"llvm.loop.unroll.full"}