Skip to content

Commit 820ebe3

Browse files
committed
[DebugInfo] Emit distinct DILocation for different inline instances
LLVM seems to determine a variable instance as a combination of DILocalVariable and DILocation. Therefore if multiple llvm.dbg.declare have the same variable/location parameters, they are considered to be referencing the same instance of variable. Swift IRGen emits a set of llvm.dbg.declare calls for every variable instance (with unique SILDebugScope), so it is important that these calls have distinct variable/location parameters. Otherwise their DIExpression may be incorrect when treated as referencing the same variable. For example, if they have a DIExpression with fragments, we will see this as multiple declarations of the same fragment. LLVM detects this and crashes with assertion failure: DwarfExpression.cpp:679: void llvm::DwarfExpression::addFragmentOffset(const llvm::DIExpression *): Assertion `FragmentOffset >= OffsetInBits && "overlapping or duplicate fragments"' failed. The patch resolves #55703. The LIT test (debug_scope_distinct.swift) is the reproducer from that issue.
1 parent 816f606 commit 820ebe3

File tree

4 files changed

+13
-9
lines changed

4 files changed

+13
-9
lines changed

lib/IRGen/IRGenDebugInfo.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
414414
// Pretend transparent functions don't exist.
415415
if (!Scope)
416416
return createInlinedAt(CS);
417-
auto InlinedAt = llvm::DILocation::get(
417+
auto InlinedAt = llvm::DILocation::getDistinct(
418418
IGM.getLLVMContext(), L.line, L.column, Scope, createInlinedAt(CS));
419419
InlinedAtCache.insert({CS, llvm::TrackingMDNodeRef(InlinedAt)});
420420
return InlinedAt;

test/DebugInfo/inlinedAt.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ public func f(_ i : Int) -> Int { // 301
4040
// CHECK: ![[F:.*]] = distinct !DISubprogram(name: "f",
4141
// CHECK: ![[G:.*]] = distinct !DISubprogram(name: "g",
4242

43-
// CHECK: ![[L3:.*]] = !DILocation(line: 302, column: 10,
44-
// CHECK-SAME: scope: ![[F:.*]])
43+
// CHECK: ![[L3:.*]] = distinct !DILocation(line: 302, column: 10,
44+
// CHECK-SAME: scope: ![[F:.*]])
4545
// CHECK: ![[H:.*]] = distinct !DISubprogram(name: "h",
4646
// CHECK: ![[L1]] = !DILocation(line: 101, column: 8, scope: ![[H]],
4747
// CHECK-SAME: inlinedAt: ![[L2:.*]])
48-
// CHECK: ![[L2]] = !DILocation(line: 203, column: 10, scope: ![[G]],
49-
// CHECK-SAME: inlinedAt: ![[L3]])
48+
// CHECK: ![[L2]] = distinct !DILocation(line: 203, column: 10, scope: ![[G]],
49+
// CHECK-SAME: inlinedAt: ![[L3]])
5050

test/DebugInfo/inlinescopes.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func transparent(_ x: Int64) -> Int64 { return noinline(x) }
2626
func inlined(_ x: Int64) -> Int64 {
2727
let result = transparent(x)
2828
// CHECK-DAG: ![[CALL]] = !DILocation(line: [[@LINE-1]], column: {{.*}}, scope: ![[INLINED1:.*]], inlinedAt: ![[INLINEDAT:.*]])
29-
// CHECK-DAG: ![[INLINEDAT]] = !DILocation({{.*}}scope: ![[INLINEDAT1:[0-9]+]]
29+
// CHECK-DAG: ![[INLINEDAT]] = distinct !DILocation({{.*}}scope: ![[INLINEDAT1:[0-9]+]]
3030
// CHECK-DAG: ![[INLINED1]] = distinct !DILexicalBlock(scope: ![[INLINED:[0-9]+]]
3131
// Check if the inlined and removed function still has the correct linkage name.
3232
// CHECK-DAG: ![[INLINED]] = distinct !DISubprogram(name: "inlined", linkageName: "$s4main7inlinedys5Int64VADF"

test/IRGen/debug_scope_distinct.swift

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swiftc_driver -DM -emit-module -emit-module-path %t/M.swiftmodule %s -module-name M
33
// RUN: %target-swiftc_driver -O -g -I %t -c %s -emit-ir -o - | %FileCheck %s
4+
// RUN: %target-swiftc_driver -O -g -I %t -c %s -o /dev/null
45

56
// CHECK: define {{.*}} void @"$s4main1TV4move2byyAC13TangentVectorV_tF"
67
// CHECK-SAME: ptr {{.*}} %[[ARG_PTR:.*]],
@@ -13,17 +14,20 @@
1314
//
1415
// CHECK: %[[ARG2_GEP:.*]] = getelementptr inbounds %T4main1TV13TangentVectorV, ptr %[[ARG_PTR]], i64 0, i32 2
1516
// CHECK: %[[ARG2:.*]] = load {{.*}} %[[ARG2_GEP]]
16-
// CHECK: call void @llvm.dbg.value(metadata {{.*}} %[[ARG2]], metadata ![[VAR1]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg ![[LOC1]]
17+
// CHECK: call void @llvm.dbg.value(metadata {{.*}} %[[ARG2]], metadata ![[VAR1]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg ![[LOC2:[0-9]+]]
1718
// CHECK: %[[ARG3_GEP:.*]] = getelementptr inbounds %T4main1TV13TangentVectorV, ptr %[[ARG_PTR]], i64 0, i32 2, i32 0, i32 1
1819
// CHECK: %[[ARG3:.*]] = load {{.*}} %[[ARG3_GEP]]
19-
// CHECK: call void @llvm.dbg.value(metadata {{.*}} %[[ARG3]], metadata ![[VAR1]], metadata !DIExpression(DW_OP_LLVM_fragment, 64, 8)), !dbg ![[LOC1]]
20+
// CHECK: call void @llvm.dbg.value(metadata {{.*}} %[[ARG3]], metadata ![[VAR1]], metadata !DIExpression(DW_OP_LLVM_fragment, 64, 8)), !dbg ![[LOC2]]
2021

2122
// CHECK-DAG: ![[VAR1]] = !DILocalVariable(name: "offset", arg: 1, scope: ![[SCOPE:[0-9]+]]
2223

2324
// CHECK-DAG: ![[LOC1]] = !DILocation(line: 0, scope: ![[SCOPE]], inlinedAt: ![[LOCINL1:[0-9]+]])
24-
// CHECK-DAG: ![[LOCINL1]] = !DILocation(line: 0, scope: ![[SUBPROG:[0-9]+]])
25+
// CHECK-DAG: ![[LOCINL1]] = distinct !DILocation(line: 0, scope: ![[SUBPROG:[0-9]+]])
2526
// CHECK-DAG: ![[SUBPROG]] = distinct !DISubprogram(name: "move", linkageName: "$s4main1TV4move2byyAC13TangentVectorV_tF"
2627

28+
// CHECK-DAG: ![[LOC2]] = !DILocation(line: 0, scope: ![[SCOPE]], inlinedAt: ![[LOCINL2:[0-9]+]])
29+
// CHECK-DAG: ![[LOCINL2]] = distinct !DILocation(line: 0, scope: ![[SUBPROG]])
30+
2731
#if M
2832
import _Differentiation
2933

0 commit comments

Comments
 (0)