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