Skip to content

Commit 2751d98

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 0d65205 commit 2751d98

File tree

4 files changed

+12
-9
lines changed

4 files changed

+12
-9
lines changed

lib/IRGen/IRGenDebugInfo.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
413413
// Pretend transparent functions don't exist.
414414
if (!Scope)
415415
return createInlinedAt(CS);
416-
auto InlinedAt = llvm::DILocation::get(
416+
auto InlinedAt = llvm::DILocation::getDistinct(
417417
IGM.getLLVMContext(), L.line, L.column, Scope, createInlinedAt(CS));
418418
InlinedAtCache.insert({CS, llvm::TrackingMDNodeRef(InlinedAt)});
419419
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

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
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 @"$s4main1TV13TangentVectorV1poiyA2E_AEtFZTm"
67
// CHECK: entry:
78
// CHECK-NEXT: call void @llvm.dbg.declare(metadata %TSb* undef, metadata ![[VAR1:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 192, 8)), !dbg ![[LOC1:[0-9]+]]
89
// CHECK-NEXT: call void @llvm.dbg.declare(metadata %TSb* undef, metadata ![[VAR2:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 192, 8)), !dbg ![[LOC1]]
9-
// CHECK-NEXT: call void @llvm.dbg.declare(metadata %TSb* undef, metadata ![[VAR1]], metadata !DIExpression(DW_OP_LLVM_fragment, 192, 8)), !dbg ![[LOC1]]
10-
// CHECK-NEXT: call void @llvm.dbg.declare(metadata %TSb* undef, metadata ![[VAR2]], metadata !DIExpression(DW_OP_LLVM_fragment, 192, 8)), !dbg ![[LOC1]]
10+
// CHECK-NEXT: call void @llvm.dbg.declare(metadata %TSb* undef, metadata ![[VAR1]], metadata !DIExpression(DW_OP_LLVM_fragment, 192, 8)), !dbg ![[LOC2:[0-9]+]]
11+
// CHECK-NEXT: call void @llvm.dbg.declare(metadata %TSb* undef, metadata ![[VAR2]], metadata !DIExpression(DW_OP_LLVM_fragment, 192, 8)), !dbg ![[LOC2:[0-9]+]]
1112

1213
// CHECK: ![[VAR1]] = !DILocalVariable(name: "lhs", arg: 1, scope: ![[SCOPE:[0-9]+]]
1314
// CHECK: ![[VAR2]] = !DILocalVariable(name: "rhs", arg: 2, scope: ![[SCOPE:[0-9]+]]
1415

1516
// CHECK: ![[LOC1]] = !DILocation(line: 0, scope: ![[SCOPE]], inlinedAt: ![[LOCINL1:[0-9]+]])
16-
// CHECK: ![[LOCINL1]] = !DILocation(line: 0, scope: ![[SUBPROG:[0-9]+]])
17+
// CHECK: ![[LOCINL1]] = distinct !DILocation(line: 0, scope: ![[SUBPROG:[0-9]+]])
1718
// CHECK: ![[SUBPROG]] = distinct !DISubprogram(name: "+", linkageName: "$s4main1TV13TangentVectorV1poiyA2E_AEtFZ"
19+
// CHECK: ![[LOC2]] = !DILocation(line: 0, scope: ![[SCOPE]], inlinedAt: ![[LOCINL2:[0-9]+]])
20+
// CHECK: ![[LOCINL2]] = distinct !DILocation(line: 0, scope: ![[SUBPROG]])
1821

1922
#if M
2023
import _Differentiation

0 commit comments

Comments
 (0)