diff --git a/flang/lib/Optimizer/Transforms/AddDebugFoundation.cpp b/flang/lib/Optimizer/Transforms/AddDebugFoundation.cpp index 9972961de29f2..16b8db7ec8c64 100644 --- a/flang/lib/Optimizer/Transforms/AddDebugFoundation.cpp +++ b/flang/lib/Optimizer/Transforms/AddDebugFoundation.cpp @@ -93,8 +93,18 @@ void AddDebugFoundationPass::runOnOperation() { context, llvm::dwarf::getCallingConvention("DW_CC_normal"), {bT, bT}); mlir::LLVM::DIFileAttr funcFileAttr = getFileAttr(funcFilePath); + + // Only definitions need a distinct identifier and a compilation unit. + mlir::DistinctAttr id; + mlir::LLVM::DICompileUnitAttr compilationUnit; + if (!funcOp.isExternal()) { + id = mlir::DistinctAttr::create(mlir::UnitAttr::get(context)); + compilationUnit = cuAttr; + } mlir::LLVM::DISubprogramAttr spAttr = mlir::LLVM::DISubprogramAttr::get( - context, cuAttr, fileAttr, funcName, funcName, funcFileAttr, /*line=*/1, + context, id, compilationUnit, fileAttr, funcName, funcName, + funcFileAttr, + /*line=*/1, /*scopeline=*/1, mlir::LLVM::DISubprogramFlags::Definition, subTypeAttr); funcOp->setLoc(builder.getFusedLoc({funcOp->getLoc()}, spAttr)); diff --git a/flang/test/Transforms/debug-line-table-inc-file.fir b/flang/test/Transforms/debug-line-table-inc-file.fir index 9ab4025a58626..f809ab99b4727 100644 --- a/flang/test/Transforms/debug-line-table-inc-file.fir +++ b/flang/test/Transforms/debug-line-table-inc-file.fir @@ -30,8 +30,8 @@ module attributes {} { // CHECK: #[[MODULE_LOC]] = loc("{{.*}}simple.f90":0:0) // CHECK: #[[LOC_INC_FILE:.*]] = loc("{{.*}}inc.f90":1:1) // CHECK: #[[LOC_FILE:.*]] = loc("{{.*}}simple.f90":3:1) -// CHECK: #[[DI_CU:.*]] = #llvm.di_compile_unit, sourceLanguage = DW_LANG_Fortran95, file = #[[DI_FILE]], producer = "Flang", isOptimized = false, emissionKind = LineTablesOnly> -// CHECK: #[[DI_SP_INC:.*]] = #llvm.di_subprogram -// CHECK: #[[DI_SP:.*]] = #llvm.di_subprogram +// CHECK: #[[DI_CU:.*]] = #llvm.di_compile_unit, sourceLanguage = DW_LANG_Fortran95, file = #[[DI_FILE]], producer = "Flang", isOptimized = false, emissionKind = LineTablesOnly> +// CHECK: #[[DI_SP_INC:.*]] = #llvm.di_subprogram, compileUnit = #[[DI_CU]], scope = #[[DI_FILE]], name = "_QPsinc", linkageName = "_QPsinc", file = #[[DI_INC_FILE]], {{.*}}> +// CHECK: #[[DI_SP:.*]] = #llvm.di_subprogram, compileUnit = #[[DI_CU]], scope = #[[DI_FILE]], name = "_QQmain", linkageName = "_QQmain", file = #[[DI_FILE]], {{.*}}> // CHECK: #[[FUSED_LOC_INC_FILE]] = loc(fused<#[[DI_SP_INC]]>[#[[LOC_INC_FILE]]]) // CHECK: #[[FUSED_LOC_FILE]] = loc(fused<#[[DI_SP]]>[#[[LOC_FILE]]]) diff --git a/flang/test/Transforms/debug-line-table.fir b/flang/test/Transforms/debug-line-table.fir index 115c6929778ec..f091d97ce89ea 100644 --- a/flang/test/Transforms/debug-line-table.fir +++ b/flang/test/Transforms/debug-line-table.fir @@ -5,20 +5,26 @@ module attributes { fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.dat func.func @_QPsb() { return loc(#loc_sb) } loc(#loc_sb) + func.func private @decl() -> i32 loc(#loc_decl) } loc(#loc_module) #loc_module = loc("./simple.f90":1:1) #loc_sb = loc("./simple.f90":2:1) +#loc_decl = loc("./simple.f90":10:1) // CHECK: module attributes // CHECK: func.func @[[SB_NAME:.*]]() { // CHECK: return loc(#[[SB_LOC:.*]]) // CHECK: } loc(#[[FUSED_SB_LOC:.*]]) +// CHECK: func.func private @[[DECL_NAME:.*]]() -> i32 loc(#[[FUSED_DECL_LOC:.*]]) // CHECK: } loc(#[[MODULE_LOC:.*]]) // CHECK: #di_basic_type = #llvm.di_basic_type // CHECK: #di_file = #llvm.di_file<"[[FILE_NAME:.*]]" in "[[DIR_NAME:.*]]"> // CHECK: #[[MODULE_LOC]] = loc("[[DIR_NAME]]/[[FILE_NAME]]":1:1) // CHECK: #[[SB_LOC]] = loc("./simple.f90":2:1) -// CHECK: #di_compile_unit = #llvm.di_compile_unit, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "Flang", isOptimized = false, emissionKind = LineTablesOnly> +// CHECK: #[[DECL_LOC:.*]] = loc("./simple.f90":10:1) +// CHECK: #di_compile_unit = #llvm.di_compile_unit, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "Flang", isOptimized = false, emissionKind = LineTablesOnly> // CHECK: #di_subroutine_type = #llvm.di_subroutine_type -// CHECK: #di_subprogram = #llvm.di_subprogram -// CHECK: #[[FUSED_SB_LOC]] = loc(fused<#di_subprogram>[#[[SB_LOC]]]) +// CHECK: #[[SB_SUBPROGRAM:.*]] = #llvm.di_subprogram, compileUnit = #di_compile_unit, scope = #di_file, name = "[[SB_NAME]]", linkageName = "[[SB_NAME]]", file = #di_file, line = 1, scopeLine = 1, subprogramFlags = Definition, type = #di_subroutine_type> +// CHECK: #[[DECL_SUBPROGRAM:.*]] = #llvm.di_subprogram +// CHECK: #[[FUSED_SB_LOC]] = loc(fused<#[[SB_SUBPROGRAM]]>[#[[SB_LOC]]]) +// CHECK: #[[FUSED_DECL_LOC]] = loc(fused<#[[DECL_SUBPROGRAM]]>[#[[DECL_LOC]]]) diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td index 3b8ca9d2e3c51..86ba9f4d3840b 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -517,6 +517,7 @@ def LLVM_DILocalVariableAttr : LLVM_Attr<"DILocalVariable", "di_local_variable", def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram", /*traits=*/[], "DIScopeAttr"> { let parameters = (ins + OptionalParameter<"DistinctAttr">:$id, OptionalParameter<"DICompileUnitAttr">:$compileUnit, "DIScopeAttr":$scope, OptionalParameter<"StringAttr">:$name, @@ -529,13 +530,13 @@ def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram", ); let builders = [ AttrBuilderWithInferredContext<(ins - "DICompileUnitAttr":$compileUnit, "DIScopeAttr":$scope, "StringRef":$name, - "StringRef":$linkageName, "DIFileAttr":$file, "unsigned":$line, - "unsigned":$scopeLine, "DISubprogramFlags":$subprogramFlags, - "DISubroutineTypeAttr":$type + "DistinctAttr":$id, "DICompileUnitAttr":$compileUnit, + "DIScopeAttr":$scope, "StringRef":$name, "StringRef":$linkageName, + "DIFileAttr":$file, "unsigned":$line, "unsigned":$scopeLine, + "DISubprogramFlags":$subprogramFlags, "DISubroutineTypeAttr":$type ), [{ MLIRContext *ctx = file.getContext(); - return $_get(ctx, compileUnit, scope, StringAttr::get(ctx, name), + return $_get(ctx, id, compileUnit, scope, StringAttr::get(ctx, name), StringAttr::get(ctx, linkageName), file, line, scopeLine, subprogramFlags, type); }]> diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp index d2e2c09e876ff..de6fb1b16977a 100644 --- a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp +++ b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp @@ -66,8 +66,15 @@ static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc, LLVM::DISubroutineTypeAttr::get(context, llvm::dwarf::DW_CC_normal, {}); StringAttr funcNameAttr = llvmFunc.getNameAttr(); - auto subprogramAttr = LLVM::DISubprogramAttr::get( - context, compileUnitAttr, fileAttr, funcNameAttr, funcNameAttr, fileAttr, + // Only definitions need a distinct identifier and a compilation unit. + mlir::DistinctAttr id; + if (!llvmFunc.isExternal()) + id = mlir::DistinctAttr::create(mlir::UnitAttr::get(context)); + else + compileUnitAttr = {}; + mlir::LLVM::DISubprogramAttr subprogramAttr = LLVM::DISubprogramAttr::get( + context, id, compileUnitAttr, fileAttr, funcNameAttr, funcNameAttr, + fileAttr, /*line=*/line, /*scopeline=*/col, LLVM::DISubprogramFlags::Definition | LLVM::DISubprogramFlags::Optimized, diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp index 97871c7fe9773..6521295230091 100644 --- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp +++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp @@ -163,6 +163,10 @@ DINamespaceAttr DebugImporter::translateImpl(llvm::DINamespace *node) { } DISubprogramAttr DebugImporter::translateImpl(llvm::DISubprogram *node) { + // Only definitions require a distinct identifier. + mlir::DistinctAttr id; + if (node->isDistinct()) + id = DistinctAttr::create(UnitAttr::get(context)); std::optional subprogramFlags = symbolizeDISubprogramFlags(node->getSubprogram()->getSPFlags()); // Return nullptr if the scope or type is a cyclic dependency. @@ -172,7 +176,7 @@ DISubprogramAttr DebugImporter::translateImpl(llvm::DISubprogram *node) { DISubroutineTypeAttr type = translate(node->getType()); if (node->getType() && !type) return nullptr; - return DISubprogramAttr::get(context, translate(node->getUnit()), scope, + return DISubprogramAttr::get(context, id, translate(node->getUnit()), scope, getStringAttrOrNull(node->getRawName()), getStringAttrOrNull(node->getRawLinkageName()), translate(node->getFile()), node->getLine(), diff --git a/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir b/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir index be84d401646dc..f63132d42ab71 100644 --- a/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir +++ b/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir @@ -4,7 +4,7 @@ // CHECK: llvm.return loc(#loc // CHECK: loc(#loc[[LOC:[0-9]+]]) // CHECK: #di_file = #llvm.di_file<"" in ""> -// CHECK: #di_subprogram = #llvm.di_subprogram +// CHECK: #di_subprogram = #llvm.di_subprogram, compileUnit = #di_compile_unit, scope = #di_file, name = "func_no_debug", linkageName = "func_no_debug", file = #di_file, line = 1, scopeLine = 1, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type> // CHECK: #loc[[LOC]] = loc(fused<#di_subprogram> module { llvm.func @func_no_debug() { @@ -14,12 +14,22 @@ module { // ----- +// Test that the declarations subprogram is not made distinct. +// CHECK-LABEL: llvm.func @func_decl_no_debug() +// CHECK: #di_subprogram = #llvm.di_subprogram< +// CHECK-NOT: id = distinct +module { + llvm.func @func_decl_no_debug() loc(unknown) +} loc(unknown) + +// ----- + // Test that existing debug info is not overwritten. // CHECK-LABEL: llvm.func @func_with_debug() // CHECK: llvm.return loc(#loc // CHECK: loc(#loc[[LOC:[0-9]+]]) // CHECK: #di_file = #llvm.di_file<"" in ""> -// CHECK: #di_subprogram = #llvm.di_subprogram +// CHECK: #di_subprogram = #llvm.di_subprogram, compileUnit = #di_compile_unit, scope = #di_file, name = "func_with_debug", linkageName = "func_with_debug", file = #di_file, line = 42, scopeLine = 42, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type> // CHECK: #loc[[LOC]] = loc(fused<#di_subprogram> module { llvm.func @func_with_debug() { @@ -31,7 +41,7 @@ module { #loc = loc("foo":0:0) #loc1 = loc(unknown) #di_compile_unit = #llvm.di_compile_unit, sourceLanguage = DW_LANG_C, file = #di_file, producer = "MLIR", isOptimized = true, emissionKind = LineTablesOnly> -#di_subprogram = #llvm.di_subprogram +#di_subprogram = #llvm.di_subprogram, compileUnit = #di_compile_unit, scope = #di_file, name = "func_with_debug", linkageName = "func_with_debug", file = #di_file, line = 42, scopeLine = 42, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type> #loc2 = loc(fused<#di_subprogram>[#loc1]) // ----- @@ -44,8 +54,8 @@ module { // CHECK-DAG: #[[DI_FILE_MODULE:.+]] = #llvm.di_file<"bar.mlir" in "baz"> // CHECK-DAG: #[[DI_FILE_FUNC:.+]] = #llvm.di_file<"file.mlir" in ""> // CHECK-DAG: #loc[[FUNCFILELOC:[0-9]+]] = loc("file.mlir":9:8) -// CHECK-DAG: #di_compile_unit = #llvm.di_compile_unit, sourceLanguage = DW_LANG_C, file = #[[DI_FILE_MODULE]], producer = "MLIR", isOptimized = true, emissionKind = LineTablesOnly> -// CHECK-DAG: #di_subprogram = #llvm.di_subprogram +// CHECK-DAG: #di_compile_unit = #llvm.di_compile_unit, sourceLanguage = DW_LANG_C, file = #[[DI_FILE_MODULE]], producer = "MLIR", isOptimized = true, emissionKind = LineTablesOnly> +// CHECK-DAG: #di_subprogram = #llvm.di_subprogram, compileUnit = #di_compile_unit, scope = #[[DI_FILE_FUNC]], name = "propagate_compile_unit", linkageName = "propagate_compile_unit", file = #[[DI_FILE_FUNC]], line = 9, scopeLine = 8, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type> // CHECK-DAG: #loc[[MODULELOC]] = loc(fused<#di_compile_unit>[#loc]) // CHECK-DAG: #loc[[FUNCLOC]] = loc(fused<#di_subprogram>[#loc[[FUNCFILELOC]] module { diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll index 03e5e5a4837ac..9ef6580bcf240 100644 --- a/mlir/test/Target/LLVMIR/Import/debug-info.ll +++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll @@ -30,8 +30,8 @@ define i32 @instruction_loc(i32 %arg1) { } ; CHECK-DAG: #[[RAW_FILE_LOC:.+]] = loc("debug-info.ll":1:2) -; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram, compileUnit = #{{.*}}, scope = #{{.*}}, name = "instruction_loc" +; CHECK-DAG: #[[CALLEE:.+]] = #llvm.di_subprogram, compileUnit = #{{.*}}, scope = #{{.*}}, name = "callee" ; CHECK-DAG: #[[FILE_LOC]] = loc(fused<#[[SP]]>[#[[RAW_FILE_LOC]]]) ; CHECK-DAG: #[[RAW_CALLEE_LOC:.+]] = loc("debug-info.ll":7:4) ; CHECK-DAG: #[[CALLEE_LOC:.+]] = loc(fused<#[[CALLEE]]>[#[[RAW_CALLEE_LOC]]]) @@ -63,7 +63,7 @@ define i32 @lexical_block(i32 %arg1) { ret i32 %2 } ; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/"> -; CHECK: #[[SP:.+]] = #llvm.di_subprogram, compileUnit = ; CHECK: #[[LB0:.+]] = #llvm.di_lexical_block ; CHECK: #[[LB1:.+]] = #llvm.di_lexical_block ; CHECK: #[[LOC0]] = loc(fused<#[[LB0]]>[{{.*}}]) @@ -93,7 +93,7 @@ define i32 @lexical_block_file(i32 %arg1) { ret i32 %2 } ; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/"> -; CHECK: #[[SP:.+]] = #llvm.di_subprogram, compileUnit = ; CHECK: #[[LB0:.+]] = #llvm.di_lexical_block_file ; CHECK: #[[LB1:.+]] = #llvm.di_lexical_block_file ; CHECK: #[[LOC0]] = loc(fused<#[[LB0]]>[ @@ -200,7 +200,7 @@ define void @composite_type() !dbg !3 { ; CHECK-DAG: #[[CU:.+]] = #llvm.di_compile_unit, sourceLanguage = DW_LANG_C, file = #[[FILE]], isOptimized = false, emissionKind = None> ; Verify an empty subroutine types list is supported. ; CHECK-DAG: #[[SP_TYPE:.+]] = #llvm.di_subroutine_type -; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram +; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram, compileUnit = #[[CU]], scope = #[[FILE]], name = "subprogram", linkageName = "subprogram", file = #[[FILE]], line = 42, scopeLine = 42, subprogramFlags = Definition, type = #[[SP_TYPE]]> define void @subprogram() !dbg !3 { ret void @@ -224,7 +224,7 @@ define void @func_loc() !dbg !3 { } ; CHECK-DAG: #[[NAME_LOC:.+]] = loc("func_loc") ; CHECK-DAG: #[[FILE_LOC:.+]] = loc("debug-info.ll":42:0) -; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram +; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram, compileUnit = #{{.*}}, scope = #{{.*}}, name = "func_loc", file = #{{.*}}, line = 42, subprogramFlags = Definition> ; CHECK: loc(fused<#[[SP]]>[#[[NAME_LOC]], #[[FILE_LOC]]] @@ -300,7 +300,7 @@ define void @class_method() { ; CHECK: #[[COMP:.+]] = #llvm.di_composite_type ; CHECK: #[[COMP_PTR:.+]] = #llvm.di_derived_type ; CHECK: #[[SP_TYPE:.+]] = #llvm.di_subroutine_type -; CHECK: #[[SP:.+]] = #llvm.di_subprogram +; CHECK: #[[SP:.+]] = #llvm.di_subprogram, compileUnit = #{{.*}}, scope = #[[COMP]], name = "class_method", file = #{{.*}}, subprogramFlags = Definition, type = #[[SP_TYPE]]> ; CHECK: #[[LOC]] = loc(fused<#[[SP]]> !llvm.dbg.cu = !{!1} @@ -485,7 +485,7 @@ declare void @llvm.dbg.value(metadata, metadata, metadata) ; // ----- ; CHECK-DAG: #[[NAMESPACE:.+]] = #llvm.di_namespace -; CHECK-DAG: #[[SUBPROGRAM:.+]] = #llvm.di_subprogram, compileUnit = #{{.*}}, scope = #[[NAMESPACE]], name = "namespace" define void @namespace(ptr %arg) { call void @llvm.dbg.value(metadata ptr %arg, metadata !7, metadata !DIExpression()), !dbg !9 @@ -506,7 +506,7 @@ declare void @llvm.dbg.value(metadata, metadata, metadata) ; // ----- -; CHECK-DAG: #[[SUBPROGRAM:.+]] = #llvm.di_subprogram, compileUnit = #{{.*}}, scope = #{{.*}}, name = "noname_variable" ; CHECK-DAG: #[[LOCAL_VARIABLE:.+]] = #llvm.di_local_variable define void @noname_variable(ptr %arg) { @@ -527,7 +527,7 @@ declare void @llvm.dbg.value(metadata, metadata, metadata) ; // ----- -; CHECK: #[[SUBPROGRAM:.*]] = #llvm.di_subprogram +; CHECK: #[[SUBPROGRAM:.*]] = #llvm.di_subprogram, compileUnit = #{{.*}}, scope = #{{.*}}, file = #{{.*}}, subprogramFlags = Definition> ; CHECK: #[[FUNC_LOC:.*]] = loc(fused<#[[SUBPROGRAM]]>[{{.*}}]) define void @noname_subprogram(ptr %arg) !dbg !8 { ret void @@ -547,7 +547,7 @@ define void @noname_subprogram(ptr %arg) !dbg !8 { ; CHECK-SAME: configMacros = "bar", includePath = "/", ; CHECK-SAME: apinotes = "/", line = 42, isDecl = true ; CHECK-SAME: > -; CHECK: #[[SUBPROGRAM:.+]] = #llvm.di_subprogram, compileUnit = #{{.*}}, scope = #[[MODULE]], name = "func_in_module" define void @func_in_module(ptr %arg) !dbg !8 { ret void @@ -614,3 +614,16 @@ define void @distinct_cu_func1() !dbg !5 { !4 = distinct !DISubprogram(name: "func", linkageName: "func", scope: !6, file: !6, line: 1, scopeLine: 1, flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: !0) !5 = distinct !DISubprogram(name: "func", linkageName: "func", scope: !6, file: !6, line: 1, scopeLine: 1, flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: !1) !6 = !DIFile(filename: "file.hpp", directory: "/") + +; // ----- + +; CHECK-LABEL: @declaration +declare !dbg !1 void @declaration() + +; CHECK: #di_subprogram = #llvm.di_subprogram< +; CHECK-NOT: id = distinct + +!llvm.module.flags = !{!0} +!0 = !{i32 2, !"Debug Info Version", i32 3} +!1 = !DISubprogram(name: "declaration", scope: !2, file: !2, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized) +!2 = !DIFile(filename: "debug-info.ll", directory: "/") diff --git a/mlir/test/Target/LLVMIR/Import/global-variables.ll b/mlir/test/Target/LLVMIR/Import/global-variables.ll index c59515dbaf759..9d9734045988a 100644 --- a/mlir/test/Target/LLVMIR/Import/global-variables.ll +++ b/mlir/test/Target/LLVMIR/Import/global-variables.ll @@ -249,8 +249,8 @@ define void @bar() { ; CHECK-DAG: #[[TYPE:.*]] = #llvm.di_basic_type ; CHECK-DAG: #[[FILE:.*]] = #llvm.di_file<"source.c" in "/path/to/file"> -; CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit, sourceLanguage = DW_LANG_C99, file = #[[FILE]], isOptimized = false, emissionKind = None> -; CHECK-DAG: #[[SPROG:.*]] = #llvm.di_subprogram +; CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit, sourceLanguage = DW_LANG_C99, file = #[[FILE]], isOptimized = false, emissionKind = None> +; CHECK-DAG: #[[SPROG:.*]] = #llvm.di_subprogram, scope = #[[CU]], name = "foo", file = #[[FILE]], line = 5, subprogramFlags = Definition> ; CHECK-DAG: #[[GVAR0:.*]] = #llvm.di_global_variable ; CHECK-DAG: #[[GVAR1:.*]] = #llvm.di_global_variable ; CHECK-DAG: #[[EXPR0:.*]] = #llvm.di_global_variable_expression>