diff --git a/llvm/lib/Transforms/Utils/LoopSimplify.cpp b/llvm/lib/Transforms/Utils/LoopSimplify.cpp --- a/llvm/lib/Transforms/Utils/LoopSimplify.cpp +++ b/llvm/lib/Transforms/Utils/LoopSimplify.cpp @@ -333,6 +333,26 @@ // process of separating the outer one. formDedicatedExitBlocks(L, DT, LI, MSSAU, PreserveLCSSA); + // Create new metadata ID for NewOuter loop + // keep other metadata attched before + BasicBlock *LatchBlock = NewOuter->getLoopLatch(); + if (LatchBlock) { + unsigned LoopMDKind = LatchBlock->getContext().getMDKindID("llvm.loop"); + Instruction *TI = LatchBlock->getTerminator(); + if (TI) { + MDNode *LoopMD = TI->getMetadata(LoopMDKind); + if (LoopMD) { + // Save space for the self-referential LoopID. + SmallVector MDs = {nullptr}; + for (unsigned i = 1; i < LoopMD->getNumOperands(); ++i) + MDs.push_back(LoopMD->getOperand(i)); + MDNode *NewLoopID = MDNode::getDistinct(LoopMD->getContext(), MDs); + NewLoopID->replaceOperandWith(0, NewLoopID); + TI->setMetadata(LoopMDKind, NewLoopID); + } + } + } + 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 diff --git a/llvm/test/Transforms/LoopSimplify/update_separate_loop_metadata.ll b/llvm/test/Transforms/LoopSimplify/update_separate_loop_metadata.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/LoopSimplify/update_separate_loop_metadata.ll @@ -0,0 +1,47 @@ +; Tests loop-simplify updates the newly created outter loop metadata with +; a new loop id and keeps other MDNode as before. + +; RUN: opt < %s -passes=loop-simplify -S | FileCheck %s +; CHECK-LABEL: while.body.thread: +; CHECK: br label %while.cond, !llvm.loop !5 +; CHECK-LABEL: while.body: +; CHECK: br label %while.cond.outer, !llvm.loop !7 + +define i16 @foo() { +entry: + br label %while.cond + +while.cond: ; preds = %while.body.thread, %while.body, %entry + %i.0 = phi i16 [ 0, %entry ], [ %inc4, %while.body.thread ], [ %inc, %while.body ] + %j.0 = phi i16 [ 0, %entry ], [ %j.0, %while.body.thread ], [ %spec.select7, %while.body ] + %cmp = icmp slt i16 %i.0, 10 + br i1 %cmp, label %while.body.thread, label %lor.end + +while.body.thread: ; preds = %while.cond + %inc4 = add nsw i16 %i.0, 1 + br label %while.cond, !llvm.loop !5 + +lor.end: ; preds = %while.cond + %cmp1.not = icmp eq i16 %j.0, 5 + br i1 %cmp1.not, label %while.end, label %while.body + +while.body: ; preds = %lor.end + %inc = add nuw nsw i16 %i.0, 1 + %cmp2 = icmp eq i16 %inc, 12 + %spec.select7 = select i1 %cmp2, i16 5, i16 %j.0 + br label %while.cond, !llvm.loop !5 + +while.end: ; preds = %lor.end + ret i16 %i.0 +} + +!llvm.module.flags = !{!0, !1, !2, !3} +!llvm.ident = !{!4} + +!0 = !{i32 7, !"Dwarf Version", i32 4} +!1 = !{i32 2, !"Debug Info Version", i32 3} +!2 = !{i32 1, !"wchar_size", i32 1} +!3 = !{i32 7, !"frame-pointer", i32 2} +!4 = !{!"clang version 16.0.0.prerel"} +!5 = distinct !{!5, !6} +!6 = !{!"llvm.loop.usefulinfo"} ; MDString used to represent any metadata \ No newline at end of file