1 # RUN: llc %s -o - -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=CHECK
2 # RUN: llc %s -o - -start-before=livedebugvalues -filetype=obj -mtriple=x86_64-unknown-unknown | llvm-dwarfdump - | FileCheck %s --check-prefix=RANGES
3 # Check that livedebugvalues does the right thing when register and constant
4 # DBG_VALUEs interact, and that their ranges are correctly terminated by the
5 # debug printing backend.
7 ; All these IR functions are duds, see the MIR below.
8 source_filename = "<stdin>"
9 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
11 define i32 @foo(i32* %bees, i32* %output) !dbg !4 {
13 br i1 undef, label %bb1, label %bb1
22 define i32 @bar(i32* %bees, i32* %output) !dbg !40 {
24 br i1 undef, label %bb1, label %bb1
33 define i32 @baz(i32* %bees, i32* %output) !dbg !80 {
35 br i1 undef, label %bb1, label %bb1
44 define i32 @qux(i32* %bees, i32* %output) !dbg !120 {
46 br i1 undef, label %bb1, label %bb1
55 ; Function Attrs: nounwind readnone speculatable
56 declare void @llvm.dbg.value(metadata, metadata, metadata)
58 ; Function Attrs: nounwind readnone speculatable
59 declare void @llvm.dbg.declare(metadata, metadata, metadata)
61 ; Function Attrs: nounwind
62 declare void @llvm.stackprotector(i8*, i8**)
64 !llvm.module.flags = !{!0, !100}
67 !100 = !{i32 2, !"Dwarf Version", i32 4}
68 !0 = !{i32 2, !"Debug Info Version", i32 3}
69 !1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "beards", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
70 !2 = !DIFile(filename: "bees.cpp", directory: ".")
71 !3 = !DILocalVariable(name: "flannel", scope: !4, file: !2, line: 1, type: !16)
72 !4 = distinct !DISubprogram(name: "nope", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true)
73 !5 = !DILocation(line: 0, scope: !4)
74 !6 = !DILocation(line: 1, scope: !4)
75 !7 = !DILocation(line: 2, scope: !4)
76 !8 = !DILocation(line: 4, scope: !4)
77 !9 = !DILocation(line: 5, scope: !4)
78 !10 = !DILocation(line: 6, scope: !4)
79 !11 = !DILocation(line: 7, scope: !4)
80 !12 = !DILocation(line: 8, scope: !4)
82 !14 = !DISubroutineType(types: !15)
84 !16 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
85 !40 = distinct !DISubprogram(name: "bar", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true)
86 !41 = !DILocalVariable(name: "towel", scope: !40, file: !2, line: 1, type: !16)
87 !42 = !DILocation(line: 40, scope: !40)
88 !80 = distinct !DISubprogram(name: "baz", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true)
89 !81 = !DILocalVariable(name: "socks", scope: !80, file: !2, line: 1, type: !16)
90 !82 = !DILocation(line: 40, scope: !80)
91 !120 = distinct !DISubprogram(name: "qux", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true)
92 !121 = !DILocalVariable(name: "shoes", scope: !120, file: !2, line: 1, type: !16)
93 !122 = !DILocation(line: 40, scope: !120)
99 tracksRegLiveness: true
102 - { reg: '$rdi', virtual-reg: '' }
105 ; Two DBG_VALUEs for eax merge into bb3, check that livedebugvalues propagates
107 ; CHECK-LABEL: name: foo
108 ; CHECK-LABEL: bb.1.bb1
109 ; CHECK: $eax = MOV32rr
110 ; CHECK-NEXT: DBG_VALUE $eax
111 ; CHECK-NEXT: JMP_1 %bb.3
112 ; CHECK-LABEL: bb.2.bb2
113 ; CHECK: $eax = ADD32ri8
114 ; CHECK-NEXT: DBG_VALUE $eax
115 ; CHECK-NEXT: JMP_1 %bb.3
116 ; CHECK-LABEL: bb.3.bb3
117 ; CHECK: DBG_VALUE $eax
118 ; Test for there being a location-list gap between bb1 and bb2, as the
119 ; variable does not have a location over the ADD32ri. The range should also
120 ; extend over the final bb.
121 ; RANGES-LABEL: DW_TAG_subprogram
122 ; RANGES: DW_AT_high_pc (0x[[NOPEHIGHPC:[0-9a-f]+]])
123 ; RANGES-LABEL: DW_AT_name ("nope")
124 ; RANGES: DW_AT_location (0x{{[0-9a-f]+}}
125 ; RANGES-NEXT: [0x{{[0-9a-f]+}}, 0x[[NOPEADDR:[0-9a-f]+]]): DW_OP_reg0 RAX
127 ; RANGES-NOT: 0x[[NOPEADDR]]
128 ; RANGES-SAME: , 0x[[NOPEHIGHPC]]): DW_OP_reg0 RAX
131 successors: %bb.1, %bb.2
134 $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
135 JCC_1 %bb.1, 2, implicit killed $eflags
142 $eax = MOV32rr killed $ecx, implicit-def $rax
143 DBG_VALUE $eax, $noreg, !3, !DIExpression(), debug-location !8
150 $eax = ADD32ri8 $eax, 3, implicit-def dead $eflags, implicit killed $rax, implicit-def $rax
151 DBG_VALUE $eax, $noreg, !3, !DIExpression(), debug-location !8
156 RETQ $eax, debug-location !9
162 tracksRegLiveness: true
165 - { reg: '$rdi', virtual-reg: '' }
167 ; Two DBG_VALUEs, one for eax, the other for zero, merge into bb3. Check that
168 ; livedebugvalues does not propagate anything.
170 ; CHECK-LABEL: name: bar
171 ; CHECK-LABEL: bb.1.bb1
172 ; CHECK: $eax = MOV32rr
173 ; CHECK-NEXT: DBG_VALUE 0
174 ; CHECK-NEXT: JMP_1 %bb.3
175 ; CHECK-LABEL: bb.2.bb2
176 ; CHECK: $eax = ADD32ri8
177 ; CHECK-NEXT: DBG_VALUE $eax
178 ; CHECK-NEXT: JMP_1 %bb.3
179 ; CHECK-LABEL: bb.3.bb3
180 ; CHECK-NOT: DBG_VALUE
181 ; Test for there being a location-list gap between bb1 and bb2, the variable
182 ; should not have a location over the ADD32ri. The range of the last entry
183 ; should not cover the last block.
184 ; RANGES-LABEL: DW_TAG_subprogram
185 ; RANGES: DW_AT_high_pc (0x[[BARHIGHPC:[0-9a-f]+]])
186 ; RANGES-LABEL: DW_AT_name ("bar")
187 ; RANGES: DW_AT_location (0x{{[0-9a-f]+}}
188 ; RANGES-NEXT: [0x{{[0-9a-f]+}}, 0x[[BARADDR:[0-9a-f]+]]): DW_OP_consts +0, DW_OP_stack_value
190 ; RANGES-NOT: 0x[[BARADDR]]
191 ; RANGES-NOT: 0x[[BARHIGHPC]]
192 ; RANGES-SAME: ): DW_OP_reg0 RAX
195 successors: %bb.1, %bb.2
198 $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
199 JCC_1 %bb.1, 2, implicit killed $eflags
206 $eax = MOV32rr killed $ecx, implicit-def $rax
207 DBG_VALUE 0, $noreg, !41, !DIExpression(), debug-location !42
214 $eax = ADD32ri8 $eax, 3, implicit-def dead $eflags, implicit killed $rax, implicit-def $rax
215 DBG_VALUE $eax, $noreg, !41, !DIExpression(), debug-location !42
220 RETQ $eax, debug-location !42
226 tracksRegLiveness: true
229 - { reg: '$rdi', virtual-reg: '' }
231 ; Two DBG_VALUEs, one for zero, the other for eax, merge into bb3. Check that
232 ; livedebugvalues does not propagate anything.
234 ; CHECK-LABEL: name: baz
235 ; CHECK-LABEL: bb.1.bb1
236 ; CHECK: $eax = MOV32rr
237 ; CHECK-NEXT: DBG_VALUE $eax
238 ; CHECK-NEXT: JMP_1 %bb.3
239 ; CHECK-LABEL: bb.2.bb2
240 ; CHECK: $eax = ADD32ri8
241 ; CHECK-NEXT: DBG_VALUE 0
242 ; CHECK-NEXT: JMP_1 %bb.3
243 ; CHECK-LABEL: bb.3.bb3
244 ; CHECK-NOT: DBG_VALUE
245 ; Test for there being a location-list gap between bb1 and bb2, the variable
246 ; should not have a location over the ADD32ri. The range of the last item
247 ; should not cover the last block.
248 ; RANGES-LABEL: DW_TAG_subprogram
249 ; RANGES: DW_AT_high_pc (0x[[BAZHIGHPC:[0-9a-f]+]])
250 ; RANGES-LABEL: DW_AT_name ("baz")
251 ; RANGES: DW_AT_location (0x{{[0-9a-f]+}}
252 ; RANGES-NEXT: [0x{{[0-9a-f]+}}, 0x[[BAZADDR:[0-9a-f]+]]): DW_OP_reg0 RAX
254 ; RANGES-NOT: 0x[[BAZADDR]]
255 ; RANGES-NOT: 0x[[BAZHIGHPC]]
256 ; RANGES-SAME: ): DW_OP_consts +0, DW_OP_stack_value
259 successors: %bb.1, %bb.2
262 $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
263 JCC_1 %bb.1, 2, implicit killed $eflags
270 $eax = MOV32rr killed $ecx, implicit-def $rax
271 DBG_VALUE $eax, $noreg, !81, !DIExpression(), debug-location !82
278 $eax = ADD32ri8 $eax, 3, implicit-def dead $eflags, implicit killed $rax, implicit-def $rax
279 DBG_VALUE 0, $noreg, !81, !DIExpression(), debug-location !82
284 RETQ $eax, debug-location !82
290 tracksRegLiveness: true
293 - { reg: '$rdi', virtual-reg: '' }
295 ; Two DBG_VALUEs for zero merging into bb3, Check that livedebugvalues does
296 ; propagate the zero into the merging block.
297 ; CHECK-LABEL: name: qux
298 ; CHECK-LABEL: bb.1.bb1
299 ; CHECK: $eax = MOV32rr
300 ; CHECK-NEXT: DBG_VALUE 0
301 ; CHECK-NEXT: JMP_1 %bb.3
302 ; CHECK-LABEL: bb.2.bb2
303 ; CHECK: $eax = ADD32ri8
304 ; CHECK-NEXT: DBG_VALUE 0
305 ; CHECK-NEXT: JMP_1 %bb.3
306 ; CHECK-LABEL: bb.3.bb3
308 ; Test for there being a location-list gap between bb1 and bb2, the variable
309 ; should not have a location over the ADD32ri. The final entry should cover
311 ; RANGES-LABEL: DW_TAG_subprogram
312 ; RANGES: DW_AT_high_pc (0x[[QUXHIGHPC:[0-9a-f]+]])
313 ; RANGES-LABEL: DW_AT_name ("qux")
314 ; RANGES: DW_AT_location (0x{{[0-9a-f]+}}
315 ; RANGES-NEXT: [0x{{[0-9a-f]+}}, 0x[[QUXADDR:[0-9a-f]+]]): DW_OP_consts +0, DW_OP_stack_value
316 ; RANGES-NOT: 0x[[QUXADDR]]
317 ; RANGES-NEXT: [0x{{[0-9a-f]+}}, 0x[[QUXHIGHPC]]): DW_OP_consts +0, DW_OP_stack_value
320 successors: %bb.1, %bb.2
323 $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
324 JCC_1 %bb.1, 2, implicit killed $eflags
331 $eax = MOV32rr killed $ecx, implicit-def $rax
332 DBG_VALUE 0, $noreg, !121, !DIExpression(), debug-location !122
339 $eax = ADD32ri8 $eax, 3, implicit-def dead $eflags, implicit killed $rax, implicit-def $rax
340 DBG_VALUE 0, $noreg, !121, !DIExpression(), debug-location !122
345 RETQ $eax, debug-location !122