<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 - Code sinking pessimizes common GPU code patterns"
   href="https://bugs.llvm.org/show_bug.cgi?id=43785">43785</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Code sinking pessimizes common GPU code patterns
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </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>new bugs
          </td>
        </tr>

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

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

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>In GPU shaders used by games, it's pretty common to average a bunch of texture
samples in a loop in the fragment shader, e.g. for blurring an image:

vec4 sample = vec4(0);
for (int i = 0; i < NUM_SAMPLES; i++)
    sample += texture(...);

...
... = sample;

The problem happens after we unroll this loop, especially when doing very
aggressive unrolling (as is usually beneficial on GPU's) and NUM_SAMPLES is
very large (say, 8 to 16). If there's any intervening control flow, then LLVM's
code sinking pass will try to pull the entire unrolled loop downwards, but
since texture() is convergent, it can't, so it leaves just the texture
operations:

sample1 = texture(...);
sample2 = texture(...);
...
sampleN = texture(...);
...
... = sample1 + sample2 + ... + sampleN;

And now all of the samples are live at the same time, which results in a huge
increase in register pressure. We noticed this when changing RadeonSI to use
NIR, since this resulted in a few shaders in Civilization: Beyond Earth
spilling after unrolling started happening before LLVM.

I'm not entirely sure what to do here. Code sinking can definitely be
beneficial in some cases for register pressure, and disabling it is largely a
wash. We could just disable it in LLVM for AMDGPU/Mesa and do something much
less aggressive in our stack, although this is a problem that likely affects
other non-Mesa GPU stacks using LLVM.</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>