<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 - [WebAssembly] WebAssemblyDebugValueManager cannot handle DBG_VALUE_LISTs"
   href="https://bugs.llvm.org/show_bug.cgi?id=50361">50361</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[WebAssembly] WebAssemblyDebugValueManager cannot handle DBG_VALUE_LISTs
          </td>
        </tr>

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

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

        <tr>
          <th>Hardware</th>
          <td>All
          </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>Backend: WebAssembly
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>aheejin@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>aardappel@gmail.com, dschuff@google.com, llvm-bugs@lists.llvm.org, ydelendik@mozilla.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>WebAssemblyDebugValueManager class
(<a href="https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp">https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp</a>)
was created when there was no DBG_VALUE_LIST instruction, so it assumes all
debug value instructions are DBG_VALUEs, each of which can have at most a
single register operand. WebAssemblyDebugValueManager groups a register def
with its corresponding DBG_VALUEs that refer to the def.


1. When a reg def moves, we can't move DBG_VALUE_LISTs like DBG_VALUEs.

With DBG_VALUE_LIST instruction this relationship does not hold anymore.
DBG_VALUE_LIST can contain multiple register operands and a complex expression
describing the relationship between those operands. So when moving an
instruction that defines a register, we can move DBG_VALUEs referring to that
def but can't safely do the same thing with DBG_VALUE_LISTs. For example, see
the pseudocode below:
```
%0 = ...
DBG_VALUE %0, ...
%1 = ...
...
%2 = ADD %1, %2
```
When we move %0 right before %2, we can move the DBG_VALUE with it:
```
%1 = ...
...
%0 = ...
DBG_VALUE %0, ...
%2 = ADD %1, %2
```

But if it is a DBG_VALUE_LIST, there can be multiple register operands that
aren't supposed to be moved:
```
%0 = ...
DBG_VALUE_LIST ... %0, %1, ...
%1 = ...
...
%2 = ADD %1, %2
```

When we move %0 right before %2, we can't move the DBG_VLAUE_LIST in the same
way, because it changes the meaning of the DBG_VALUE_LIST:
```
%1 = ...
...
%0 = ...
DBG_VALUE_LIST ... %0, %1, ... ;; Error. %1's value changed by new def
%2 = ADD %1, %2
```

But currently WebAssemblyDebugValueManager moves all DBG_VALUE_LISTs around in
the same way, which should be fixed.

---

2. We can't copy DBG_VALUE_LISTs in a brute-force manner as we do for
DBG_VALUEs.

A single DBG_VALUE_LIST instruction can contain any number of register
operands. In real world code I have seen a DBG_VALUE_LIST with dozens of them.

In WebAssemblyRegisterStackify, when we create a `tee.local` for a reg def, one
reg def becomes three reg defs, which is well illustrated in this comment:
<a href="https://github.com/llvm/llvm-project/blob/541c2845ded174f8937433fc8a110a2e644919a6/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp#L606-L622">https://github.com/llvm/llvm-project/blob/541c2845ded174f8937433fc8a110a2e644919a6/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp#L606-L622</a>
(In the old code, there's one def 'Reg', but in the new code, there are three
with the same value: 'Reg', 'DefReg', and 'TeeReg')

And when a def becomes three defs, each corresponding DBG_VALUE is copied twice
so there will be three copies of it. But if a DBG_VALUE_LIST contains dozens of
registers and each of them gets tee'd, the DBG_VALUE_LIST can be copied
exponentially. For example, if a DBG_VALUE_LIST contains %0, %1, and %2, after
%0 is tee'd, the instruction has 3 copies. And after %1 is tee'd, each of 3
copies becomes 3 copies, so there will be 9 copies. And after %2 is tee'd there
will be 27 copies.

This way, in real world code, I have seen a BB with ~100 instruction (including
DBG_VALUEs and DBG_VALUE_LISTs) becomes several million instructions,
effectively stalling the compilation process. It will look like
infinite-looping.

---

To fix both bugs, we should come up with a way so that it can handle
DBG_VALUE_LISTs correctly and efficiently. In the meantime, I am planning to
nullify those DBG_VALUE_LIST instructions to make them appear as "optimized
out", which is at least correct.</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>