<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [DebugInfo@O2] LiveDebugValues is no respecter of variable fragments"
   href="https://bugs.llvm.org/show_bug.cgi?id=41979">41979</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[DebugInfo@O2] LiveDebugValues is no respecter of variable fragments
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Keywords</th>
          <td>wrong-debug
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Common Code Generator Code
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>jeremy.morse.llvm@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>aprantl@apple.com, chackz0x12@gmail.com, david.stenberg@ericsson.com, greg.bedwell@sony.com, llvm-bugs@lists.llvm.org, orlando.hyams@sony.com, paul.robinson@am.sony.com, stephen.tozer@sony.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>With LLVM/clang r361045, if one runs 'llc -run-pass=livedebugvalues -x mir -o
-' on the code below, it appears that LiveDebugValues doesn't propagate
variable fragment locations in the way I would expect (i.e., at all).

The intention with this test is that, for a 64 bit variable (say a struct with
two 32-bit values) we specify the location of one 32-bit fragment in one block;
then the location of the other 32-bit fragment in another block. The control
flow between these blocks is linear (see the IR below); I would expect
LiveDebugValues to track and propagate the locations separately for each
fragment as they don't interfere with each other. The result should be (IMO)
two DBG_VALUEs in the exit block, each specifying the
location of one fragment of the source variable.

Instead, LiveDebugValues only seems to track one fragment per source variable,
and the second fragment "takes over" from the first fragment after the second
DBG_VALUE. Only the second fragment is propagated into the exit block, despite
there being no register clobbers. llvm-dwarfdump confirms we only get one
fragment of the variable in the exit block for the code below:

  [0x12,  0x19): DW_OP_reg0 RAX, DW_OP_piece 0x4
  [0x19,  0x1b): DW_OP_reg0 RAX, DW_OP_piece 0x4, DW_OP_reg3 RBX, DW_OP_piece
0x4
  [0x1b,  0x1e): DW_OP_piece 0x4, DW_OP_reg3 RBX, DW_OP_piece 0x4)

Where the first location entry corresponds to the code after the first
DBG_VALUE, the second to the contents of %bb.2 after the second DBG_VALUE, and
the third to the exit block.

I think dstenb spotted this in the recent DbgEntityHistoryCalculator
discussions; it's been at the back of my mind too, I figured I'd record a
reproducer somewhere so it doesn't get lost.

-------->8--------
--- |
  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 label %bb1
  bb1:
    br label %bb2
  bb2:
    br label %bb3
  bb3:
    ret i32 0
  }

  !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)
  !8 = !DILocation(line: 4, scope: !4)
  !13 = !{!3}
  !14 = !DISubroutineType(types: !15)
  !15 = !{!16}
  !16 = !DIBasicType(name: "looong", size: 64, align: 64, encoding:
DW_ATE_signed)

...
---
name:            foo
tracksRegLiveness: true
registers:       []
liveins:         
  - { reg: '$rdi', virtual-reg: '' }
body:             |
  bb.0.entry:
    successors: %bb.1
    liveins: $rdi

    $ecx = XOR32rr undef $ecx, undef $ecx, implicit-def $eflags
    JMP_1 %bb.1

  bb.1.bb1 (align 4):
    successors: %bb.2
    liveins: $ecx, $rdi

    $eax = MOV32rr killed $ecx, implicit-def $rax
    DBG_VALUE $eax, $noreg, !3, !DIExpression(DW_OP_LLVM_fragment, 0, 32),
debug-location !8
    JMP_1 %bb.2

  bb.2.bb2:
    successors: %bb.3
    liveins: $eax

    $ebx = MOV32rr $eax
    $ebx = ADD32ri8 $ebx, 3, implicit-def dead $eflags, implicit killed $rbx,
implicit-def $rbx
    DBG_VALUE $ebx, $noreg, !3, !DIExpression(DW_OP_LLVM_fragment, 32, 32),
debug-location !8
    JMP_1 %bb.3

  bb.3.bb3:
    liveins: $eax, $ebx
    $eax = XOR32rr killed $eax, killed $ebx, implicit-def $eflags
    RETQ $eax, debug-location !8

...
--------8<--------</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>