Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit b0a5d37

Browse files
committed
add-discriminators: Fix handling of inlined locations
This fixes a bug that occurs when a function that is defined on the same line as its call site is inlined. This situation can easily happen in macro expansions. To fix the issue this looks at the subprogram the instruction belongs to first. Fixes PR30681.
1 parent 941c219 commit b0a5d37

File tree

3 files changed

+101
-10
lines changed

3 files changed

+101
-10
lines changed

lib/Transforms/Utils/AddDiscriminators.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ static bool addDiscriminators(Function &F) {
171171
DIBuilder Builder(*M, /*AllowUnresolved*/ false);
172172

173173
typedef std::pair<StringRef, unsigned> Location;
174-
typedef DenseMap<const BasicBlock *, Metadata *> BBScopeMap;
174+
typedef SmallDenseMap<DIScope *, DILexicalBlockFile *, 1> ScopeMap;
175+
typedef DenseMap<const BasicBlock *, ScopeMap> BBScopeMap;
175176
typedef DenseMap<Location, BBScopeMap> LocationBBMap;
176177
typedef DenseMap<Location, unsigned> LocationDiscriminatorMap;
177178
typedef DenseSet<Location> LocationSet;
@@ -189,20 +190,23 @@ static bool addDiscriminators(Function &F) {
189190
const DILocation *DIL = I.getDebugLoc();
190191
if (!DIL)
191192
continue;
193+
DIScope *Scope = DIL->getScope();
192194
Location L = std::make_pair(DIL->getFilename(), DIL->getLine());
193195
auto &BBMap = LBM[L];
194-
auto R = BBMap.insert(std::make_pair(&B, (Metadata *)nullptr));
196+
auto R = BBMap.insert({&B, ScopeMap()});
195197
if (BBMap.size() == 1)
196198
continue;
197199
bool InsertSuccess = R.second;
198-
Metadata *&NewScope = R.first->second;
199-
// If we could insert a different block in the same location, a
200+
ScopeMap &Scopes = R.first->second;
201+
// If we could insert more than one block with the same line+file, a
200202
// discriminator is needed to distinguish both instructions.
201-
if (InsertSuccess) {
202-
auto *Scope = DIL->getScope();
203-
auto *File =
204-
Builder.createFile(DIL->getFilename(), Scope->getDirectory());
205-
NewScope = Builder.createLexicalBlockFile(Scope, File, ++LDM[L]);
203+
auto R1 = Scopes.insert({Scope, nullptr});
204+
DILexicalBlockFile *&NewScope = R1.first->second;
205+
unsigned Discriminator = InsertSuccess ? ++LDM[L] : LDM[L];
206+
if (!NewScope) {
207+
auto *File = Builder.createFile(DIL->getFilename(),
208+
Scope->getDirectory());
209+
NewScope = Builder.createLexicalBlockFile(Scope, File, Discriminator);
206210
}
207211
I.setDebugLoc(DILocation::get(Ctx, DIL->getLine(), DIL->getColumn(),
208212
NewScope, DIL->getInlinedAt()));
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
; RUN: opt < %s -add-discriminators -S | FileCheck %s
2+
;
3+
; Generated at -O3 from:
4+
; g();f(){for(;;){g();}}g(){__builtin___memset_chk(0,0,0,__builtin_object_size(1,0));}
5+
; The fact that everything is on one line is significant!
6+
;
7+
; This test ensures that inline info isn't dropped even if the call site and the
8+
; inlined function are defined on the same line.
9+
source_filename = "t.c"
10+
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
11+
target triple = "arm64-apple-ios"
12+
13+
; Function Attrs: noreturn nounwind ssp
14+
define i32 @f() local_unnamed_addr #0 !dbg !7 {
15+
entry:
16+
%0 = tail call i64 @llvm.objectsize.i64.p0i8(i8* inttoptr (i64 1 to i8*), i1 false) #2, !dbg !11
17+
br label %for.cond, !dbg !18
18+
19+
for.cond: ; preds = %for.cond, %entry
20+
; CHECK: %call.i
21+
%call.i = tail call i8* @__memset_chk(i8* null, i32 0, i64 0, i64 %0) #2, !dbg !19
22+
; CHECK: br label %for.cond, !dbg ![[BR:[0-9]+]]
23+
br label %for.cond, !dbg !20, !llvm.loop !21
24+
}
25+
26+
; Function Attrs: nounwind ssp
27+
define i32 @g() local_unnamed_addr #1 !dbg !12 {
28+
entry:
29+
%0 = tail call i64 @llvm.objectsize.i64.p0i8(i8* inttoptr (i64 1 to i8*), i1 false), !dbg !22
30+
%call = tail call i8* @__memset_chk(i8* null, i32 0, i64 0, i64 %0) #2, !dbg !23
31+
ret i32 undef, !dbg !24
32+
}
33+
34+
; Function Attrs: nounwind
35+
declare i8* @__memset_chk(i8*, i32, i64, i64) local_unnamed_addr #2
36+
37+
; Function Attrs: nounwind readnone
38+
declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) #3
39+
40+
attributes #0 = { noreturn nounwind ssp }
41+
attributes #1 = { nounwind ssp }
42+
attributes #2 = { nounwind }
43+
attributes #3 = { nounwind readnone }
44+
45+
!llvm.dbg.cu = !{!0}
46+
!llvm.module.flags = !{!3, !4, !5}
47+
!llvm.ident = !{!6}
48+
49+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "LLVM version 4.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
50+
!1 = !DIFile(filename: "t.c", directory: "/")
51+
!2 = !{}
52+
!3 = !{i32 2, !"Dwarf Version", i32 4}
53+
!4 = !{i32 2, !"Debug Info Version", i32 3}
54+
!5 = !{i32 1, !"PIC Level", i32 2}
55+
!6 = !{!"LLVM version 4.0.0"}
56+
; CHECK: ![[F:.*]] = distinct !DISubprogram(name: "f",
57+
!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, variables: !2)
58+
!8 = !DISubroutineType(types: !9)
59+
!9 = !{!10}
60+
!10 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
61+
!11 = !DILocation(line: 1, column: 56, scope: !12, inlinedAt: !13)
62+
!12 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, variables: !2)
63+
!13 = distinct !DILocation(line: 1, column: 17, scope: !14)
64+
; CHECK: ![[BF:.*]] = !DILexicalBlockFile(scope: ![[LB1:[0-9]+]],
65+
; CHECK-SAME: discriminator: 1)
66+
!14 = !DILexicalBlockFile(scope: !15, file: !1, discriminator: 1)
67+
; CHECK: ![[LB1]] = distinct !DILexicalBlock(scope: ![[LB2:[0-9]+]],
68+
; CHECK-SAME: line: 1, column: 16)
69+
!15 = distinct !DILexicalBlock(scope: !16, file: !1, line: 1, column: 16)
70+
; CHECK: ![[LB2]] = distinct !DILexicalBlock(scope: ![[LB3:[0-9]+]],
71+
; CHECK-SAME: line: 1, column: 9)
72+
!16 = distinct !DILexicalBlock(scope: !17, file: !1, line: 1, column: 9)
73+
; CHECK: ![[LB3]] = distinct !DILexicalBlock(scope: ![[F]],
74+
; CHECK-SAME: line: 1, column: 9)
75+
!17 = distinct !DILexicalBlock(scope: !7, file: !1, line: 1, column: 9)
76+
!18 = !DILocation(line: 1, column: 9, scope: !7)
77+
!19 = !DILocation(line: 1, column: 27, scope: !12, inlinedAt: !13)
78+
; CHECK: ![[BR]] = !DILocation(line: 1, column: 9, scope: ![[BF2:[0-9]+]])
79+
; CHECK: ![[BF2]] = !DILexicalBlockFile(scope: ![[BF]],
80+
; CHECK-SAME: discriminator: 1)
81+
!20 = !DILocation(line: 1, column: 9, scope: !14)
82+
!21 = distinct !{!21, !18}
83+
!22 = !DILocation(line: 1, column: 56, scope: !12)
84+
!23 = !DILocation(line: 1, column: 27, scope: !12)
85+
!24 = !DILocation(line: 1, column: 84, scope: !12)

