Index: include/llvm/IR/DebugInfoMetadata.h =================================================================== --- include/llvm/IR/DebugInfoMetadata.h +++ include/llvm/IR/DebugInfoMetadata.h @@ -1415,17 +1415,17 @@ /// 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. + /// 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. If no \p Inst is provided, we + /// assume it is not a call instruction. /// /// 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. - static const DILocation *getMergedLocation(const DILocation *LocA, - const DILocation *LocB) { - if (LocA && LocB && (LocA == LocB || !LocA->canDiscriminate(*LocB))) - return LocA; - return nullptr; - } + static const DILocation *getMergedLocation( + const DILocation *LocA, const DILocation *LocB, + const Instruction *Inst = nullptr); /// Returns the base discriminator for a given encoded discriminator \p D. static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) { Index: lib/IR/DebugInfo.cpp =================================================================== --- lib/IR/DebugInfo.cpp +++ lib/IR/DebugInfo.cpp @@ -669,3 +669,22 @@ return Val->getZExtValue(); return 0; } + +const llvm::DILocation *DILocation::getMergedLocation( + const DILocation *LocA, const DILocation *LocB, const Instruction *Inst) { + if (LocA && LocB && (LocA == LocB || !LocA->canDiscriminate(*LocB))) + return LocA; + if (!LocA || !LocB || !Inst || !isa(Inst)) + return nullptr; + SmallPtrSet InlinedLocationsA; + for (DILocation *L = LocA->getInlinedAt(); L; L = L->getInlinedAt()) + InlinedLocationsA.insert(L); + const DILocation *Result = LocB; + for (DILocation *L = LocB->getInlinedAt(); L; L = L->getInlinedAt()) { + Result = L; + if (InlinedLocationsA.count(L)) + break; + } + return DILocation::get(Result->getContext(), 0, 0, Result->getScope(), + Result->getInlinedAt()); +} Index: lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- lib/Transforms/Utils/SimplifyCFG.cpp +++ lib/Transforms/Utils/SimplifyCFG.cpp @@ -1279,9 +1279,8 @@ // I1 and I2 are being combined into a single instruction. Its debug // location is the merged locations of the original instructions. - if (!isa(I1)) - I1->setDebugLoc( - DILocation::getMergedLocation(I1->getDebugLoc(), I2->getDebugLoc())); + I1->setDebugLoc( + DILocation::getMergedLocation(I1->getDebugLoc(), I2->getDebugLoc(), I1)); I2->eraseFromParent(); Changed = true; Index: test/Transforms/SimplifyCFG/remove-debug.ll =================================================================== --- test/Transforms/SimplifyCFG/remove-debug.ll +++ test/Transforms/SimplifyCFG/remove-debug.ll @@ -4,12 +4,15 @@ ; DebugLoc is supported (https://reviews.llvm.org/D24180) ; CHECK: line: 6 ; CHECK-NOT: line: 7 -; CHECK: line: 8 -; CHECK: line: 9 +; CHECK-NOT: line: 8 +; CHECK-NOT: line: 9 ; CHECK-NOT: line: 10 -; CHECK: line: 11 +; CHECK-NOT: line: 11 +; CHECK: line: 0 +; CHECK: line: 12 -; Checks if the debug info for hoisted "x = i" is removed +; Checks if the debug info for hoisted "x = i" is removed and +; the debug info for hoisted "bar()" is set as line 0 ; int x; ; void bar(); ; void baz(); @@ -20,6 +23,7 @@ ; bar(); ; } else { ; x = i; +; bar(); ; baz(); ; } ; } @@ -45,7 +49,8 @@ ;