Index: include/llvm/IR/DebugInfoMetadata.h =================================================================== --- include/llvm/IR/DebugInfoMetadata.h +++ include/llvm/IR/DebugInfoMetadata.h @@ -1369,14 +1369,30 @@ /// represented in a single line entry. In this case, no location /// should be set. /// - /// Currently the function does not create a new location. If the locations - /// are the same, or cannot be discriminated, the first location is returned. - /// Otherwise an empty location will be used. + /// Currently the function does not create a new 'valid' location. If the + /// locations are the same, or cannot be discriminated, the first location is + /// returned. Otherwise a dummy location of (line: 0, column: 0) is returned + /// with a scope of LocA, considering inlining context. static const DILocation *getMergedLocation(const DILocation *LocA, const DILocation *LocB) { - if (LocA && LocB && (LocA == LocB || !LocA->canDiscriminate(*LocB))) + if (!LocA || !LocB) + return nullptr; + + if (LocA == LocB || !LocA->canDiscriminate(*LocB)) return LocA; - return nullptr; + + // If the locations can be discriminated, returns a dummy location. + while (auto *InlinedLoc = LocA->getInlinedAt()) + LocA = InlinedLoc; + while (auto *InlinedLoc = LocB->getInlinedAt()) + LocB = InlinedLoc; + assert(LocA->getScope()->getSubprogram() == + LocB->getScope()->getSubprogram() && + "Cannot merge debug locations in different subprograms."); + assert(&LocA->getContext() == &LocB->getContext() && + "Cannot merge debug locations in different contexts."); + + return DILocation::get(LocA->getContext(), 0, 0, LocA->getScope()); } Metadata *getRawScope() const { return getOperand(0); } Index: test/DebugInfo/Generic/instcombine-phi.ll =================================================================== --- test/DebugInfo/Generic/instcombine-phi.ll +++ test/DebugInfo/Generic/instcombine-phi.ll @@ -25,7 +25,7 @@ ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ] ; CHECK: sub nsw i32 %b, %[[PHI]] -; CHECK-NOT: !dbg +; CHECK: !dbg [[DBG1:![0-9]+]] ; CHECK: ret i32 define i32 @binop(i32 %a, i32 %b) !dbg !6 { @@ -67,7 +67,7 @@ ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ] ; CHECK: icmp slt i32 %[[PHI]], %b -; CHECK-NOT: !dbg +; CHECK: !dbg [[DBG2:![0-9]+]] ; CHECK: ret i32 define i32 @cmp(i32 %a, i32 %b) !dbg !15 { @@ -109,7 +109,7 @@ ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i64 [ %call, %if.then ], [ %call1, %if.else ] ; CHECK: getelementptr inbounds i32, i32* %b, i64 %[[PHI]] -; CHECK-NOT: !dbg +; CHECK: !dbg [[DBG3:![0-9]+]] ; CHECK: ret i32* define i32* @gep(i32 %a, i32* %b) !dbg !23 { @@ -150,7 +150,7 @@ ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32* [ %call, %if.then ], [ %call1, %if.else ] ; CHECK: load i32, i32* %[[PHI]] -; CHECK-NOT: !dbg +; CHECK: !dbg [[DBG4:![0-9]+]] ; CHECK: ret i32 define i32 @load(i32 %a) !dbg !31 { @@ -191,7 +191,7 @@ ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ] ; CHECK: sext i32 %[[PHI]] to i64 -; CHECK-NOT: !dbg +; CHECK: !dbg [[DBG5:![0-9]+]] ; CHECK: ret i64 define i64 @cast(i32 %a) !dbg !39 { @@ -232,7 +232,7 @@ ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ] ; CHECK: add nsw i32 %[[PHI]], -5 -; CHECK-NOT: !dbg +; CHECK: !dbg [[DBG6:![0-9]+]] ; CHECK: ret i32 define i32 @binop_const(i32 %a) !dbg !45 { @@ -274,7 +274,7 @@ ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ] ; CHECK: icmp slt i32 %[[PHI]], 10 -; CHECK-NOT: !dbg +; CHECK: !dbg [[DBG7:![0-9]+]] ; CHECK: ret i32 define i32 @cmp_const(i32 %a) !dbg !53 { @@ -308,6 +308,21 @@ !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4} +; CHECK: [[BINOP:![0-9]+]] = distinct !DISubprogram(name: "binop"{{.+}}) +; CHECK: [[DBG1]] = !DILocation(line: 0, scope: [[BINOP]]) +; CHECK: [[CMP:![0-9]+]] = distinct !DISubprogram(name: "cmp"{{.+}}) +; CHECK: [[DBG2]] = !DILocation(line: 0, scope: [[CMP]]) +; CHECK: [[GEP:![0-9]+]] = distinct !DISubprogram(name: "gep"{{.+}}) +; CHECK: [[DBG3]] = !DILocation(line: 0, scope: [[GEP]]) +; CHECK: [[LOAD:![0-9]+]] = distinct !DISubprogram(name: "load"{{.+}}) +; CHECK: [[DBG4]] = !DILocation(line: 0, scope: [[LOAD]]) +; CHECK: [[CAST:![0-9]+]] = distinct !DISubprogram(name: "cast"{{.+}}) +; CHECK: [[DBG5]] = !DILocation(line: 0, scope: [[CAST]]) +; CHECK: [[BINOP_CONST:![0-9]+]] = distinct !DISubprogram(name: "binop_const"{{.+}}) +; CHECK: [[DBG6]] = !DILocation(line: 0, scope: [[BINOP_CONST]]) +; CHECK: [[CMP_CONST:![0-9]+]] = distinct !DISubprogram(name: "cmp_const"{{.+}}) +; CHECK: [[DBG7]] = !DILocation(line: 0, scope: [[CMP_CONST]]) + !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2) !1 = !DIFile(filename: "test.c", directory: "") !2 = !{} Index: test/DebugInfo/Generic/simplifycfg_sink_last_inst.ll =================================================================== --- test/DebugInfo/Generic/simplifycfg_sink_last_inst.ll +++ test/DebugInfo/Generic/simplifycfg_sink_last_inst.ll @@ -25,7 +25,7 @@ ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call1, %if.else ], [ %call, %if.then ] ; CHECK: sub nsw i32 %b, %[[PHI]] -; CHECK-NOT: !dbg +; CHECK: !dbg [[DBG1:![0-9]+]] ; CHECK: ret i32 define i32 @test(i32 %a, i32 %b) !dbg !6 { @@ -61,9 +61,8 @@ ; CHECK: define i32 @test2 ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call1, %if.else ], [ %call, %if.then ] -; CHECK: sub nsw i32 %b, %[[PHI]], !dbg ![[DBG:.*]] +; CHECK: sub nsw i32 %b, %[[PHI]], !dbg ![[DBG2:.*]] ; CHECK: ret i32 -; CHECK: ![[DBG]] = !DILocation(line: 17, scope: !{{.*}}) define i32 @test2(i32 %a, i32 %b) !dbg !15 { entry: @@ -91,6 +90,10 @@ !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4} +; CHECK: [[TEST:![0-9]+]] = distinct !DISubprogram(name: "test"{{.+}}) +; CHECK: [[DBG1]] = !DILocation(line: 0, scope: [[TEST]]) +; CHECK: ![[DBG2]] = !DILocation(line: 17, scope: !{{.*}}) + !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2) !1 = !DIFile(filename: "test.c", directory: "") !2 = !{} Index: test/DebugInfo/Generic/store-tail-merge.ll =================================================================== --- test/DebugInfo/Generic/store-tail-merge.ll +++ test/DebugInfo/Generic/store-tail-merge.ll @@ -22,7 +22,8 @@ ; CHECK: if.end: ; CHECK-NEXT: %storemerge = phi ; This final check is the "real" test, verify no !dbg on the store. -; CHECK-NEXT: store i32 %storemerge{{.*}}, align 4{{$}} +; CHECK-NEXT: store i32 %storemerge{{.*}}, align 4 +; CHECK: !dbg [[DBG:![0-9]+]] ; ; ModuleID = 'test1.ll' source_filename = "test.c" @@ -56,6 +57,9 @@ !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4} +; CHECK: [[FOO:![0-9]+]] = distinct !DISubprogram(name: "foo"{{.+}}) +; CHECK: [[DBG]] = !DILocation(line: 0, scope: [[FOO]]) + !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2) !1 = !DIFile(filename: "test.c", directory: "/home/probinson/projects/scratch") !2 = !{} Index: test/Transforms/SimplifyCFG/remove-debug-2.ll =================================================================== --- test/Transforms/SimplifyCFG/remove-debug-2.ll +++ test/Transforms/SimplifyCFG/remove-debug-2.ll @@ -13,12 +13,13 @@ ; CHECK: icmp ne {{.+}}!dbg ![[DLOC2:[0-9]+]] ; CHECK: [[VREG:%[^ ]+]] = select ; CHECK: store i32 [[VREG]] -; CHECK-NOT: !dbg -; CHECK-SAME: {{$}} -; CHECK: ret {{.+}}!dbg ![[DLOC3:[0-9]+]] -; CHECK: ![[DLOC1]] = !DILocation(line: 2 -; CHECK: ![[DLOC2]] = !DILocation(line: 3 -; CHECK: ![[DLOC3]] = !DILocation(line: 5 +; CHECK-SAME: !dbg ![[DLOC3:[0-9]+]] +; CHECK: ret {{.+}}!dbg ![[DLOC4:[0-9]+]] +; CHECK-DAG: [[FOO:![0-9]+]] = distinct !DISubprogram(name: "foo"{{.+}}) +; CHECK-DAG: ![[DLOC1]] = !DILocation(line: 2 +; CHECK-DAG: ![[DLOC2]] = !DILocation(line: 3 +; CHECK-DAG: ![[DLOC3]] = !DILocation(line: 0, scope: [[FOO]]) +; CHECK-DAG: ![[DLOC4]] = !DILocation(line: 5 target triple = "x86_64-unknown-linux-gnu"