test/Transforms/AddDiscriminators/oneline.ll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,12 @@ attributes #1 = { nounwind readnone }
8888
!27 = !DILocation(line: 2, column: 42, scope: !20)
8989
!28 = !DILocation(line: 3, column: 1, scope: !4)
9090

91+
; CHECK: ![[F:.*]] = distinct !DISubprogram(name: "foo",
9192
; CHECK: ![[THEN1]] = !DILocation(line: 2, column: 17, scope: ![[THENBLOCK:[0-9]+]])
9293
; CHECK: ![[THENBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 1)
9394
; CHECK: ![[THEN2]] = !DILocation(line: 2, column: 19, scope: ![[THENBLOCK]])
94-
; CHECK: ![[THEN3]] = !DILocation(line: 2, column: 7, scope: ![[THENBLOCK]])
95+
; CHECK: ![[THEN3]] = !DILocation(line: 2, column: 7, scope: ![[BRBLOCK:[0-9]+]])
96+
; CHECK: ![[BRBLOCK]] = !DILexicalBlockFile(scope: ![[F]]{{.*}} discriminator: 1)
9597
; CHECK: ![[ELSE]] = !DILocation(line: 2, column: 25, scope: ![[ELSEBLOCK:[0-9]+]])
9698
; CHECK: ![[ELSEBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 2)
9799
; CHECK: ![[COMBINE]] = !DILocation(line: 2, column: 42, scope: ![[COMBINEBLOCK:[0-9]+]])

0 commit comments

Comments
 (0)