Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1362,8 +1362,8 @@ if (auto *Scope = cast_or_null(S)) { Fn = Scope->getFilename(); Dir = Scope->getDirectory(); - if (auto *LBF = dyn_cast(Scope)) - if (getDwarfVersion() >= 4) + if (Line != 0 && getDwarfVersion() >= 4) + if (auto *LBF = dyn_cast(Scope)) Discriminator = LBF->getDiscriminator(); unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID(); Index: test/CodeGen/Generic/dbg-line-0-no-discriminator.ll =================================================================== --- test/CodeGen/Generic/dbg-line-0-no-discriminator.ll +++ test/CodeGen/Generic/dbg-line-0-no-discriminator.ll @@ -0,0 +1,100 @@ +; RUN: llc -O0 -filetype=asm %s -o - | FileCheck %s +; Verify we got at least one discriminator, and line 0 never has one. +; CHECK: .loc 1 {{[1-9]*}} {{.*}} discriminator +; CHECK-NOT: .loc 1 0 {{.*}} discriminator +; +; Test source: +; int main() { +; unsigned int x = 0U; +; static int const limit = 100000U; +; for (volatile unsigned int i = 0; i < limit; ++i) { +; if ((i & 0x40) == 0) +; x += i; +; } +; return int(x); +; } +; $ clang -c -gmlt -fdebug-info-for-profiling -S -emit-llvm +; then remove the target triple (to make it generic) and the +; function attributes (to simplify it a tiny bit). + +; ModuleID = 'bz183143.cpp' +source_filename = "bz183143.cpp" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +; Function Attrs: norecurse nounwind uwtable +define i32 @main() local_unnamed_addr !dbg !7 { +entry: + %i = alloca i32, align 4 + %i.0.i.0..sroa_cast = bitcast i32* %i to i8*, !dbg !9 + call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %i.0.i.0..sroa_cast), !dbg !9 + store volatile i32 0, i32* %i, align 4, !dbg !10 + %i.0.i.0.9 = load volatile i32, i32* %i, align 4, !dbg !11 + %cmp10 = icmp ult i32 %i.0.i.0.9, 100000, !dbg !13 + br i1 %cmp10, label %for.body, label %for.cond.cleanup, !dbg !14 + +for.cond.cleanup: ; preds = %for.inc, %entry + %x.0.lcssa = phi i32 [ 0, %entry ], [ %x.1, %for.inc ] + call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %i.0.i.0..sroa_cast), !dbg !15 + ret i32 %x.0.lcssa, !dbg !16 + +for.body: ; preds = %entry, %for.inc + %x.011 = phi i32 [ %x.1, %for.inc ], [ 0, %entry ] + %i.0.i.0.2 = load volatile i32, i32* %i, align 4, !dbg !17 + %and = and i32 %i.0.i.0.2, 64, !dbg !18 + %cmp1 = icmp eq i32 %and, 0, !dbg !19 + br i1 %cmp1, label %if.then, label %for.inc, !dbg !20 + +if.then: ; preds = %for.body + %i.0.i.0.3 = load volatile i32, i32* %i, align 4, !dbg !21 + %add = add i32 %i.0.i.0.3, %x.011, !dbg !22 + br label %for.inc, !dbg !23 + +for.inc: ; preds = %for.body, %if.then + %x.1 = phi i32 [ %add, %if.then ], [ %x.011, %for.body ] + %i.0.i.0.4 = load volatile i32, i32* %i, align 4, !dbg !24 + %inc = add i32 %i.0.i.0.4, 1, !dbg !24 + store volatile i32 %inc, i32* %i, align 4, !dbg !24 + %i.0.i.0. = load volatile i32, i32* %i, align 4, !dbg !11 + %cmp = icmp ult i32 %i.0.i.0., 100000, !dbg !13 + br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !14, !llvm.loop !26 +} + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) + + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 5.0.0 (trunk 307600)", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2, debugInfoForProfiling: true) +!1 = !DIFile(filename: "bz183143.cpp", directory: "/home/probinson/projects/scratch") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 5.0.0 (trunk 307600)"} +!7 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !2) +!8 = !DISubroutineType(types: !2) +!9 = !DILocation(line: 4, column: 8, scope: !7) +!10 = !DILocation(line: 4, column: 30, scope: !7) +!11 = !DILocation(line: 4, column: 37, scope: !12) +!12 = !DILexicalBlockFile(scope: !7, file: !1, discriminator: 2) +!13 = !DILocation(line: 4, column: 39, scope: !12) +!14 = !DILocation(line: 4, column: 3, scope: !12) +!15 = !DILocation(line: 4, column: 3, scope: !7) +!16 = !DILocation(line: 8, column: 3, scope: !7) +!17 = !DILocation(line: 5, column: 10, scope: !7) +!18 = !DILocation(line: 5, column: 12, scope: !7) +!19 = !DILocation(line: 5, column: 20, scope: !7) +!20 = !DILocation(line: 5, column: 9, scope: !7) +!21 = !DILocation(line: 6, column: 12, scope: !7) +!22 = !DILocation(line: 6, column: 9, scope: !7) +!23 = !DILocation(line: 6, column: 7, scope: !7) +!24 = !DILocation(line: 4, column: 48, scope: !25) +!25 = !DILexicalBlockFile(scope: !7, file: !1, discriminator: 6) +!26 = distinct !{!26, !15, !27} +!27 = !DILocation(line: 7, column: 3, scope: !7)