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

    <tr>
        <th>Summary</th>
        <td>
            [AArch64] Suboptimal codegen for `is_power_of_two`
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

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

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

<pre>
    The traditional test if an integer is a power of two is `((x - 1) & x) == 0 && x != 0`. However, InstCombine rewrites this idiom to `popcount(x) == 1`. This is more efficient on architectures with scalar `popcount,` but AArch64 only support `popcount` on vectors, so the extra instructions to transfer data between scalar and vector registers makes the resulting code less efficient than the traditional method.


C code ([godbolt](https://godbolt.org/z/bfM6KoTbf)):
```c
bool is_power_of_two(uint32_t x) { return ((x - 1) & x) == 0 && x != 0; }
```

Clang output:
```
is_power_of_two: // @is_power_of_two
  mov w8, w0
  fmov d0, x8
  cnt v0.8b, v0.8b
  uaddlv h0, v0.8b
  fmov w8, s0
  cmp w8, #1
  cset w0, eq
  ret
```

GCC output:
```
is_power_of_two:
  sub w1, w0, #1
  tst w1, w0
  ccmp w0, 0, 4, eq
  cset w0, ne
  ret
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJydVE2P2jAQ_TXJZbQocSCEQw4saNtq1VP3jpzYIe46cWqPgfbXdxzILrBqpVYywfPGfn7zYVdG_CxfWglouVCoTM81oHQIqgHeg-pR7qUF5YDDYI40NQ3g0QQkypOIFTRO8ABpxFYQsRxO4yTb0oAkICNIk3REaNMMPhPTQdqIbeBL73Bjukr1Eqw8WkWnA7ZEr4QyHaAJ5wxmqI3vMRx2xZ-ObC_jagedsRJk06hayR7B9MBt3RJhjd4S61FhC67mmttbzg1ZUHmE9Zo25HPaqn-C88NgLN4spXVEeyBGY12Q7wyJpVNPlEDKlkPr65BGF4QT1ruGciY4cqgkHqXsJwW8FxciinuvHEpLIfDXMfyQC-c1qn4PtREStHTuKjZsqTh4V7dOYmvELEq2UbK-_m7OHKFYi8e9EZXRGC22ZLeIg4uydcSeaFxcM2P3ZP2iX9V8zZ_NS9VQ0sPIJt48OY_6bFfGaCrBbmyRnWl21CJE76l_MrbDS1MsHyksqkUP_9E32SMRbO-Ov4lSc8qW8Th4_Cj0bN5LzNZwDh2ieXLvHHcAtdUBjkUo9jGZsCaAIgngqZjAmgpzSGZFFeDz5OLxXAh9gDb54Gne2d0be90NFyxiWfqGOolBAsHyxwRSPv-Skk-bzT8nZGJ2voJjegn7TgrSA_Hmm-SNqsel42d-K_RKfS__rD6WZZrnSZEt2WoeizITq2zFY1SoZUnde7mh1L3wzVdmQNVR54f23tPVasx4s--DIlpvdXnX7PQa-GpWm44MrQ_T38NgzXe6l2Qq57yka_60WDK2iNsy54JVLC2YyNhyuZLLNM1XTbYUq5XIl-k81ryS2gWhpDBWJUsYS4q0SBfzNJvPkiwRCQVXFAWvBOfUdLLjSs_CweHaxbYcNVR-78ip6Vlw707unNr3Uk783NOFt-VzJ_mr6uNRbjlq_Q33i7rg">