<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 --- - Expression can be expanded to fold two constant integer multiplies into one."
   href="https://llvm.org/bugs/show_bug.cgi?id=30907">30907</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Expression can be expanded to fold two constant integer multiplies into one.
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </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>normal
          </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>simon.hosie@arm.com
          </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>Clang apparently cannot see that these are equivalent:

uint32_t f0(uint32_t x, uint32_t y) {
  static const uint64_t k0 = 0x12345678, k1 = 0x87654321, k2 =
0x0123456789abcdef;
  return (uint32_t)(k2 * (k0 * x + k1 * y) >> 32);
}

uint32_t f1(uint32_t x, uint32_t y) {
  static const uint64_t k0 = 0x12345678, k1 = 0x87654321, k2 =
0x0123456789abcdef;
  return (uint32_t)((k2 * k0 * x + k2 * k1 * y) >> 32);
}

clang -O3 -S -o- test.c

f0() gets three multiplies on 64-bit targets, while f1() gets two.

I guess it's possible that f0 could turn out faster on some hardware because it
needs only one full 64x64 multiply (along with two 64x32 multiplies).  If the
compiler knows that then maybe it should factorise rather than expand.</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>