1# RUN: llc %s -o - -run-pass=livedebugvalues | 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 $ebx, $noreg, !{{[0-9]+}},
19# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 32, 32)
20# CHECK-NEXT: DBG_VALUE $eax, $noreg, !{{[0-9]+}},
21# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 0, 32)
22# CHECK-NEXT: XOR32rr
23# CHECK-NEXT: RETQ
24#
25# CHECK-LABEL: bar
26# CHECK-LABEL: bb.0.entry:
27# CHECK:      DBG_VALUE $cx, $noreg, !{{[0-9]+}},
28# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 0, 16)
29
30# CHECK-LABEL: bb.1.bb1:
31# CHECK:      DBG_VALUE $cx, $noreg, !{{[0-9]+}},
32# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 0, 16)
33# CHECK-NEXT: MOV32rr
34# CHECK-NEXT: DBG_VALUE $ax, $noreg, !{{[0-9]+}},
35# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 8, 16)
36# CHECK-NEXT: JMP_1
37
38# CHECK-LABEL: bb.2.bb2:
39# CHECK-NOT:  DBG_VALUE
40# CHECK:      DBG_VALUE $ax, $noreg, !{{[0-9]+}},
41# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 8, 16)
42# CHECK-NEXT: MOV32rr
43# CHECK-NEXT: ADD32ri8
44# CHECK-NEXT: DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
45# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 32, 32)
46# CHECK-NEXT: JMP_1
47
48# CHECK-LABEL: bb.3.bb3:
49# CHECK:      DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
50# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 32, 32)
51# CHECK-NEXT: DBG_VALUE $ax, $noreg, !{{[0-9]+}},
52# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 8, 16)
53# CHECK-NEXT: XOR32rr
54# CHECK-NEXT: RETQ
55
56# CHECK-LABEL: baz
57# CHECK-LABEL: bb.0.entry:
58# CHECK:      DBG_VALUE $cx,  $noreg, !{{[0-9]+}},
59# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 0, 16)
60# CHECK-NEXT: JMP_1 %bb.1
61#
62# CHECK-LABEL: bb.1.bb1:
63# CHECK:      DBG_VALUE $cx,  $noreg, !{{[0-9]+}},
64# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 0, 16)
65# CHECK-NEXT: MOV32rr
66# CHECK-NEXT: DBG_VALUE $rdi, $noreg, !{{[0-9]+}}, !DIExpression()
67# CHECK-NEXT: JMP_1 %bb.2
68#
69# CHECK-LABEL: bb.2.bb2:
70# CHECK-NOT:  DBG_VALUE $cx
71# CHECK:      DBG_VALUE $rdi, $noreg, !{{[0-9]+}}, !DIExpression()
72# CHECK-NEXT: MOV32rr
73# CHECK-NEXT: ADD32ri8
74# CHECK-NEXT: DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
75# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 32, 32)
76# CHECK-NEXT: JMP_1 %bb.3
77#
78# CHECK-LABEL: bb.3.bb3:
79# CHECK-NOT:  DBG_VALUE $rdi
80# CHECK-NOT:  DBG_VALUE $cx
81# CHECK:      DBG_VALUE $ebx, $noreg, !{{[0-9]+}},
82# CHECK-SAME:                 !DIExpression(DW_OP_LLVM_fragment, 32, 32)
83# CHECK-NEXT: XOR32rr
84# CHECK-NEXT: RETQ
85
86--- |
87  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
88  target triple = "x86_64-unknown-linux-gnu"
89
90  define i32 @foo(i32* %bees, i32* %output) !dbg !4 {
91  entry:
92    br label %bb1
93  bb1:
94    br label %bb2
95  bb2:
96    br label %bb3
97  bb3:
98    ret i32 0
99  }
100
101  define i32 @bar(i32* %bees, i32* %output) !dbg !40 {
102  entry:
103    br label %bb1
104  bb1:
105    br label %bb2
106  bb2:
107    br label %bb3
108  bb3:
109    ret i32 0
110  }
111
112  define i32 @baz(i32* %bees, i32* %output) !dbg !80 {
113  entry:
114    br label %bb1
115  bb1:
116    br label %bb2
117  bb2:
118    br label %bb3
119  bb3:
120    ret i32 0
121  }
122
123  !llvm.module.flags = !{!0, !100}
124  !llvm.dbg.cu = !{!1}
125
126  !100 = !{i32 2, !"Dwarf Version", i32 4}
127  !0 = !{i32 2, !"Debug Info Version", i32 3}
128  !1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "beards", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
129  !2 = !DIFile(filename: "bees.cpp", directory: ".")
130  !3 = !DILocalVariable(name: "flannel", scope: !4, file: !2, line: 1, type: !16)
131  !4 = distinct !DISubprogram(name: "nope", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true)
132  !8 = !DILocation(line: 4, scope: !4)
133  !13 = !{!3}
134  !14 = !DISubroutineType(types: !15)
135  !15 = !{!16}
136  !16 = !DIBasicType(name: "looong", size: 64, align: 64, encoding: DW_ATE_signed)
137  !40 = distinct !DISubprogram(name: "toast", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !53, type: !14, isDefinition: true)
138  !43 = !DILocalVariable(name: "charm", scope: !40, file: !2, line: 1, type: !16)
139  !48 = !DILocation(line: 4, scope: !40)
140  !53 = !{!43}
141  !80 = distinct !DISubprogram(name: "mort", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !93, type: !14, isDefinition: true)
142  !83 = !DILocalVariable(name: "bodkin", scope: !80, file: !2, line: 1, type: !16)
143  !88 = !DILocation(line: 4, scope: !80)
144  !93 = !{!83}
145
146...
147---
148name:            foo
149tracksRegLiveness: true
150registers:       []
151liveins:
152  - { reg: '$rdi', virtual-reg: '' }
153body:             |
154  bb.0.entry:
155    successors: %bb.1
156    liveins: $rdi
157
158    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
159    JMP_1 %bb.1
160
161  bb.1.bb1 (align 4):
162    successors: %bb.2
163    liveins: $ecx, $rdi
164
165    $eax = MOV32rr killed $ecx, implicit-def $rax
166    DBG_VALUE $eax, $noreg, !3, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !8
167    JMP_1 %bb.2
168
169  bb.2.bb2:
170    successors: %bb.3
171    liveins: $eax
172
173    $ebx = MOV32rr $eax
174    $ebx = ADD32ri8 $ebx, 3, implicit-def dead $eflags, implicit killed $rbx, implicit-def $rbx
175    DBG_VALUE $ebx, $noreg, !3, !DIExpression(DW_OP_LLVM_fragment, 32, 32), debug-location !8
176    JMP_1 %bb.3
177
178  bb.3.bb3:
179    liveins: $eax, $ebx
180    $eax = XOR32rr killed $eax, killed $ebx, implicit-def $eflags
181    RETQ $eax, debug-location !8
182
183...
184---
185name:            bar
186tracksRegLiveness: true
187registers:       []
188liveins:
189  - { reg: '$rdi', virtual-reg: '' }
190body:             |
191  bb.0.entry:
192    successors: %bb.1
193    liveins: $rdi
194
195    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
196    DBG_VALUE $cx, $noreg, !43, !DIExpression(DW_OP_LLVM_fragment, 0, 16), debug-location !48
197    JMP_1 %bb.1
198
199  bb.1.bb1:
200    successors: %bb.2
201    liveins: $ecx, $rdi
202
203    $eax = MOV32rr killed $ecx, implicit-def $rax
204    DBG_VALUE $ax, $noreg, !43, !DIExpression(DW_OP_LLVM_fragment, 8, 16), debug-location !48
205    JMP_1 %bb.2
206
207  bb.2.bb2:
208    successors: %bb.3
209    liveins: $eax
210
211    $ebx = MOV32rr $eax
212    $ebx = ADD32ri8 $ebx, 3, implicit-def dead $eflags, implicit killed $rbx, implicit-def $rbx
213    DBG_VALUE $ebx, $noreg, !43, !DIExpression(DW_OP_LLVM_fragment, 32, 32), debug-location !48
214    JMP_1 %bb.3
215
216  bb.3.bb3:
217    liveins: $eax, $ebx
218    $eax = XOR32rr killed $eax, killed $ebx, implicit-def $eflags
219    RETQ $eax, debug-location !48
220
221...
222---
223name:            baz
224tracksRegLiveness: true
225registers:       []
226liveins:
227  - { reg: '$rdi', virtual-reg: '' }
228body:             |
229  bb.0.entry:
230    successors: %bb.1
231    liveins: $rdi
232
233    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
234    DBG_VALUE $cx, $noreg, !83, !DIExpression(DW_OP_LLVM_fragment, 0, 16), debug-location !88
235    JMP_1 %bb.1
236
237  bb.1.bb1:
238    successors: %bb.2
239    liveins: $ecx, $rdi
240
241    $eax = MOV32rr killed $ecx, implicit-def $rax
242    DBG_VALUE $rdi, $noreg, !83, !DIExpression(), debug-location !88
243    JMP_1 %bb.2
244
245  bb.2.bb2:
246    successors: %bb.3
247    liveins: $eax
248
249    $ebx = MOV32rr $eax
250    $ebx = ADD32ri8 $ebx, 3, implicit-def dead $eflags, implicit killed $rbx, implicit-def $rbx
251    DBG_VALUE $ebx, $noreg, !83, !DIExpression(DW_OP_LLVM_fragment, 32, 32), debug-location !88
252    JMP_1 %bb.3
253
254  bb.3.bb3:
255    liveins: $eax, $ebx
256    $eax = XOR32rr killed $eax, killed $ebx, implicit-def $eflags
257    RETQ $eax, debug-location !88
258
259...
260