Index: llvm/trunk/include/llvm/IR/DebugInfoMetadata.h =================================================================== --- llvm/trunk/include/llvm/IR/DebugInfoMetadata.h +++ llvm/trunk/include/llvm/IR/DebugInfoMetadata.h @@ -1497,26 +1497,25 @@ /// discriminator. inline const DILocation *cloneWithDuplicationFactor(unsigned DF) const; + enum { NoGeneratedLocation = false, WithGeneratedLocation = true }; + /// When two instructions are combined into a single instruction we also /// need to combine the original locations into a single location. /// /// When the locations are the same we can use either location. When they - /// differ, we need a third location which is distinct from either. If - /// they have the same file/line but have a different discriminator we - /// could create a location with a new discriminator. If they are from - /// different files/lines the location is ambiguous and can't be - /// represented in a single line entry. In this case, no location - /// should be set, unless the merged instruction is a call, which we will - /// set the merged debug location as line 0 of the nearest common scope - /// where 2 locations are inlined from. This only applies to Instruction; - /// for MachineInstruction, as it is post-inline, we will treat the call - /// instruction the same way as other instructions. + /// differ, we need a third location which is distinct from either. If they + /// have the same file/line but have a different discriminator we could + /// create a location with a new discriminator. If they are from different + /// files/lines the location is ambiguous and can't be represented in a line + /// entry. In this case, if \p GenerateLocation is true, we will set the + /// merged debug location as line 0 of the nearest common scope where the two + /// locations are inlined from. /// - /// \p ForInst: The Instruction the merged DILocation is for. If the - /// Instruction is unavailable or non-existent, use nullptr. + /// \p GenerateLocation: Whether the merged location can be generated when + /// \p LocA and \p LocB differ. static const DILocation * getMergedLocation(const DILocation *LocA, const DILocation *LocB, - const Instruction *ForInst = nullptr); + bool GenerateLocation = NoGeneratedLocation); /// Returns the base discriminator for a given encoded discriminator \p D. static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) { Index: llvm/trunk/lib/IR/DebugInfo.cpp =================================================================== --- llvm/trunk/lib/IR/DebugInfo.cpp +++ llvm/trunk/lib/IR/DebugInfo.cpp @@ -675,7 +675,8 @@ void Instruction::applyMergedLocation(const DILocation *LocA, const DILocation *LocB) { - setDebugLoc(DILocation::getMergedLocation(LocA, LocB, this)); + setDebugLoc(DILocation::getMergedLocation(LocA, LocB, + DILocation::WithGeneratedLocation)); } //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/IR/DebugInfoMetadata.cpp =================================================================== --- llvm/trunk/lib/IR/DebugInfoMetadata.cpp +++ llvm/trunk/lib/IR/DebugInfoMetadata.cpp @@ -68,16 +68,16 @@ Storage, Context.pImpl->DILocations); } -const DILocation * -DILocation::getMergedLocation(const DILocation *LocA, const DILocation *LocB, - const Instruction *ForInst) { +const DILocation *DILocation::getMergedLocation(const DILocation *LocA, + const DILocation *LocB, + bool GenerateLocation) { if (!LocA || !LocB) return nullptr; if (LocA == LocB || !LocA->canDiscriminate(*LocB)) return LocA; - if (!dyn_cast_or_null(ForInst)) + if (!GenerateLocation) return nullptr; SmallPtrSet InlinedLocationsA; Index: llvm/trunk/test/DebugInfo/Generic/instcombine-phi.ll =================================================================== --- llvm/trunk/test/DebugInfo/Generic/instcombine-phi.ll +++ llvm/trunk/test/DebugInfo/Generic/instcombine-phi.ll @@ -5,8 +5,8 @@ ; If all the operands to a phi node are of the same operation, instcombine ; will try to pull them through the phi node, combining them into a single -; operation. Check that when it does this the combined operation does not -; have a debug location set. +; operation. Check that when it does this the combined operation has a merged +; debug location. ; Test folding of a binary operation. Generated from source: @@ -24,8 +24,7 @@ ; CHECK: define i32 @binop ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ] -; CHECK: sub nsw i32 %b, %[[PHI]] -; CHECK-NOT: !dbg +; CHECK: sub nsw i32 %b, %[[PHI]], !dbg [[binopMergedLoc:![0-9]+]] ; CHECK: ret i32 define i32 @binop(i32 %a, i32 %b) !dbg !6 { @@ -66,8 +65,7 @@ ; CHECK: define i32 @cmp ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ] -; CHECK: icmp slt i32 %[[PHI]], %b -; CHECK-NOT: !dbg +; CHECK: icmp slt i32 %[[PHI]], %b, !dbg [[cmpMergedLoc:![0-9]+]] ; CHECK: ret i32 define i32 @cmp(i32 %a, i32 %b) !dbg !15 { @@ -108,8 +106,7 @@ ; CHECK: define i32* @gep ; 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: getelementptr inbounds i32, i32* %b, i64 %[[PHI]], !dbg [[gepMergedLoc:![0-9]+]] ; CHECK: ret i32* define i32* @gep(i32 %a, i32* %b) !dbg !23 { @@ -149,8 +146,7 @@ ; CHECK: define i32 @load ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32* [ %call, %if.then ], [ %call1, %if.else ] -; CHECK: load i32, i32* %[[PHI]] -; CHECK-NOT: !dbg +; CHECK: load i32, i32* %[[PHI]],{{.*}} !dbg [[loadMergedLoc:![0-9]+]] ; CHECK: ret i32 define i32 @load(i32 %a) !dbg !31 { @@ -190,8 +186,7 @@ ; CHECK: define i64 @cast ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ] -; CHECK: sext i32 %[[PHI]] to i64 -; CHECK-NOT: !dbg +; CHECK: sext i32 %[[PHI]] to i64, !dbg [[castMergedLoc:![0-9]+]] ; CHECK: ret i64 define i64 @cast(i32 %a) !dbg !39 { @@ -231,8 +226,7 @@ ; CHECK: define i32 @binop_const ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ] -; CHECK: add nsw i32 %[[PHI]], -5 -; CHECK-NOT: !dbg +; CHECK: add nsw i32 %[[PHI]], -5, !dbg [[binopConstMergedLoc:![0-9]+]] ; CHECK: ret i32 define i32 @binop_const(i32 %a) !dbg !45 { @@ -273,8 +267,7 @@ ; CHECK: define i32 @cmp_const ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call, %if.then ], [ %call1, %if.else ] -; CHECK: icmp slt i32 %[[PHI]], 10 -; CHECK-NOT: !dbg +; CHECK: icmp slt i32 %[[PHI]], 10, !dbg [[cmpConstMergedLoc:![0-9]+]] ; CHECK: ret i32 define i32 @cmp_const(i32 %a) !dbg !53 { @@ -305,6 +298,14 @@ declare i32* @foo3() declare i32* @bar3() +; CHECK: [[binopMergedLoc]] = !DILocation(line: 0 +; CHECK: [[cmpMergedLoc]] = !DILocation(line: 0 +; CHECK: [[gepMergedLoc]] = !DILocation(line: 0 +; CHECK: [[loadMergedLoc]] = !DILocation(line: 0 +; CHECK: [[castMergedLoc]] = !DILocation(line: 0 +; CHECK: [[binopConstMergedLoc]] = !DILocation(line: 0 +; CHECK: [[cmpConstMergedLoc]] = !DILocation(line: 0 + !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4} Index: llvm/trunk/test/DebugInfo/Generic/simplifycfg_sink_last_inst.ll =================================================================== --- llvm/trunk/test/DebugInfo/Generic/simplifycfg_sink_last_inst.ll +++ llvm/trunk/test/DebugInfo/Generic/simplifycfg_sink_last_inst.ll @@ -6,7 +6,8 @@ ; Simplify CFG will try to sink the last instruction in a series of basic ; blocks, creating a "common" instruction in the successor block. If the ; debug locations of the commoned instructions have different file/line -; numbers the debug location of the common instruction should not be set. +; numbers the debug location of the common instruction should be a merged +; location. ; Generated from source: @@ -24,8 +25,7 @@ ; CHECK: define i32 @test ; CHECK-LABEL: if.end: ; CHECK: %[[PHI:.*]] = phi i32 [ %call1, %if.else ], [ %call, %if.then ] -; CHECK: sub nsw i32 %b, %[[PHI]] -; CHECK-NOT: !dbg +; CHECK: sub nsw i32 %b, %[[PHI]], !dbg [[testMergedLoc:![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 [[test2Loc:![0-9]+]] ; CHECK: ret i32 -; CHECK: ![[DBG]] = !DILocation(line: 17, scope: !{{.*}}) define i32 @test2(i32 %a, i32 %b) !dbg !15 { entry: @@ -85,6 +84,9 @@ ret i32 %b.addr.0, !dbg !17 } +; CHECK: [[testMergedLoc]] = !DILocation(line: 0 +; CHECK: [[test2Loc]] = !DILocation(line: 17 + declare i32 @foo() declare i32 @bar() Index: llvm/trunk/test/DebugInfo/Generic/store-tail-merge.ll =================================================================== --- llvm/trunk/test/DebugInfo/Generic/store-tail-merge.ll +++ llvm/trunk/test/DebugInfo/Generic/store-tail-merge.ll @@ -21,8 +21,10 @@ ; CHECK: define {{.*}}@foo ; 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{{$}} +; +; The debug location on the store should be a line-0 location. +; CHECK-NEXT: store i32 %storemerge{{.*}}, align 4, !dbg [[storeLoc:![0-9]+]] +; CHECK: [[storeLoc]] = !DILocation(line: 0 ; ; ModuleID = 'test1.ll' source_filename = "test.c" Index: llvm/trunk/test/Transforms/SimplifyCFG/remove-debug-2.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/remove-debug-2.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/remove-debug-2.ll @@ -1,6 +1,7 @@ ; RUN: opt < %s -simplifycfg -S | FileCheck %s -; Check if the debug info for hoisted store for "ret = 0" is removed +; Check that the debug location for the hoisted store for "ret = 0" is a +; line-0 location. ; ; int foo(int x) { ; int ret = 1; @@ -12,12 +13,11 @@ ; CHECK: store i32 1,{{.+}}!dbg ![[DLOC1:[0-9]+]] ; CHECK: icmp ne {{.+}}!dbg ![[DLOC2:[0-9]+]] ; CHECK: [[VREG:%[^ ]+]] = select -; CHECK: store i32 [[VREG]] -; CHECK-NOT: !dbg -; CHECK-SAME: {{$}} +; CHECK: store i32 [[VREG]],{{.*}} !dbg [[storeLoc:![0-9]+]] ; CHECK: ret {{.+}}!dbg ![[DLOC3:[0-9]+]] ; CHECK: ![[DLOC1]] = !DILocation(line: 2 ; CHECK: ![[DLOC2]] = !DILocation(line: 3 +; CHECK: [[storeLoc]] = !DILocation(line: 0 ; CHECK: ![[DLOC3]] = !DILocation(line: 5 target triple = "x86_64-unknown-linux-gnu" Index: llvm/trunk/test/Transforms/SimplifyCFG/remove-debug.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/remove-debug.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/remove-debug.ll @@ -26,9 +26,9 @@ ; Function Attrs: uwtable define void @_Z3fooi(i32) #0 !dbg !6 { -; CHECK: load i32, i32* %2, align 4, !tbaa -; CHECK: store i32 %5, i32* @x, align 4, !tbaa -; CHECK: call void @_Z3barv(), !dbg ![[BAR:[0-9]+]] +; CHECK: load i32, i32* %2, align 4, !dbg ![[LOAD:[0-9]+]], !tbaa +; CHECK: store i32 %5, i32* @x, align 4, !dbg ![[BAR:[0-9]+]], !tbaa +; CHECK: call void @_Z3barv(), !dbg ![[BAR]] ; CHECK: call void @_Z3bazv(), !dbg ![[BAZ:[0-9]+]] %2 = alloca i32, align 4 store i32 %0, i32* %2, align 4, !tbaa !8 @@ -60,6 +60,7 @@ !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4} +; CHECK: ![[LOAD]] = !DILocation(line: 6, column: 7 ; CHECK: ![[BAR]] = !DILocation(line: 0 ; CHECK: ![[BAZ]] = !DILocation(line: 12, column: 5 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1)