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

    <tr>
        <th>Summary</th>
        <td>
            [x86-64 BMI1] AND-NOT's should be preferred to OR-NOT's because we have `andn`/`vpandn` instructions
        </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>
    Zig code:

```zig
export fn foo(w: u64, x: u64, y: u64, z: u64) u64 {
    var s = w;
    s &= ~(x & y);
    s &= ~(z & ~y);
    return s;
}

export fn fooVec(w: @Vector(16, u8), x: @Vector(16, u8), y: @Vector(16, u8), z: @Vector(16, u8)) @Vector(16, u8) {
    var s = w;
    s &= ~(x & y);
    s &= ~(z & ~y);
    return s;
}
```

Compiled for Znver3:

```asm
foo:
        not     rcx
        and     rsi, rdx
        andn    rax, rsi, rdi
        or      rcx, rdx
 and     rax, rcx
        ret

fooVec:
        vpand   xmm1, xmm2, xmm1
        vpcmpeqd        xmm4, xmm4, xmm4
        vpandn  xmm0, xmm1, xmm0
        vpxor   xmm1, xmm3, xmm4
        vpor    xmm1, xmm1, xmm2
        vpand   xmm0, xmm0, xmm1
        ret
```

I expected it to be `and`+`andn`+`andn`+`andn` for the scalar version, and `vpand`+`vpandn`+`vpandn`+`vpandn` for the vector version. However, it turns `s &= ~(z & ~y);` into `s &= ~z | y;`. While this makes sense on machines without `andn` (and doesn't matter for machines which have `andn` and `orn`, or just `vpternlogq`), with x86-64 BMI1 we only get `andn`. We never got an `orn`, so this optimization hurts us.

LLVM (optimized):

```llvm
define dso_local i64 @foo(i64 %0, i64 %1, i64 %2, i64 %3) local_unnamed_addr {
Entry:
  %4 = and i64 %2, %1
  %5 = xor i64 %4, -1
  %6 = and i64 %5, %0
  %.not = xor i64 %3, -1
  %7 = or i64 %.not, %2
  %8 = and i64 %6, %7
  ret i64 %8
}

declare void @llvm.dbg.value(metadata, metadata, metadata) #1

define dso_local <16 x i8> @fooVec(<16 x i8> %0, <16 x i8> %1, <16 x i8> %2, <16 x i8> %3) local_unnamed_addr {
Entry:
  %4 = and <16 x i8> %2, %1
  %5 = xor <16 x i8> %4, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
  %6 = and <16 x i8> %5, %0
  %.not = xor <16 x i8> %3, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
  %7 = or <16 x i8> %.not, %2
  %8 = and <16 x i8> %6, %7
  ret <16 x i8> %8
}
```

[LLVM Godbolt link](https://llvm.godbolt.org/z/ETEdK3fGM)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMV0lv2zwT_jX0ZRBDolYffGjiuF_xdQFeFCnQS0GLY4mtRLok5e3Q3_6ClGzLW3J4Lw0Ck-I8fDgznEVixohSIk5J8kiS2Yi1tlJ6-sJqwZn-NVoovpt-FyUUiiOJ3pFgRoLDbxp0_3tRdiu4XSltYSlhqRSh-YZE76BNY0KfYDuY7wbz_XE-cQOQ7LEjAwBYMw0GSDSDDYkG6wYITd3yH0LzrXuAHaGT-5i9x_y5Amm0rZZgjoskmw1tPLPoBYuDUSQOXrCwShOah6mzo80d98HQV-S7N-T7V-WTe6K_x3GHsBj68Uk1K1Ejh6XS8F2uUUf3oomZpltxMXTAQP8nlfWjLrbnAiZ5JzDCuUTza7n0crb18gNMnMOUhiP_Gc2Rv99_eb5GO7Smj5ZL9derjmfbNKGPlaah_RheIotmhb_54XnbNHGPPI3X3NIjgyNnNwaXyK23c4CI7nF2DhkgT3rfsyw4nnrTspOnbgXKB8DtCguLHIQFq2CB4IJCcgekj91cvvrgg8xWCKZgNdOwRm2Ekk4dpyRJA6_tcVvnuTcfj7Rrn34H2jH8T21wjdrxO51bLY075LU8SgMQ0qpz2B5I5uuDk4_hWyVqBFsJAw37hQYMSoOgJDSsqIREAxthK9VaGNhOaO6M5AqNJDSz0DBrUXvlT_sqUVRQsTUOt_bOUboz_sllw8_W2M5jFrWsVfnby3ylcqfDNk8f0hgeP30IYeO0q3dQ4lClMXxDkM5DUCoLTJ4fYlRno1pZ0Yg9s0JJqFptDbRmPIyNjx9fPjn7eiRy78zbVaSu130Z4bgUEoEb9aNWBatBuC4TB12L8g808Zr083Awp4N55Kqsp_jRSska5D8Y5_pUeJ-l1btBzhOaxL4GO8cOCf0hJ1DiQS4ne5DP8IchJL3kSXqeYAAau-p4QRVdUWUeckK4XT0ZHcDyyxPTHpQdQBrtQZbfbJ4ci5pphLUS3Hnc3cmYL8rxmtUtEpo3aBlnljnm2_MJEBqF56QX10mipzCFLYicRM_9xXad-kLS3_LVanhzld5c_W8xcOeQe9FwBY97nUTurtRF5l8wiZ5vxumV8m9G7C1n_-XmHnPpSvc3s-pqx838ukJdZdqtJkqSR18r3yu-ULWFWshfJJkRmlfWrowLTzondO4TsuxAY6VLQud7QufPX5_5_6Pl-0-ETkZ8GvFJNGEjnIYZTaMsz9NkVE2LIktxkuRZTpeLZII0D3HJl3GRxkkRpWwkpjSgcTAJkyCJwyAZJ0WOkyyLCwwXDAtK4gAbJuqxV0PpciSMaXEaBnkWhaOaLbA2_sOEUokb8FJCqftO0VO36WHRlsYVFmGsOdFYYWv_RTPoTSSZwbvPs4fPX74SmhkwlWpr7t4uVhqXqDVy97bx5Z8jYoEFaw26pnbRKJ3zhu8FQhqr28I1LjNqdT0993IpbNUuxoVqepf3w8NKq59YWELn3jRD6Ly3fT2l_wYAAP__riSRLA">