1; RUN: %llc_dwarf %s -o - -filetype=obj | llvm-dwarfdump - | FileCheck %s -implicit-check-not=DW_TAG 2; 3; Issue #46473 4; XFAIL: target=sparc{{.*}} 5; 6; This tests that we do not create concrete variable DIEs for variables that 7; have no location -- for both ways that LLVM-IR can express a variable with 8; no location. It's possible to: 9; 1) Omit all dbg.values and place the variable in the subprograms retained 10; nodes list, 11; 2) Have a dbg.value with an undef operand, and none with "real" operands. 12; Both of these should produce the same DWARF. In the two functions below 13; (qux and croix) I've modified the IR to represent both scenarios. 14; 15; Original C, LLVM-IR modified afterwards: 16; 17; int foo(int bar) { 18; int baz = 12 + bar; 19; return baz; 20; } 21; 22; int qux(int quux) { 23; int xyzzy = foo(quux); 24; return xyzzy; 25; } 26; 27; int croix(int quux) { 28; int xyzzy = foo(quux); 29; return xyzzy; 30; } 31; 32;; Note the implicit DW_TAG check-not in the FileCheck command line. 33; CHECK: DW_TAG_compile_unit 34;; 35;; First subprogram is attached to the plain "foo" function in the output 36;; object. It should have locations for the two variables in the function, 37;; let's be non-specific as to how. 38; CHECK: DW_TAG_subprogram 39; CHECK: DW_AT_abstract_origin (0x{{[0-9a-f]*}} "foo") 40; CHECK: DW_TAG_formal_parameter 41; CHECK: DW_AT_location 42; CHECK: DW_TAG_variable 43; CHECK: DW_AT_location 44; 45;; Abstract subprogram; should have plain variable declarations 46; CHECK: DW_TAG_subprogram 47; CHECK: DW_AT_name ("foo") 48; CHECK: DW_TAG_formal_parameter 49; CHECK: DW_AT_name ("bar") 50; CHECK: DW_TAG_variable 51; CHECK: DW_AT_name ("baz") 52; 53; CHECK: DW_TAG_base_type 54; 55;; The copy of "foo" inlined into "qux" should have no children. 56; CHECK: DW_TAG_subprogram 57; CHECK: DW_AT_name ("qux") 58; CHECK: DW_TAG_formal_parameter 59; CHECK: DW_TAG_variable 60; CHECK: DW_TAG_inlined_subroutine 61; CHECK: NULL 62; 63;; Same for the copy of foo inlined into "croix" 64; CHECK: DW_TAG_subprogram 65; CHECK: DW_AT_name ("croix") 66; CHECK: DW_TAG_formal_parameter 67; CHECK: DW_TAG_variable 68; CHECK: DW_TAG_inlined_subroutine 69; CHECK: NULL 70 71; NOTE: Instructions below changed from `add` to `mul` to make them more expensive 72; and unlikely to be sunk to replace COPYs into a return value register. 73 74; Function Attrs: norecurse nounwind readnone uwtable willreturn 75define dso_local i32 @foo(i32 %bar) local_unnamed_addr !dbg !7 { 76entry: 77 call void @llvm.dbg.value(metadata i32 %bar, metadata !12, metadata !DIExpression()), !dbg !14 78 %add = mul nsw i32 %bar, 12, !dbg !15 79 call void @llvm.dbg.value(metadata i32 %add, metadata !13, metadata !DIExpression()), !dbg !14 80 ret i32 %add, !dbg !16 81} 82 83; Function Attrs: norecurse nounwind readnone uwtable willreturn 84define dso_local i32 @qux(i32 %quux) local_unnamed_addr !dbg !17 { 85entry: 86 %add.i = mul nsw i32 %quux, 12, !dbg !24 87 ret i32 %add.i, !dbg !25 88} 89 90; Function Attrs: norecurse nounwind readnone uwtable willreturn 91define dso_local i32 @croix(i32 %quux) local_unnamed_addr !dbg !26 { 92entry: 93 call void @llvm.dbg.value(metadata i32 undef, metadata !28, metadata !DIExpression()), !dbg !30 94 call void @llvm.dbg.value(metadata i32 undef, metadata !12, metadata !DIExpression()), !dbg !31 95 %add.i = mul nsw i32 %quux, 12, !dbg !33 96 call void @llvm.dbg.value(metadata i32 undef, metadata !13, metadata !DIExpression()), !dbg !31 97 call void @llvm.dbg.value(metadata i32 undef, metadata !29, metadata !DIExpression()), !dbg !30 98 ret i32 %add.i, !dbg !34 99} 100 101; Function Attrs: nofree nosync nounwind readnone speculatable willreturn 102declare void @llvm.dbg.value(metadata, metadata, metadata) 103 104!llvm.dbg.cu = !{!0} 105!llvm.module.flags = !{!3, !4, !5} 106!llvm.ident = !{!6} 107 108!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) 109!1 = !DIFile(filename: "test.c", directory: ".") 110!2 = !{} 111!3 = !{i32 7, !"Dwarf Version", i32 4} 112!4 = !{i32 2, !"Debug Info Version", i32 3} 113!5 = !{i32 1, !"wchar_size", i32 4} 114!6 = !{!"clang"} 115!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) 116!8 = !DISubroutineType(types: !9) 117!9 = !{!10, !10} 118!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 119!11 = !{!12, !13} 120!12 = !DILocalVariable(name: "bar", arg: 1, scope: !7, file: !1, line: 1, type: !10) 121!13 = !DILocalVariable(name: "baz", scope: !7, file: !1, line: 2, type: !10) 122!14 = !DILocation(line: 0, scope: !7) 123!15 = !DILocation(line: 2, column: 16, scope: !7) 124!16 = !DILocation(line: 3, column: 3, scope: !7) 125!17 = distinct !DISubprogram(name: "qux", scope: !1, file: !1, line: 6, type: !8, scopeLine: 6, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !18) 126!18 = !{!19, !20} 127!19 = !DILocalVariable(name: "quux", arg: 1, scope: !17, file: !1, line: 6, type: !10) 128!20 = !DILocalVariable(name: "xyzzy", scope: !17, file: !1, line: 7, type: !10) 129!21 = !DILocation(line: 0, scope: !17) 130!22 = !DILocation(line: 0, scope: !7, inlinedAt: !23) 131!23 = distinct !DILocation(line: 7, column: 15, scope: !17) 132!24 = !DILocation(line: 2, column: 16, scope: !7, inlinedAt: !23) 133!25 = !DILocation(line: 8, column: 3, scope: !17) 134!26 = distinct !DISubprogram(name: "croix", scope: !1, file: !1, line: 11, type: !8, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !27) 135!27 = !{!28, !29} 136!28 = !DILocalVariable(name: "quux", arg: 1, scope: !26, file: !1, line: 11, type: !10) 137!29 = !DILocalVariable(name: "xyzzy", scope: !26, file: !1, line: 12, type: !10) 138!30 = !DILocation(line: 0, scope: !26) 139!31 = !DILocation(line: 0, scope: !7, inlinedAt: !32) 140!32 = distinct !DILocation(line: 12, column: 15, scope: !26) 141!33 = !DILocation(line: 2, column: 16, scope: !7, inlinedAt: !32) 142!34 = !DILocation(line: 13, column: 3, scope: !26) 143