<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 - Failed access analysis and missing vectorization of loop containing std::min/std::max"
   href="https://bugs.llvm.org/show_bug.cgi?id=40066">40066</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Failed access analysis and missing vectorization of loop containing std::min/std::max
          </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>Global Analyses
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>moritz.kreutzer@siemens.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Hi,

Clang trunk fails to vectorize the following loop with "cannot identify array
bounds":

    for (int i = 0; i < end; ++i) // does not vectorize
    {
        dst[i] = std::min(dst[i], dst[i]/src[i]);
    }

If we don't use std::min, but a simple ternary operator, Clang is able to
vectorize the resulting loop:

    for (int i = 0; i < end; ++i) // vectorizes
    {
        dst[i] = dst[i] < dst[i]/src[i] ? dst[i] : dst[i]/src[i];
    }

The problem does not seem to be std::min in itself, because Clang is able to
vectorize the following loop (note the different logic and the absence of an
implicit temporary for dst[i]/src[i]):

    for (int i = 0; i < end; ++i) // vectorizes
    {
        dst[i] = std::min(dst[i], src[i]);
    }

If we replace std::min with a custom implementation, returning the result by
value instead of "const &" (as it is done in libstdc++), we can also get the
first version to vectorize.

Obligatory godbolt: <a href="https://godbolt.org/z/6xjhz">https://godbolt.org/z/6xjhz</a>-

All in all, it seems like mixing references and values is the problem here. I
have tried patching D23686, D52116, and D52117, to no avail. From my feeling,
the first loop is something which should be vectorizable, even with the default
implementation of std::min (return a const reference ) in libstdc++ (in the
end, the call should be inlined and the compiler should be able to see through
everything). But maybe I'm missing something obvious, so any help is greatly
appreciated.


Thanks in advance,
Moritz</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>