<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/58996>58996</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Support the `% N` -> `& (N - 1)` transformation for runtime power-of-two values
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          scottmcm
      </td>
    </tr>
</table>

<pre>
    I [tried](https://llvm.godbolt.org/z/8YqnY9j1d) sending this to opt
```llvm
define i16 @src(i16 %x, i16 %y) {
start:
  %0 = tail call i16 @llvm.ctpop.i16(i16 %y)
  %_3 = icmp eq i16 %0, 1
  tail call void @llvm.assume(i1 %_3)
  %_7 = icmp eq i16 %y, 0
  %1 = urem i16 %x, %y
  ret i16 %1
}
```
expecting it to optimize to something like this
```llvm
define i16 @tgt(i16 %x, i16 %y) {
start:
  %0 = sub nuw i16 %y, 1
  %1 = and i16 %x, %0
  ret i16 %1
}
```

but it didn't -- it left the `div` in the generated assembly.

Alive2 proof that this would be fine: <https://alive2.llvm.org/ce/z/irgU2q>

---

If there's a better way to communicate this, then please let me know!  Assuming ctpop seemed like the best way, though, since `x & (x - 1) == 0` gets normalized down to `ctpop <= 1`, and thus I assumed that it was the preferred way to tell LLVM the value is a power-of-two.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJylVE2PnDgQ_TXmUqIFpmngwGGS3kgjZXNZ7Uo5rQAXtBOwGdt0T8-v37JhZnomOSRaqT9sV_lV1XtVbrW41vfA8g_OSBQsPzJenpybLcvuGP9En3E8T7tBi1aPbqfNQEdP9C2_Pqiv1bdUMF6BRSWkGsCdpAWnQc-OJUeW3LFDsn48ynoksJcKQaYHYPvEmo4ihg3PHxn_CNv66nFZ8WG9ZF1jnE8p7MA7JMCyI7hGjtA14_gMGNLt3KznHZ28Ynu8m9v_ZuG67KYZ8OE5aOITSJ_dXrHPWooX8MbaZcKAvCK9Qy5-hnz1yMmNWxq8FoMT3FYfXDcvg-7ZtuXEiuM7XtctPs7YOa-AdBv_cpJP6NdWT0i6kG2U3zFI9IvauMH9L23s0oJaLm8oSH-goFHiPQPJ7zOw_raL8wwIKRTjhYM49tsRe2LlhEDeQp7pF6QKBwMqNI1DASQqTu143d3C3Y3yjBxmo3VP_o1bG_yil1FAi-DJosKpjI9vZ6YJF3ehXdaR6XCbG2mGv_kDy_64DRTH8e323kdDQ1cKCw1Fcg4NXJqr17PT07Qo2VHaq5jEGXkrmEdsLFK1DiaE70pfGE8B7ny7evnDUNCo4kT1br2ABG6dh15h9DKc_MpK1QW-Hol7z3_5CDGJ53XPjl42Tz3x5ywobSYq-IlQhb4onyPZ1mjEjHdOvU4E67V2p8XCPaxTJFZapU_Bhnxmgz0aQ5atXoc0gJ8___NnMJ-bcaEG9bTM-oIm1n3sLnoXYZ0eDuW-3CdFFYk6E1VWNZGTbsT6r2WetXnpAeom-OLTj0mG9SCU-GUr0ZucaZTtfWVOagW0ArMomip8E3fNx0aLGeu3LTBIKrTdkVrbG7r9xdRN32hYfSsQBUj6fcrLqjpEpzrPK95nZXbgZVW0yLuiOhT5XoisTfZtu4_GpsXR1vRcM84V0mh5CFrTwx3Jmiecp2maJ9m-yKtd1-6rA7ZFm_Cu77GkkcaJ3rSXvoxMHVJql8H6101aZ1-NpJAcFGIIR_jNQv1hattp56ZuikLsOuT-Hy_41ck">