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.
6--- |
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"
10
11  define i32 @foo(i32* %bees, i32* %output) !dbg !4 {
12  entry:
13    br i1 undef, label %bb1, label %bb1
14  bb1:
15    br label %bb3
16  bb2:
17    br label %bb3
18  bb3:
19    ret i32 0
20  }
21
22  define i32 @bar(i32* %bees, i32* %output) !dbg !40 {
23  entry:
24    br i1 undef, label %bb1, label %bb1
25  bb1:
26    br label %bb3
27  bb2:
28    br label %bb3
29  bb3:
30    ret i32 0
31  }
32
33  define i32 @baz(i32* %bees, i32* %output) !dbg !80 {
34  entry:
35    br i1 undef, label %bb1, label %bb1
36  bb1:
37    br label %bb3
38  bb2:
39    br label %bb3
40  bb3:
41    ret i32 0
42  }
43
44  define i32 @qux(i32* %bees, i32* %output) !dbg !120 {
45  entry:
46    br i1 undef, label %bb1, label %bb1
47  bb1:
48    br label %bb3
49  bb2:
50    br label %bb3
51  bb3:
52    ret i32 0
53  }
54
55  ; Function Attrs: nounwind readnone speculatable
56  declare void @llvm.dbg.value(metadata, metadata, metadata)
57
58  ; Function Attrs: nounwind readnone speculatable
59  declare void @llvm.dbg.declare(metadata, metadata, metadata)
60
61  ; Function Attrs: nounwind
62  declare void @llvm.stackprotector(i8*, i8**)
63
64  !llvm.module.flags = !{!0, !100}
65  !llvm.dbg.cu = !{!1}
66
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)
81  !13 = !{!3}
82  !14 = !DISubroutineType(types: !15)
83  !15 = !{!16}
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)
94
95...
96---
97name:            foo
98alignment:       16
99tracksRegLiveness: true
100registers:       []
101liveins:
102  - { reg: '$rdi', virtual-reg: '' }
103body:             |
104
105  ; Two DBG_VALUEs for eax merge into bb3, check that livedebugvalues propagates
106  ; the location.
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
126  ; RANGES-NEXT:   [
127  ; RANGES-NOT:    0x[[NOPEADDR]]
128  ; RANGES-SAME:   , 0x[[NOPEHIGHPC]]): DW_OP_reg0 RAX
129
130  bb.0.entry:
131    successors: %bb.1, %bb.2
132    liveins: $rdi
133
134    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
135    JCC_1 %bb.1, 2, implicit killed $eflags
136    JMP_1 %bb.2
137
138  bb.1.bb1 (align 4):
139    successors: %bb.3
140    liveins: $ecx, $rdi
141
142    $eax = MOV32rr killed $ecx, implicit-def $rax
143    DBG_VALUE $eax, $noreg, !3, !DIExpression(), debug-location !8
144    JMP_1 %bb.3
145
146  bb.2.bb2:
147    successors: %bb.3
148    liveins: $rax
149
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
152    JMP_1 %bb.3
153
154  bb.3.bb3:
155    liveins: $rax
156    RETQ $eax, debug-location !9
157
158...
159---
160name:            bar
161alignment:       16
162tracksRegLiveness: true
163registers:       []
164liveins:
165  - { reg: '$rdi', virtual-reg: '' }
166body:             |
167  ; Two DBG_VALUEs, one for eax, the other for zero, merge into bb3. Check that
168  ; livedebugvalues does not propagate anything.
169  ; the location.
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
189  ; RANGES-NEXT:   [
190  ; RANGES-NOT:    0x[[BARADDR]]
191  ; RANGES-NOT:    0x[[BARHIGHPC]]
192  ; RANGES-SAME:   ): DW_OP_reg0 RAX
193
194  bb.0.entry:
195    successors: %bb.1, %bb.2
196    liveins: $rdi
197
198    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
199    JCC_1 %bb.1, 2, implicit killed $eflags
200    JMP_1 %bb.2
201
202  bb.1.bb1 (align 4):
203    successors: %bb.3
204    liveins: $ecx, $rdi
205
206    $eax = MOV32rr killed $ecx, implicit-def $rax
207    DBG_VALUE 0, $noreg, !41, !DIExpression(), debug-location !42
208    JMP_1 %bb.3
209
210  bb.2.bb2:
211    successors: %bb.3
212    liveins: $rax
213
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
216    JMP_1 %bb.3
217
218  bb.3.bb3:
219    liveins: $rax
220    RETQ $eax, debug-location !42
221
222...
223---
224name:            baz
225alignment:       16
226tracksRegLiveness: true
227registers:       []
228liveins:
229  - { reg: '$rdi', virtual-reg: '' }
230body:             |
231  ; Two DBG_VALUEs, one for zero, the other for eax, merge into bb3. Check that
232  ; livedebugvalues does not propagate anything.
233  ; the location.
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
253  ; RANGES-NEXT:   [
254  ; RANGES-NOT:    0x[[BAZADDR]]
255  ; RANGES-NOT:    0x[[BAZHIGHPC]]
256  ; RANGES-SAME:   ): DW_OP_consts +0, DW_OP_stack_value
257
258  bb.0.entry:
259    successors: %bb.1, %bb.2
260    liveins: $rdi
261
262    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
263    JCC_1 %bb.1, 2, implicit killed $eflags
264    JMP_1 %bb.2
265
266  bb.1.bb1 (align 4):
267    successors: %bb.3
268    liveins: $ecx, $rdi
269
270    $eax = MOV32rr killed $ecx, implicit-def $rax
271    DBG_VALUE $eax, $noreg, !81, !DIExpression(), debug-location !82
272    JMP_1 %bb.3
273
274  bb.2.bb2:
275    successors: %bb.3
276    liveins: $rax
277
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
280    JMP_1 %bb.3
281
282  bb.3.bb3:
283    liveins: $rax
284    RETQ $eax, debug-location !82
285
286...
287---
288name:            qux
289alignment:       16
290tracksRegLiveness: true
291registers:       []
292liveins:
293  - { reg: '$rdi', virtual-reg: '' }
294body:             |
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
307  ; CHECK:       DBG_VALUE 0
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
310  ; the final block.
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
318
319  bb.0.entry:
320    successors: %bb.1, %bb.2
321    liveins: $rdi
322
323    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
324    JCC_1 %bb.1, 2, implicit killed $eflags
325    JMP_1 %bb.2
326
327  bb.1.bb1 (align 4):
328    successors: %bb.3
329    liveins: $ecx, $rdi
330
331    $eax = MOV32rr killed $ecx, implicit-def $rax
332    DBG_VALUE 0, $noreg, !121, !DIExpression(), debug-location !122
333    JMP_1 %bb.3
334
335  bb.2.bb2:
336    successors: %bb.3
337    liveins: $rax
338
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
341    JMP_1 %bb.3
342
343  bb.3.bb3:
344    liveins: $rax
345    RETQ $eax, debug-location !122
346
347...
348