Index: llvm/trunk/lib/IR/DebugInfo.cpp =================================================================== --- llvm/trunk/lib/IR/DebugInfo.cpp +++ llvm/trunk/lib/IR/DebugInfo.cpp @@ -241,26 +241,29 @@ static llvm::MDNode *stripDebugLocFromLoopID(llvm::MDNode *N) { assert(N->op_begin() != N->op_end() && "Missing self reference?"); - auto DebugLocOp = - std::find_if(N->op_begin() + 1, N->op_end(), [](const MDOperand &Op) { - return isa(Op.get()); - }); - // No debug location, we do not have to rewrite this MDNode. - if (DebugLocOp == N->op_end()) + // if there is no debug location, we do not have to rewrite this MDNode. + if (std::none_of(N->op_begin() + 1, N->op_end(), [](const MDOperand &Op) { + return isa(Op.get()); + })) return N; - // There is only the debug location without any actual loop metadata, hence we + // If there is only the debug location without any actual loop metadata, we // can remove the metadata. - if (N->getNumOperands() == 2) + if (std::none_of(N->op_begin() + 1, N->op_end(), [](const MDOperand &Op) { + return !isa(Op.get()); + })) return nullptr; SmallVector Args; // Reserve operand 0 for loop id self reference. auto TempNode = MDNode::getTemporary(N->getContext(), None); Args.push_back(TempNode.get()); - Args.append(N->op_begin() + 1, DebugLocOp); - Args.append(DebugLocOp + 1, N->op_end()); + // Add all non-debug location operands back. + for (auto Op = N->op_begin() + 1; Op != N->op_end(); Op++) { + if (!isa(*Op)) + Args.push_back(*Op); + } // Set the first operand to itself. MDNode *LoopID = MDNode::get(N->getContext(), Args); Index: llvm/trunk/test/DebugInfo/strip-loop-metadata.ll =================================================================== --- llvm/trunk/test/DebugInfo/strip-loop-metadata.ll +++ llvm/trunk/test/DebugInfo/strip-loop-metadata.ll @@ -33,6 +33,34 @@ ret void, !dbg !21 } +; CHECK-LABEL: _Z5test3v +; CHECK: br {{.*}} !llvm.loop [[LOOP2:![0-9]+]] +define void @_Z5test3v() !dbg !22 { +entry: + br label %while.body, !dbg !23 + +while.body: + call void @_Z3barv(), !dbg !24 + br label %while.body, !dbg !25, !llvm.loop !26 + +return: + ret void, !dbg !28 +} + +; CHECK-LABEL: _Z5test4v +; CHECK-NOT: br {{.*}} !llvm.loop +define void @_Z5test4v() !dbg !30 { +entry: + br label %while.body, !dbg !31 + +while.body: + call void @_Z3barv(), !dbg !32 + br label %while.body, !dbg !33, !llvm.loop !34 + +return: + ret void, !dbg !36 +} + !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4, !5} !llvm.ident = !{!6} @@ -59,6 +87,21 @@ !19 = distinct !{!19, !16, !20} !20 = !{!"llvm.loop.unroll.enable"} !21 = !DILocation(line: 12, column: 1, scope: !15) +!22 = distinct !DISubprogram(name: "test3", scope: !1, file: !1, line: 8, type: !8, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!23 = !DILocation(line: 8, column: 14, scope: !22) +!24 = !DILocation(line: 11, column: 5, scope: !22) +!25 = !DILocation(line: 10, column: 3, scope: !22) +!26 = distinct !{!26, !23, !29, !27} +!27 = !{!"llvm.loop.unroll.enable"} +!28 = !DILocation(line: 12, column: 1, scope: !22) +!29 = !DILocation(line: 12, column: 1, scope: !22) +!30 = distinct !DISubprogram(name: "test4", scope: !1, file: !1, line: 8, type: !8, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!31 = !DILocation(line: 8, column: 14, scope: !30) +!32 = !DILocation(line: 11, column: 5, scope: !30) +!33 = !DILocation(line: 10, column: 3, scope: !30) +!34 = distinct !{!34, !31, !35} +!35 = !DILocation(line: 12, column: 1, scope: !30) +!36 = !DILocation(line: 12, column: 1, scope: !30) ; CHECK-NOT: !DICompileUnit ; CHECK-NOT: !DIFile @@ -68,4 +111,5 @@ ; CHECK-NOT: !DILexicalBlockFile ; CHECK: [[LOOP]] = distinct !{[[LOOP]], [[LOOP_UNROLL:![0-9]+]]} ; CHECK-NEXT: [[LOOP_UNROLL]] = !{!"llvm.loop.unroll.enable"} +; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[LOOP_UNROLL]]} ; CHECK-NOT: !DILocation