xref: /llvm-project/llvm/test/DebugInfo/MIR/X86/live-debug-values-fragments.mir (revision 676efd0ffb717215c752f200fe14163732290dcc)
1# RUN: llc %s -o - -run-pass=livedebugvalues -experimental-debug-variable-locations=true | FileCheck %s
2#
3# The first func tests that, for two independent variable fragments defined in
4# blocks 1 and 2, _both_ their locations are propagated into the exit block.
5# LiveDebugValues previously ignored fragments and only propagated the last
6# variable location seen.
7#
8# The second func tests that overlapping variable fragments are handled
9# correctly -- that the redefinition of a particular fragment also clobbers
10# any overlaps. The dbg value of $cx in block one should not be propagated to
11# block two, because an overlapping dbg value inst has been encountered.
12#
13# The third function checks that DBG_VALUEs without fragments are seen as
14# overlapping any DBG_VALUE with a fragment.
15#
16# CHECK-LABEL: foo
17# CHECK-LABEL: bb.3.bb3:
18# CHECK:      DBG_VALUE $ecx, $noreg, !{{[0-9]+}},
19# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 0, 32)
20# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
21# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 0, 32)
22# CHECK-SAME:                 $ecx, $r8d
23# CHECK-NEXT: DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
24# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 32, 32)
25# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
26# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 32, 32)
27# CHECK-SAME:                 $ebx, $r10d
28# CHECK-NEXT: XOR32rr
29# CHECK-NEXT: RET64
30#
31# CHECK-LABEL: bar
32# CHECK-LABEL: bb.0.entry:
33# CHECK:      DBG_VALUE $cx, $noreg, !{{[0-9]+}},
34# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 0, 16)
35# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
36# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 0, 16)
37# CHECK-SAME:                 $cx, $r8w
38
39# CHECK-LABEL: bb.1.bb1:
40# CHECK:      DBG_VALUE $cx, $noreg, !{{[0-9]+}},
41# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 0, 16)
42# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
43# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 0, 16)
44# CHECK-SAME:                 $cx, $r8w
45# CHECK-NEXT: MOV32rr
46# CHECK-NEXT: MOV32rr
47# CHECK-NEXT: DBG_VALUE $ax, $noreg, !{{[0-9]+}},
48# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 8, 16)
49# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
50# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 8, 16)
51# CHECK-SAME:                 $ax, $r9w
52# CHECK-NEXT: JMP_1
53
54# CHECK-LABEL: bb.2.bb2:
55# CHECK-NOT:  DBG_VALUE
56# CHECK-NOT:  DBG_VALUE_LIST
57# CHECK:      DBG_VALUE $cx, $noreg, !{{[0-9]+}},
58# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 8, 16)
59# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
60# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 8, 16)
61# CHECK-SAME:                 $cx, $r8w
62# CHECK-NEXT: MOV32rr
63# CHECK-NEXT: ADD32ri8
64# CHECK-NEXT: MOV32rr
65# CHECK-NEXT: ADD32ri8
66# CHECK-NEXT: DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
67# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 32, 32)
68# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
69# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 32, 32)
70# CHECK-SAME:                 $ebx, $r10d
71# CHECK-NEXT: JMP_1
72
73# CHECK-LABEL: bb.3.bb3:
74# CHECK:      DBG_VALUE $cx, $noreg, !{{[0-9]+}},
75# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 8, 16)
76# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
77# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 8, 16)
78# CHECK-SAME:                 $cx, $r8w
79# CHECK-NEXT: DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
80# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 32, 32)
81# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
82# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 32, 32)
83# CHECK-SAME:                 $ebx, $r10d
84# CHECK-NEXT: XOR32rr
85# CHECK-NEXT: RET64
86
87# CHECK-LABEL: baz
88# CHECK-LABEL: bb.0.entry:
89# CHECK:      DBG_VALUE $cx,  $noreg, !{{[0-9]+}},
90# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 0, 16)
91# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
92# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 0, 16)
93# CHECK-SAME:                 $cx, $r8w
94# CHECK-NEXT: JMP_1 %bb.1
95#
96# CHECK-LABEL: bb.1.bb1:
97# CHECK:      DBG_VALUE $cx,  $noreg, !{{[0-9]+}},
98# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 0, 16)
99# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
100# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 0, 16)
101# CHECK-SAME:                 $cx, $r8w
102# CHECK-NEXT: MOV32rr
103# CHECK-NEXT: MOV32rr
104# CHECK-NEXT: DBG_VALUE $rdi, $noreg, !{{[0-9]+}}, !DIExpression()
105# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}}, !DIExpression({{[^)]+}}), $rdi, $rdi
106# CHECK-NEXT: JMP_1 %bb.2
107#
108# CHECK-LABEL: bb.2.bb2:
109# CHECK-NOT:  DBG_VALUE $cx
110# CHECK-NOT:  DBG_VALUE_LIST {{.+}}, $cx
111# CHECK:      DBG_VALUE $rdi, $noreg, !{{[0-9]+}}, !DIExpression()
112# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}}, !DIExpression({{[^)]+}}), $rdi, $rdi
113# CHECK-NEXT: MOV32rr
114# CHECK-NEXT: ADD32ri8
115# CHECK-NEXT: MOV32rr
116# CHECK-NEXT: ADD32ri8
117# CHECK-NEXT: DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
118# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 32, 32)
119# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
120# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 32, 32)
121# CHECK-SAME:                 $ebx, $r10d
122# CHECK-NEXT: JMP_1 %bb.3
123#
124# CHECK-LABEL: bb.3.bb3:
125# CHECK-NOT:  DBG_VALUE $rdi
126# CHECK-NOT:  DBG_VALUE $cx
127# CHECK-NOT:  DBG_VALUE_LIST {{.+}}, $rdi
128# CHECK-NOT:  DBG_VALUE_LIST {{.+}}, $cx
129# CHECK:      DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
130# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 32, 32)
131# CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]+}},
132# CHECK-SAME:                 !DIExpression({{[^)]+}}, DW_OP_LLVM_fragment, 32, 32)
133# CHECK-SAME:                 $ebx, $r10d
134# CHECK-NEXT: XOR32rr
135# CHECK-NEXT: RET64
136
137--- |
138  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
139  target triple = "x86_64-unknown-linux-gnu"
140
141  define i32 @foo(ptr %bees, ptr %output) !dbg !4 {
142  entry:
143    br label %bb1
144  bb1:
145    br label %bb2
146  bb2:
147    br label %bb3
148  bb3:
149    ret i32 0
150  }
151
152  define i32 @bar(ptr %bees, ptr %output) !dbg !40 {
153  entry:
154    br label %bb1
155  bb1:
156    br label %bb2
157  bb2:
158    br label %bb3
159  bb3:
160    ret i32 0
161  }
162
163  define i32 @baz(ptr %bees, ptr %output) !dbg !80 {
164  entry:
165    br label %bb1
166  bb1:
167    br label %bb2
168  bb2:
169    br label %bb3
170  bb3:
171    ret i32 0
172  }
173
174  !llvm.module.flags = !{!0, !100}
175  !llvm.dbg.cu = !{!1}
176
177  !100 = !{i32 2, !"Dwarf Version", i32 4}
178  !0 = !{i32 2, !"Debug Info Version", i32 3}
179  !1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "beards", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
180  !2 = !DIFile(filename: "bees.cpp", directory: ".")
181  !3 = !DILocalVariable(name: "flannel", scope: !4, file: !2, line: 1, type: !16)
182  !4 = distinct !DISubprogram(name: "nope", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true)
183  !5 = !DILocalVariable(name: "panel", scope: !4, file: !2, line: 1, type: !16)
184  !8 = !DILocation(line: 4, scope: !4)
185  !13 = !{!3, !5}
186  !14 = !DISubroutineType(types: !15)
187  !15 = !{!16}
188  !16 = !DIBasicType(name: "looong", size: 64, align: 64, encoding: DW_ATE_signed)
189  !40 = distinct !DISubprogram(name: "toast", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !53, type: !14, isDefinition: true)
190  !43 = !DILocalVariable(name: "charm", scope: !40, file: !2, line: 1, type: !16)
191  !44 = !DILocalVariable(name: "calm", scope: !40, file: !2, line: 1, type: !16)
192  !48 = !DILocation(line: 4, scope: !40)
193  !53 = !{!43, !44}
194  !80 = distinct !DISubprogram(name: "mort", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !93, type: !14, isDefinition: true)
195  !81 = distinct !DISubprogram(name: "floor", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !93, type: !14, isDefinition: true)
196  !83 = !DILocalVariable(name: "bodkin", scope: !80, file: !2, line: 1, type: !16)
197  !84 = !DILocalVariable(name: "goblin", scope: !80, file: !2, line: 1, type: !16)
198  !88 = !DILocation(line: 4, scope: !80)
199  !93 = !{!83, !84}
200
201...
202---
203name:            foo
204tracksRegLiveness: true
205debugInstrRef: true
206registers:       []
207liveins:
208  - { reg: '$rdi', virtual-reg: '' }
209body:             |
210  bb.0.entry:
211    successors: %bb.1
212    liveins: $rdi
213
214    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
215    $r8d = XOR32rr undef $r8d, undef $r8d, implicit-def $eflags
216    JMP_1 %bb.1
217
218  bb.1.bb1 (align 4):
219    successors: %bb.2
220    liveins: $ecx, $edx, $rdi, $r8d
221
222    $eax = MOV32rr killed $ecx, implicit-def $rax
223    $r9d = MOV32rr killed $r8d, implicit-def $r9
224    DBG_VALUE $eax, $noreg, !3, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !8
225    DBG_VALUE_LIST !5, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_fragment, 0, 32), $eax, $r9d, debug-location !8
226    JMP_1 %bb.2
227
228  bb.2.bb2:
229    successors: %bb.3
230    liveins: $eax, $r9d
231
232    $ebx = MOV32rr $eax
233    $ebx = ADD32ri8 $ebx, 3, implicit-def dead $eflags, implicit killed $rbx, implicit-def $rbx
234    $r10d = MOV32rr $r9d
235    $r10d = ADD32ri8 $r10d, 3, implicit-def dead $eflags, implicit killed $rbx, implicit-def $rbx
236    DBG_VALUE $ebx, $noreg, !3, !DIExpression(DW_OP_LLVM_fragment, 32, 32), debug-location !8
237    DBG_VALUE_LIST !5, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_fragment, 32, 32), $ebx, $r10d, debug-location !8
238    JMP_1 %bb.3
239
240  bb.3.bb3:
241    liveins: $eax, $ebx, $r9d, $r10d
242    $eax = XOR32rr killed $eax, killed $ebx, implicit-def $eflags
243    RET64 $eax, debug-location !8
244
245...
246---
247name:            bar
248tracksRegLiveness: true
249debugInstrRef: true
250registers:       []
251liveins:
252  - { reg: '$rdi', virtual-reg: '' }
253body:             |
254  bb.0.entry:
255    successors: %bb.1
256    liveins: $rdi
257
258    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
259    $r8d = XOR32rr undef $r8d, undef $r8d, implicit-def $eflags
260    DBG_VALUE $cx, $noreg, !43, !DIExpression(DW_OP_LLVM_fragment, 0, 16), debug-location !48
261    DBG_VALUE_LIST !44, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_fragment, 0, 16), $cx, $r8w, debug-location !48
262    JMP_1 %bb.1
263
264  bb.1.bb1:
265    successors: %bb.2
266    liveins: $ecx, $r8d, $rdi
267
268    $eax = MOV32rr killed $ecx, implicit-def $rax
269    $r9d = MOV32rr killed $r8d, implicit-def $rax
270    DBG_VALUE $ax, $noreg, !43, !DIExpression(DW_OP_LLVM_fragment, 8, 16), debug-location !48
271    DBG_VALUE_LIST !44, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_fragment, 8, 16), $ax, $r9w, debug-location !48
272    JMP_1 %bb.2
273
274  bb.2.bb2:
275    successors: %bb.3
276    liveins: $eax, $r9d
277
278    $ebx = MOV32rr $eax
279    $ebx = ADD32ri8 $ebx, 3, implicit-def dead $eflags, implicit killed $rbx, implicit-def $rbx
280    $r10d = MOV32rr $r9d
281    $r10d = ADD32ri8 $r10d, 3, implicit-def dead $eflags, implicit killed $rbx, implicit-def $rbx
282    DBG_VALUE $ebx, $noreg, !43, !DIExpression(DW_OP_LLVM_fragment, 32, 32), debug-location !48
283    DBG_VALUE_LIST !44, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_fragment, 32, 32), $ebx, $r10d, debug-location !48
284    JMP_1 %bb.3
285
286  bb.3.bb3:
287    liveins: $eax, $ebx, $r9d, $r10d
288    $eax = XOR32rr killed $eax, killed $ebx, implicit-def $eflags
289    RET64 $eax, debug-location !48
290
291...
292---
293name:            baz
294tracksRegLiveness: true
295debugInstrRef: true
296registers:       []
297liveins:
298  - { reg: '$rdi', virtual-reg: '' }
299body:             |
300  bb.0.entry:
301    successors: %bb.1
302    liveins: $rdi
303
304    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
305    $r8d = XOR32rr undef $r8d, undef $r8d, implicit-def $eflags
306    DBG_VALUE $cx, $noreg, !83, !DIExpression(DW_OP_LLVM_fragment, 0, 16), debug-location !88
307    DBG_VALUE_LIST !84, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_fragment, 0, 16), $cx, $r8w, debug-location !88
308    JMP_1 %bb.1
309
310  bb.1.bb1:
311    successors: %bb.2
312    liveins: $ecx, $r8d, $rdi
313
314    $eax = MOV32rr killed $ecx, implicit-def $rax
315    $r9d = MOV32rr killed $r8d, implicit-def $r9
316    DBG_VALUE $rdi, $noreg, !83, !DIExpression(), debug-location !88
317    DBG_VALUE_LIST !84, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), $rdi, $rdi, debug-location !88
318    JMP_1 %bb.2
319
320  bb.2.bb2:
321    successors: %bb.3
322    liveins: $eax, $r9d
323
324    $ebx = MOV32rr $eax
325    $ebx = ADD32ri8 $ebx, 3, implicit-def dead $eflags, implicit killed $rbx, implicit-def $rbx
326    $r10d = MOV32rr $r9d
327    $r10d = ADD32ri8 $r10d, 3, implicit-def dead $eflags, implicit killed $r10, implicit-def $r10
328    DBG_VALUE $ebx, $noreg, !83, !DIExpression(DW_OP_LLVM_fragment, 32, 32), debug-location !88
329    DBG_VALUE_LIST !84, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_fragment, 32, 32), $ebx, $r10d, debug-location !88
330    JMP_1 %bb.3
331
332  bb.3.bb3:
333    liveins: $eax, $ebx
334    $eax = XOR32rr killed $eax, killed $ebx, implicit-def $eflags
335    RET64 $eax, debug-location !88
336
337...
338