<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 - First DBG_VALUE for parameter is moved down after the end of the prologue (before DebugHandlerBase)"
   href="https://bugs.llvm.org/show_bug.cgi?id=40638">40638</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>First DBG_VALUE for parameter is moved down after the end of the prologue (before DebugHandlerBase)
          </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>Severity</th>
          <td>enhancement
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>DebugInfo
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>david.stenberg@ericsson.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>jdevlieghere@apple.com, keith.walker@arm.com, llvm-bugs@lists.llvm.org, paul_robinson@playstation.sony.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Spun out of PR40188.

When compiling the following example, lst.c:

    int g1, g2;

    void foo(int *p1) {
      g1 = g2;
      *p1 = 0;
    }

using:

    $ clang --target=i386-unknown-linux-gnu -g -O1 lst.c 

we land in a situation where we have a DBG_VALUE for p1 at the start of the
function before register allocation:

    # *** IR Dump Before Debug Variable Analysis ***:
    # Machine code for function foo: NoPHIs, TracksLiveness
    Frame Objects:
      fi#-1: size=4, align=16, fixed, at location [SP+4]

    0B  bb.0.entry:
          DBG_VALUE %fixed-stack.0, 0, !"p1", !DIExpression(), debug-location
!20; lst.c:3:15 line no:3
    16B   %0:gr32 = MOV32rm %fixed-stack.0, 1, $noreg, 0, $noreg :: (load 4
from %fixed-stack.0, align 16)
    32B   %1:gr32 = MOV32rm $noreg, 1, $noreg, @g2, $noreg, debug-location !21
:: (dereferenceable load 4 from @g2, !tbaa !22); lst.c:4:8
    48B   MOV32mr $noreg, 1, $noreg, @g1, $noreg, %1:gr32, debug-location !26
:: (store 4 into @g1, !tbaa !22); lst.c:4:6
    64B   MOV32mi %0:gr32, 1, $noreg, 0, $noreg, 0, debug-location !27 ::
(store 4 into %ir.p1, !tbaa !22); lst.c:5:7
    80B   RET 0, debug-location !28; lst.c:6:1

    # End machine code for function foo.

    ********** COMPUTING LIVE DEBUG VARIABLES: foo **********
    ********** DEBUG VARIABLES **********
    !"p1,3"      [32B;96B):0 ind Loc0=%stack.4294967295

The lexical-scope trimming in LiveDebugVariables results in the value being
moved down after the first, DL-less instruction:

    ********** EMITTING LIVE DEBUG VARIABLES **********
    !"p1,3"      [32B;96B):0 ind Loc0=%stack.4294967295
        [16B;96B):0 %bb.0-96B
    ********** EMITTING LIVE DEBUG LABELS **********
    # *** IR Dump After Virtual Register Rewriter ***:
    # Machine code for function foo: NoPHIs, TracksLiveness, NoVRegs
    Frame Objects:
      fi#-1: size=4, align=16, fixed, at location [SP+4]

    0B  bb.0.entry:
    16B   renamable $eax = MOV32rm %fixed-stack.0, 1, $noreg, 0, $noreg ::
(load 4 from %fixed-stack.0, align 16)
          DBG_VALUE %fixed-stack.0, 0, !"p1", !DIExpression(), debug-location
!20; lst.c:3:15 line no:3
    32B   renamable $ecx = MOV32rm $noreg, 1, $noreg, @g2, $noreg,
debug-location !21 :: (dereferenceable load 4 from @g2, !tbaa !22); lst.c:4:8
    48B   MOV32mr $noreg, 1, $noreg, @g1, $noreg, killed renamable $ecx,
debug-location !26 :: (store 4 into @g1, !tbaa !22); lst.c:4:6
    64B   MOV32mi killed renamable $eax, 1, $noreg, 0, $noreg, 0,
debug-location !27 :: (store 4 into %ir.p1, !tbaa !22); lst.c:5:7
    80B   RET 0, debug-location !28; lst.c:6:1

Later on, an instruction with a debug location is scheduled above the
DBG_VALUE, effectively ending the prologue without a location for p1:

    # *** IR Dump Before Post RA top-down list latency scheduler ***:
    # Machine code for function foo: NoPHIs, TracksLiveness, NoVRegs
    Frame Objects:
      fi#-1: size=4, align=16, fixed, at location [SP+4]

    bb.0.entry:
      renamable $eax = MOV32rm $esp, 1, $noreg, 4, $noreg :: (load 4 from
%fixed-stack.0, align 16)
      DBG_VALUE $esp, 0, !"p1", !DIExpression(DW_OP_plus_uconst, 4),
debug-location !20; lst.c:3:15 line no:3 indirect
      renamable $ecx = MOV32rm $noreg, 1, $noreg, @g2, $noreg, debug-location
!21 :: (dereferenceable load 4 from @g2, !tbaa !22); lst.c:4:8
      MOV32mr $noreg, 1, $noreg, @g1, $noreg, killed renamable $ecx,
debug-location !26 :: (store 4 into @g1, !tbaa !22); lst.c:4:6
      MOV32mi killed renamable $eax, 1, $noreg, 0, $noreg, 0, debug-location
!27 :: (store 4 into %ir.p1, !tbaa !22); lst.c:5:7
      RETL debug-location !28; lst.c:6:1

    # *** IR Dump After Post RA top-down list latency scheduler ***:
    # Machine code for function foo: NoPHIs, TracksLiveness, NoVRegs
    Frame Objects:
      fi#-1: size=4, align=16, fixed, at location [SP+4]

    bb.0.entry:
      renamable $ecx = MOV32rm $noreg, 1, $noreg, @g2, $noreg, debug-location
!21 :: (dereferenceable load 4 from @g2, !tbaa !22); lst.c:4:8
      renamable $eax = MOV32rm $esp, 1, $noreg, 4, $noreg :: (load 4 from
%fixed-stack.0, align 16)
      DBG_VALUE $esp, 0, !"p1", !DIExpression(DW_OP_plus_uconst, 4),
debug-location !20; lst.c:3:15 line no:3 indirect
      MOV32mr $noreg, 1, $noreg, @g1, $noreg, killed renamable $ecx,
debug-location !26 :: (store 4 into @g1, !tbaa !22); lst.c:4:6
      MOV32mi killed renamable $eax, 1, $noreg, 0, $noreg, 0, debug-location
!27 :: (store 4 into %ir.p1, !tbaa !22); lst.c:5:7
      RETL debug-location !28; lst.c:6:1

Currently, DebugHandlerBase::beginFunction() will move up the debug value to
the start of the function, so the end results from Clang for this example will
be correct. However, in <a href="https://reviews.llvm.org/D57511">https://reviews.llvm.org/D57511</a> I'm looking into
removing that code, as it can move debug values over their defining
instructions.

The lexical-scope trimming is done to avoid unnecessary DBG_VALUEs being
emitted:

  // The computed intervals may extend beyond the range of the debug
  // location's lexical scope. In this case, splitting of an interval
  // can result in an interval outside of the scope being created,
  // causing extra unnecessary DBG_VALUEs to be emitted. To prevent
  // this, trim the intervals to the lexical scope.

In this case, keeping the DBG_VALUE at the start of the function does not
result in extra DBG_VALUEs. Can the trimming perhaps be made more selective, so
it avoids situations like this for parameters? Or should this be solved in
another way?</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>