<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 --- - Invariant loads are not hoisted all the way out of certain simple nested loops" href="https://urldefense.proofpoint.com/v2/url?u=https-3A__llvm.org_bugs_show-5Fbug.cgi-3Fid-3D23816&d=AwMBaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=pF93YEPyB-J_PERP4DUZOJDzFVX5ZQ57vQk33wu0vio&m=5Pi_0e5bx_BcCGGoS-W_jM14py8IWqOlav4QKTH5YWY&s=e4RkEZBp7Lg2QA76J0wa51fZr19Q0wPtVvSA8rQ4vf8&e=">23816</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Invariant loads are not hoisted all the way out of certain simple nested loops
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>tools
          </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>opt
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>broune@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>In this simple example, *a is hoisted out of the inner loop, but not out of the
outer loop with -O2. I think -O2 should be powerful enough to hoist *a out of
both loops for this example.

__attribute__((noinline))
float computeSum(float* a, int N, int M) {
  float sum = 0;
#pragma nounroll
  for (int i = 0; i < N; ++i) {
#pragma nounroll
    for (int j = 0; j < M; ++j) {
      sum += *a;
    }
  }
  return sum;
}

int main(int argc, char** argv) {
  float a = 42;
  return computeSum(&a, 1000, 1);
}

The reason is that -O2 does not have loop unswitching enabled. To have a safe
place to hoist *a out to, we need to loop unswitch on the condition M > 0. I
assume loop unswitching is disabled because it can cause code bloat and slower
code in some cases, though note that in this case, the version of the loop for
M <= 0 does nothing, so a safe version of loop unswitching that only fires on
such cases could run with -O2. This wouldn't work for cases where the outer
loop does more than just run an inner loop, but it would be a good start and it
would also speed things up by not having to check M>0 for every iteration of
the outer loop.

An alternative would be for licm to introduce a check for M>0 outside the outer
loop, which would create a safe place to put the load.

With -O3 the load does get hoisted all the way out as loop unswitching is
enabled there. However, loop unswitching only fires on loops that are smaller
than a threshold. If we set the threshold to a smaller value like 10, to
simulate a larger loop, then loop unswitching does not fire here and the load
does not get hoisted even for -O3. The loop unswitch pass does have code to
detect trivial cases where one of the two versions of the loop is empty, but
it's not powerful enough to recognize that for this example (it mostly detects
cases similar to "if (loop-invariant) break;").

This bug is for -O2 to handle (i.e. hoist loads all the way out) the above
simple example and for -O3 to handle similar loops that are larger than the
threshold for loop unswitching.</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>