Commit e2f94974 authored by Jeremy Morse's avatar Jeremy Morse
Browse files

[DebugInfo] Add a test that fell out of an earlier commit

r362951 was supposed to contain this test, however it didn't get committed
due to operator error. This was originally part of D59431.

llvm-svn: 363161
parent 2466ba97
Loading
Loading
Loading
Loading
+347 −0
Original line number Diff line number Diff line
# RUN: llc %s -o - -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=CHECK
# RUN: llc %s -o - -start-before=livedebugvalues -filetype=obj -mtriple=x86_64-unknown-unknown | llvm-dwarfdump - | FileCheck %s --check-prefix=RANGES
# Check that livedebugvalues does the right thing when register and constant
# DBG_VALUEs interact, and that their ranges are correctly terminated by the
# debug printing backend.
--- |
  ; All these IR functions are duds, see the MIR below.
  source_filename = "<stdin>"
  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
  
  define i32 @foo(i32* %bees, i32* %output) !dbg !4 {
  entry:
    br i1 undef, label %bb1, label %bb1
  bb1:
    br label %bb3
  bb2:
    br label %bb3
  bb3:
    ret i32 0
  }

  define i32 @bar(i32* %bees, i32* %output) !dbg !40 {
  entry:
    br i1 undef, label %bb1, label %bb1
  bb1:
    br label %bb3
  bb2:
    br label %bb3
  bb3:
    ret i32 0
  }

  define i32 @baz(i32* %bees, i32* %output) !dbg !80 {
  entry:
    br i1 undef, label %bb1, label %bb1
  bb1:
    br label %bb3
  bb2:
    br label %bb3
  bb3:
    ret i32 0
  }

  define i32 @qux(i32* %bees, i32* %output) !dbg !120 {
  entry:
    br i1 undef, label %bb1, label %bb1
  bb1:
    br label %bb3
  bb2:
    br label %bb3
  bb3:
    ret i32 0
  }

  ; Function Attrs: nounwind readnone speculatable
  declare void @llvm.dbg.value(metadata, metadata, metadata)
  
  ; Function Attrs: nounwind readnone speculatable
  declare void @llvm.dbg.declare(metadata, metadata, metadata)
  
  ; Function Attrs: nounwind
  declare void @llvm.stackprotector(i8*, i8**)
  
  !llvm.module.flags = !{!0, !100}
  !llvm.dbg.cu = !{!1}
  
  !100 = !{i32 2, !"Dwarf Version", i32 4}
  !0 = !{i32 2, !"Debug Info Version", i32 3}
  !1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "beards", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
  !2 = !DIFile(filename: "bees.cpp", directory: ".")
  !3 = !DILocalVariable(name: "flannel", scope: !4, file: !2, line: 1, type: !16)
  !4 = distinct !DISubprogram(name: "nope", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true)
  !5 = !DILocation(line: 0, scope: !4)
  !6 = !DILocation(line: 1, scope: !4)
  !7 = !DILocation(line: 2, scope: !4)
  !8 = !DILocation(line: 4, scope: !4)
  !9 = !DILocation(line: 5, scope: !4)
  !10 = !DILocation(line: 6, scope: !4)
  !11 = !DILocation(line: 7, scope: !4)
  !12 = !DILocation(line: 8, scope: !4)
  !13 = !{!3}
  !14 = !DISubroutineType(types: !15)
  !15 = !{!16}
  !16 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
  !40 = distinct !DISubprogram(name: "bar", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true)
  !41 = !DILocalVariable(name: "towel", scope: !40, file: !2, line: 1, type: !16)
  !42 = !DILocation(line: 40, scope: !40)
  !80 = distinct !DISubprogram(name: "baz", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true)
  !81 = !DILocalVariable(name: "socks", scope: !80, file: !2, line: 1, type: !16)
  !82 = !DILocation(line: 40, scope: !80)
  !120 = distinct !DISubprogram(name: "qux", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true)
  !121 = !DILocalVariable(name: "shoes", scope: !120, file: !2, line: 1, type: !16)
  !122 = !DILocation(line: 40, scope: !120)

...
---
name:            foo
alignment:       4
tracksRegLiveness: true
registers:       []
liveins:         
  - { reg: '$rdi', virtual-reg: '' }
