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

    <tr>
        <th>Summary</th>
        <td>
            [LLVM] Missed optimization on boolean instructions.
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            llvm:optimizations,
            missed-optimization
      </td>
    </tr>

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

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

<pre>
    All the following expression are the equivalent. and should be optimized into `~((y | z) ^ x)`
```c
int test0(int x, int y, int z) {
    return ((x&y&~z) | (x&~y&z) | (~x&~y&~z) | (x&y&z));
}

int test1(int x, int y, int z) {
    return ((~z) & ((x&y) | (~x&~y))) ^ (z & ((x&y) | (x&~y)));
}

int test2(int x, int y, int z) {
    return ((x&y) | (~x&~y)) ^ (z & (((x&y) | (~x&~y)) ^ ((x&y) | (x&~y))));
}

int test3(int x, int y, int z) {
    return ~((y | z) ^ x);
}
```
but clang -O3 is far from optimizing into into the optimal form.
```
define dso_local noundef i32 @_Z5test0iii(i32 noundef %0, i32 noundef %1, i32 noundef %2) local_unnamed_addr #0 {
  %4 = xor i32 %2, -1
  %5 = and i32 %4, %0
  %6 = and i32 %5, %1
  %7 = or i32 %1, %0
  %8 = or i32 %7, %2
  %9 = xor i32 %8, -1
  %10 = and i32 %0, %2
  %11 = or i32 %6, %10
  %12 = or i32 %11, %9
  ret i32 %12
}

define dso_local noundef i32 @_Z5test1iii(i32 noundef %0, i32 noundef %1, i32 noundef %2) local_unnamed_addr #0 {
  %4 = xor i32 %1, %0
  %5 = or i32 %4, %2
  %6 = and i32 %2, %0
  %7 = xor i32 %5, -1
  %8 = or i32 %6, %7
  ret i32 %8
}

define dso_local noundef i32 @_Z5test2iii(i32 noundef %0, i32 noundef %1, i32 noundef %2) local_unnamed_addr #0 {
  %4 = xor i32 %1, -1
  %5 = and i32 %4, %2
  %6 = xor i32 %5, %0
  %7 = xor i32 %6, %1
  %8 = xor i32 %7, -1
  ret i32 %8
}

define dso_local noundef i32 @_Z5test3iii(i32 noundef %0, i32 noundef %1, i32 noundef %2) local_unnamed_addr #0 {
  %4 = or i32 %2, %1
  %5 = xor i32 %4, %0
  %6 = xor i32 %5, -1
  ret i32 %6
}
```
gcc is much closer to generating the optimal code than clang. https://godbolt.org/z/ceTo6M1as
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEVk1v4zYQ_TWjyyCGNBL1cdAhG9enDQoURQ-9BPqgbRY0mZJU6uSQ316QshNF1iZpt-gCgk2RjzNv3nA0bKwVO8V5DewLsHXUDG6vTf1LI7nquYla3T_W11Ki23Pcain1X0LtkB_vDbdWaIWN4WGR_zmIB7_NrbBRPdq9HmSPLUd978RBPPEehXIaIY-fgUqg8hGhuMEnoAqB_YRHoAryGOI1xNd-EJ5ufBfKoePWxUClHx-Bbrw9fDwPRjvFlxGPiGi4G4zC0dkRKH8Eyp9PuBs8TT772enk88vsBfYM9U968gTF-jR4QzT5t0RPTil_S_ySXjU-QTug8umdPbMtH3Gn7xR5mesS0c_u-URMH4eV_vOw3jmpl87OR3Z8bQeHnWzUDq9-TlFY3DYGt0YfzgXhCylURPjxNRQWGolbbQ6rRaM93wrFsbf6Tuqukaj0oHq-RZESQhbf_c5ClQghfLApvQCAWBzCfTuXLMyRjzOYvxuUag68v2v63iBQGk9VAmIZQrrGozYjgbD3Bq-SCYQFiP8knCCZhwQ6r6B8DmIn0NRSEUCvvpIFQ-UMU5wwNMFUc9LlBekknhOKFwwlycxbfmY9pZTQnPeZeHVGGe5eFmnxDH8y8ckPS_xSMtgs8GxBw4vM04KhYu6NXWRsnvhzKooFjcvvkZh-rMSfq61LhefifaRwvlCA5RxUvGX0X0mc_r8Sz75es6DZPOhvf7--fUAnyuTvt41d1_lmcRi6PXZSW27QadxxxU3jfMuYNopO9_721aix06xw79y9hfQaaAO02em-1dKttNkBbZ6ANh3_Vee3SWOjvk77Kq2aiNdJkVSsYBWron2dp9uS5VnZtyXP4zjZVm3clWmabTmjgvFI1BRTFudUJgmrkmpVFrzKKaOq6kvWZTlkMT80Qq6kfDh435GwduB1VcRZFsmm5dKG-yaRR0B6fWqIjRNaWSCfBSA6CGt5fzVd9GtsHZnab7xqh52FLJbCOvvqzAknw33269ffboGt8TbYwakd1ApbrSVvFAplnRm64HsVDUbWMxGF2w_tqtMHoE0gPP5d3Rv9B-8c0CbEZ4E2Y4gPNf0dAAD__y5lA9k">