<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - SROA sometimes breaks local variable debuginfo that uses DIExpression"
   href="https://llvm.org/bugs/show_bug.cgi?id=30703">30703</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>SROA sometimes breaks local variable debuginfo that uses DIExpression
          </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>All
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>normal
          </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>michaelwoerister@posteo.net
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>In the Rust compiler, closures are translated into regular functions with the
closure environment passed in as the first function parameter. These
environments are structs containing the variables that have been captured by
the closure. Each captured variable can either be contained in the environment
struct directly (by value), or the environment contains a pointer to where the
captured variable actually lives.

When generating debuginfo for closures, we want captured variables to appear
like regular locals. To this end we use a `@llvm.dbg.declare()` that points to
the alloca containing the environment struct and that has a DIExpression
navigating to field in question (via a DW_OP_plus) and, if needed, doing a
DW_OP_deref. This works well in most cases, but sometimes SROA will produce
bitcode that fails verification with an error like:

piece is larger than or outside of variable
  call void @llvm.dbg.value(metadata { i8*, i64 }* %arg0.sroa.5.0.copyload, i64
0, metadata !361, metadata !370), !dbg !368
!361 = !DILocalVariable(name: "buf", scope: !313, file: !30, line: 1, type:
!341)
!370 = !DIExpression(DW_OP_bit_piece, 128, 64)

So far, we have been able to work around this by always creating an additional
alloca containing a pointer to the environment struct and then using that as
the starting point for computing the variables' location in the DIExpression.
SROA seems to be able to handle this case in a more reliable way. However, we'd
like to get rid of this additional alloca that is just introduced for the sake
of debuginfo.

We have managed to create a rather small test case for reproducing this:
<a href="https://gist.github.com/michaelwoerister/55aed8d38be97c404b31c091cbb37ebd">https://gist.github.com/michaelwoerister/55aed8d38be97c404b31c091cbb37ebd</a>

bugpoint reduced this further (it fails for a different variable there, one
that does not have a DW_OP_plus, but with the same assertion):
<a href="https://gist.github.com/michaelwoerister/8dba37e51a4dc17413229770081d2c76">https://gist.github.com/michaelwoerister/8dba37e51a4dc17413229770081d2c76</a></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>