body:             |

  ; Two DBG_VALUEs for eax merge into bb3, check that livedebugvalues propagates
  ; the location.
  ; CHECK-LABEL: name: foo
  ; CHECK-LABEL: bb.1.bb1
  ; CHECK:       $eax = MOV32rr
  ; CHECK-NEXT:  DBG_VALUE $eax
  ; CHECK-NEXT:  JMP_1 %bb.3
  ; CHECK-LABEL: bb.2.bb2
  ; CHECK:       $eax = ADD32ri8
  ; CHECK-NEXT:  DBG_VALUE $eax
  ; CHECK-NEXT:  JMP_1 %bb.3
  ; CHECK-LABEL: bb.3.bb3
  ; CHECK:       DBG_VALUE $eax
  ; Test for there being a location-list gap between bb1 and bb2, as the
  ; variable does not have a location over the ADD32ri. The range should also
  ; extend over the final bb.
  ; RANGES-LABEL: DW_TAG_subprogram
  ; RANGES:       DW_AT_high_pc (0x[[NOPEHIGHPC:[0-9a-f]+]])
  ; RANGES-LABEL: DW_AT_name ("nope")
  ; RANGES:       DW_AT_location (0x{{[0-9a-f]+}}
  ; RANGES-NEXT:   [0x{{[0-9a-f]+}}, 0x[[NOPEADDR:[0-9a-f]+]]): DW_OP_reg0 RAX
  ; RANGES-NEXT:   [
  ; RANGES-NOT:    0x[[NOPEADDR]]
  ; RANGES-SAME:   , 0x[[NOPEHIGHPC]]): DW_OP_reg0 RAX

  bb.0.entry:
    successors: %bb.1, %bb.2
    liveins: $rdi
  
    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
    JCC_1 %bb.1, 2, implicit killed $eflags
    JMP_1 %bb.2
  
  bb.1.bb1 (align 4):
    successors: %bb.3
    liveins: $ecx, $rdi
  
    $eax = MOV32rr killed $ecx, implicit-def $rax
    DBG_VALUE $eax, $noreg, !3, !DIExpression(), debug-location !8
    JMP_1 %bb.3
  
  bb.2.bb2:
    successors: %bb.3
    liveins: $rax
  
    $eax = ADD32ri8 $eax, 3, implicit-def dead $eflags, implicit killed $rax, implicit-def $rax
    DBG_VALUE $eax, $noreg, !3, !DIExpression(), debug-location !8
    JMP_1 %bb.3

  bb.3.bb3:
    liveins: $rax
    RETQ $eax, debug-location !9

...
---
name:            bar
alignment:       4
tracksRegLiveness: true
registers:       []
liveins:         
  - { reg: '$rdi', virtual-reg: '' }
body:             |
  ; Two DBG_VALUEs, one for eax, the other for zero, merge into bb3. Check that
  ; livedebugvalues does not propagate anything.
  ; the location.
  ; CHECK-LABEL: name: bar
  ; CHECK-LABEL: bb.1.bb1
  ; CHECK:       $eax = MOV32rr
  ; CHECK-NEXT:  DBG_VALUE 0
  ; CHECK-NEXT:  JMP_1 %bb.3
  ; CHECK-LABEL: bb.2.bb2
  ; CHECK:       $eax = ADD32ri8
  ; CHECK-NEXT:  DBG_VALUE $eax
  ; CHECK-NEXT:  JMP_1 %bb.3
  ; CHECK-LABEL: bb.3.bb3
  ; CHECK-NOT:   DBG_VALUE
  ; Test for there being a location-list gap between bb1 and bb2, the variable
  ; should not have a location over the ADD32ri. The range of the last entry
  ; should not cover the last block.
  ; RANGES-LABEL: DW_TAG_subprogram
  ; RANGES:       DW_AT_high_pc (0x[[BARHIGHPC:[0-9a-f]+]])
  ; RANGES-LABEL: DW_AT_name ("bar")
  ; RANGES:       DW_AT_location (0x{{[0-9a-f]+}}
  ; RANGES-NEXT:   [0x{{[0-9a-f]+}}, 0x[[BARADDR:[0-9a-f]+]]): DW_OP_consts +0, DW_OP_stack_value
  ; RANGES-NEXT:   [
  ; RANGES-NOT:    0x[[BARADDR]]
  ; RANGES-NOT:    0x[[BARHIGHPC]]
  ; RANGES-SAME:   ): DW_OP_reg0 RAX

  bb.0.entry:
    successors: %bb.1, %bb.2
    liveins: $rdi
  
    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
    JCC_1 %bb.1, 2, implicit killed $eflags
    JMP_1 %bb.2
  
  bb.1.bb1 (align 4):
    successors: %bb.3
    liveins: $ecx, $rdi
  
    $eax = MOV32rr killed $ecx, implicit-def $rax
    DBG_VALUE 0, $noreg, !41, !DIExpression(), debug-location !42
    JMP_1 %bb.3
  
  bb.2.bb2:
    successors: %bb.3
    liveins: $rax
  
    $eax = ADD32ri8 $eax, 3, implicit-def dead $eflags, implicit killed $rax, implicit-def $rax
    DBG_VALUE $eax, $noreg, !41, !DIExpression(), debug-location !42
    JMP_1 %bb.3

  bb.3.bb3:
    liveins: $rax
    RETQ $eax, debug-location !42

...
---
name:            baz
alignment:       4
tracksRegLiveness: true
registers:       []
liveins:         
  - { reg: '$rdi', virtual-reg: '' }
body:             |
  ; Two DBG_VALUEs, one for zero, the other for eax, merge into bb3. Check that
  ; livedebugvalues does not propagate anything.
  ; the location.
  ; CHECK-LABEL: name: baz
  ; CHECK-LABEL: bb.1.bb1
  ; CHECK:       $eax = MOV32rr
  ; CHECK-NEXT:  DBG_VALUE $eax
  ; CHECK-NEXT:  JMP_1 %bb.3
  ; CHECK-LABEL: bb.2.bb2
  ; CHECK:       $eax = ADD32ri8
  ; CHECK-NEXT:  DBG_VALUE 0
  ; CHECK-NEXT:  JMP_1 %bb.3
  ; CHECK-LABEL: bb.3.bb3
  ; CHECK-NOT:   DBG_VALUE
  ; Test for there being a location-list gap between bb1 and bb2, the variable
  ; should not have a location over the ADD32ri. The range of the last item
  ; should not cover the last block.
  ; RANGES-LABEL: DW_TAG_subprogram
  ; RANGES:       DW_AT_high_pc (0x[[BAZHIGHPC:[0-9a-f]+]])
  ; RANGES-LABEL: DW_AT_name ("baz")
  ; RANGES:       DW_AT_location (0x{{[0-9a-f]+}}
  ; RANGES-NEXT:   [0x{{[0-9a-f]+}}, 0x[[BAZADDR:[0-9a-f]+]]): DW_OP_reg0 RAX
  ; RANGES-NEXT:   [
  ; RANGES-NOT:    0x[[BAZADDR]]
  ; RANGES-NOT:    0x[[BAZHIGHPC]]
  ; RANGES-SAME:   ): DW_OP_consts +0, DW_OP_stack_value

  bb.0.entry:
    successors: %bb.1, %bb.2
    liveins: $rdi
  
    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
    JCC_1 %bb.1, 2, implicit killed $eflags
    JMP_1 %bb.2
  
  bb.1.bb1 (align 4):
    successors: %bb.3
    liveins: $ecx, $rdi
  
    $eax = MOV32rr killed $ecx, implicit-def $rax
    DBG_VALUE $eax, $noreg, !81, !DIExpression(), debug-location !82
    JMP_1 %bb.3
  
  bb.2.bb2:
    successors: %bb.3
    liveins: $rax
  
    $eax = ADD32ri8 $eax, 3, implicit-def dead $eflags, implicit killed $rax, implicit-def $rax
    DBG_VALUE 0, $noreg, !81, !DIExpression(), debug-location !82
    JMP_1 %bb.3

  bb.3.bb3:
    liveins: $rax
    RETQ $eax, debug-location !82

...
---
name:            qux
alignment:       4
tracksRegLiveness: true
registers:       []
liveins:         
  - { reg: '$rdi', virtual-reg: '' }
body:             |
  ; Two DBG_VALUEs for zero merging into bb3, Check that livedebugvalues does
  ; propagate the zero into the merging block.
  ; CHECK-LABEL: name: qux
  ; CHECK-LABEL: bb.1.bb1
  ; CHECK:       $eax = MOV32rr
  ; CHECK-NEXT:  DBG_VALUE 0
  ; CHECK-NEXT:  JMP_1 %bb.3
  ; CHECK-LABEL: bb.2.bb2
  ; CHECK:       $eax = ADD32ri8
  ; CHECK-NEXT:  DBG_VALUE 0
  ; CHECK-NEXT:  JMP_1 %bb.3
  ; CHECK-LABEL: bb.3.bb3
  ; CHECK:       DBG_VALUE 0
  ; Test for there being a location-list gap between bb1 and bb2, the variable
  ; should not have a location over the ADD32ri. The final entry should cover
  ; the final block.
  ; RANGES-LABEL: DW_TAG_subprogram
  ; RANGES:       DW_AT_high_pc (0x[[QUXHIGHPC:[0-9a-f]+]])
  ; RANGES-LABEL: DW_AT_name ("qux")
  ; RANGES:       DW_AT_location (0x{{[0-9a-f]+}}
  ; RANGES-NEXT:   [0x{{[0-9a-f]+}}, 0x[[QUXADDR:[0-9a-f]+]]): DW_OP_consts +0, DW_OP_stack_value
  ; RANGES-NOT:    0x[[QUXADDR]]
  ; RANGES-NEXT:   [0x{{[0-9a-f]+}}, 0x[[QUXHIGHPC]]): DW_OP_consts +0, DW_OP_stack_value

  bb.0.entry:
    successors: %bb.1, %bb.2
    liveins: $rdi
  
    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
    JCC_1 %bb.1, 2, implicit killed $eflags
    JMP_1 %bb.2
  
  bb.1.bb1 (align 4):
    successors: %bb.3
    liveins: $ecx, $rdi
  
    $eax = MOV32rr killed $ecx, implicit-def $rax
    DBG_VALUE 0, $noreg, !121, !DIExpression(), debug-location !122
    JMP_1 %bb.3
  
  bb.2.bb2:
    successors: %bb.3
    liveins: $rax
  
    $eax = ADD32ri8 $eax, 3, implicit-def dead $eflags, implicit killed $rax, implicit-def $rax
    DBG_VALUE 0, $noreg, !121, !DIExpression(), debug-location !122
    JMP_1 %bb.3

  bb.3.bb3:
    liveins: $rax
    RETQ $eax, debug-location !122

...