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

    <tr>
        <th>Summary</th>
        <td>
            Manual application of De Morgan's laws results in better emit
        </td>
    </tr>

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

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

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

<pre>
    I had some code and wanted to wrap the return statement in parenthesis and do a bitwise negation to see if the emit is better. Here is the code after the aforementioned modification:
```zig
export fn swarControlCharMask1(v: u64) u64 {
 const ones: u64 = 0x0101010101010101;
    const mask = ones * 0x7F;
 const low_7_bits = v & mask;
    const del = low_7_bits + ones;
 const non_control_or_space = low_7_bits + ones * (0x80 - 0x21);
    return ~(~v & (del | ~non_control_or_space));
}
```

What I got was:

```asm
swarControlCharMask1:
        movabs  rcx, 9187201950435737471
        movabs  rdx, 72340172838076673
 movabs  rax, -6872316419617283936
        and     rcx, rdi
        add rdx, rcx
        sub     rax, rcx
        or      rax, rdx
 not     rax
        or      rax, rdi
        ret
```

I had a hunch this was not the best the compiler could do, so I manually applied De Morgan's laws by inverting the bits of each operand and changing the bitwise OR's to AND's and the AND's to OR's:

```zig
export fn swarControlCharMask2(v: u64) u64 {
    const ones: u64 = 0x0101010101010101;
    const mask = ones * 0x7F;
    const low_7_bits = v & mask;
    const del = low_7_bits + ones;
    const non_control_or_space = low_7_bits + ones * (0x80 - 0x21);
    return (v | (~del & non_control_or_space));
}
```

And, sure enough, we save an instruction:

```asm
swarControlCharMask2:
        movabs rcx, 9187201950435737471
        movabs  rdx, 6872316419617283935
 movabs  rax, -72340172838076674
        and     rcx, rdi
        add rdx, rcx
        sub     rax, rcx
        and     rax, rdx
 or      rax, rdi
        ret
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8ls9zqzYQx_8a-bKTDEiA4MDBicfTHNLO9NAeMwKtQQ1IHknYTg_52zsSjhOndua9Tt_LD2Ox3-_ugtAHCedUpxFrkt-RfLUQk--Nrf8Qg5LCPi8aI1_qB-iFBGdGhNZIBKEl7IX2KMEb2FuxBd8jWPST1eC88Dii9qA0bIVF7Xt0ykWbNCCgUX6vHILGTnhldMjiEEFtYh4clQfloEHv0d7CL2gxjENsrr_xaONQbIyNtZTRKGE0Um1UG5MStiTJiiRLUiTz39-qm8_gYWush40Gtxf23mhvzXDfC_so3HNKaLkjbAlTkRFahQMQfjc7oTXaeTAa3VEChK0gOSTp-S9hbw6Ao2kU7jmqgxsIXUJy4Ot34awazP6JPzXKu6jdAaFFtF7IKHGIoo8eenfs7jytNvqpnS_0ydgntxUtXvPG3ggtk0OZwA0kB5oSWp3VP071K6Hl69wioWVsh9_D66ViIcOHJISvPs3OcRg__-yFhwfojIe9cO8zee4QbpzPXJzFNxMcf0azE40DsO2B0Huo0pLTJK3yJGM5Zzzj6RW9jHpOWZaknJasTHhRcHZUn2Qiym6KklOWFllaFVFdseI8b1gF8RbOfVipPsWlfKsZJGcxNzWzV1yOGwtncfkW18afAl87PnVj0X8xTzMYBPSTbnvwvXJhvmK1sDobdP64asetGtBCa6YhQCDUcgYeYBR6EsPwAmK7HRRKWCE8GtsJTSh3MIi9g-YFlN6h9Up3c97wtJoNoGh7MFu04Z6G_7YXuvugipT57feYyhtY_rqKX4M0KN7G3hxF1560byMH_ZIcp1X7Q-BxEv7v_DipfwxCwj2L1AgoiQ3R4mKp7wLIUsv4iE0WAbWZuj4M9whO7ML7C5R23k7t-Yvi2_FCr-HlP9Ll39TIr_DlM4eyn0eXU-7PdPl-iCxkzWTFKrHAOi2qivKCc77o61zmgpVNg1W2Saq0yMomZy3jeSHaJGXNQtU0oSxNkyJlacX4bZ5WLMtF0W5EWfEyJ1mCo1DD7TDsxltju4VybsKap6xKFoNocHBxt0Opxj3EIKE0bH5sHTw3zdQ5kiWDct69Z_HKD1g_Rl7NtJr3GQFEF6Bl0U2Dd2EPNO9j4rZmMdmh7r3fRtTQNaHrTvl-am5bMxK6DtWOh5utNX9h6wldxx4doet4Df8EAAD__885yxc">