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

    <tr>
        <th>Summary</th>
        <td>
            WASM: v128.bitselect When Argument is Zeroed Can Be Simplified
        </td>
    </tr>

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

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

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

<pre>
    Example code, compiled with Rustc nightly (arguments: `-C opt-level=3 --target=wasm32-unknown-unknown -C target-feature=+simd128 -C target-feature=+multivalue`)
```rust
#![feature(portable_simd)]
use std::simd::*;

#[inline(never)]
pub fn flush_subnormals(input: f32x4) -> f32x4 {
    let bits = input.to_bits();

    let mask = bits & u32x4::splat(0x7f800000);
    let ne_mask = mask.simd_ne(u32x4::splat(0x00000000));

    let result = bits & ne_mask.to_int().cast::<u32>();
 f32x4::from_bits(result)
}
```
This results in the following WebAssembly:
```wasm
flush_subnormals:
        local.get       0
 v128.const      0, 0, 0, 0
        local.tee       2
 local.get       1
        v128.load       0
        local.tee 3
        local.get       2
        local.get       3
 v128.const      2139095040, 2139095040, 2139095040, 2139095040 ; 0x7f800000 0x7f800000 0x7f800000 0x7f800000
        v128.and
        i32x4.eq
 v128.bitselect
        v128.store      0
 end_function
```
Due to the first argument of `bitselect` being `0 0 0 0` and the condition being reversible, the WebAssembly is simplifiable into:
```wasm
flush_subnormals:
        local.get       0
 local.get       1
        v128.load       0
        local.tee       2 ; One fewer local used
 v128.const      0, 0, 0, 0
        local.get       2
        v128.const 2139095040, 2139095040, 2139095040, 2139095040 ; 0x7f800000 0x7f800000 0x7f800000 0x7f800000
        v128.and
        i32x4.ne ; Condition reversed
 v128.and                                                       ; bitselect replaced with and
        v128.store      0
 end_function
```
If the `select` expression had the second argument as a zeroinitializer instead, the condition would not need to be reversed, and the `bitselect` would simply be able to be converted into an `and`!

Godbolt link: https://godbolt.org/z/TqK5f588f
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMVtuO2zYQ_Rr6ZWCDIi1bfvCDL3FQFEWBJkCAvhiUNLLZUKTCi72bry9IyetLdtMibYFqFxZvc2bO8Awp4Zw8aMQlydck345E8Edjl-_ReKFwVJr6efnuSbSdQqhMjYRtoDJtJxXWcJb-CL8F5yvQ8nD06hkIK4Q9hBa1d4SvgMzoeAOm82OFJ1SEbzmMx17YA3rCt2fhWs7GQX_W5qwvbxhvoF8yblD4YJHwLWFrJ9s6Y8Vb021QXp6ECkhmlLAFoVtCV7Gd_m1wfhhinLCM5OuLOSs6Y70oFe6jj2ibb_u1wSE4XxO-InyVJlOLsBXh6wHuBTRfS62kjoAaT2hvgbpQQqOhUcEd9y6U2thWKEdYIXUXfExWw9nTlLAFjAl_1_eAzAcvAAAKPZTSOyB8C8ls4s0-jhBWRGf3IV1MWuE-J5Pels0gJE89p04JT1hBn-ZNQeNzC3SB0Lh_QYmNSUzFPjF9FYsOT8R6My6LLih_H9ngKPKS2ve0JpVwfsg73wTOCH_3QHjIXVrTWNNektK7uIphvn1QRd_9eJRuCMeB1OCPCI1RypylPsAnLFfOYVuq5-jhHiBKuB_6Zmv5Dd_E2VRCTQ7oh_7gHE4ZKyaV0c5fxtnm7ucVFI849Nkw_Yie3ZslJ8qI-sH5N6j8-0Gz70_zNzixjC_oIqfTROnv9YDwNVx1-ZfNVwgLXd-PyqiTCX65DTNqBRVW_hUA543F-4yhrvdN0JWXRr-qpm1A8KYXkbTOw-VIBNPEE_Hqb0ahxCgxMotM4l8cE7pO1pXRtYxuhlU2HipOliqdw3HFjTRBOnCy7ZRsZDzKQGpv_hO9_ltKG5SRtvlXjdDgGW0_D8Fh_Q_K40293oD9vySpMWFvXra83-z7LERh_NgTsV90BxY7JarLFf5NRD-s_J-apEoyo1eB41Nn0blI6Sh6XTuMyr6WhXAg4CtaI7X0Uij5FS1I7TyK-qL0ay2cTVA1aBNvJaxjpZV4zRbbvJTPY6n1hqlGnqNNqpLevDL6hNZjnaoGhI7GMS_xSyK7vbzem7o0yoOS-nO8tI_ed6l02I6w3aGfnRh7IGz3lbDdxy8_501eFM2oXvJ6wRdihMtsTjPKeDabjo5LtqDzPMOGTRc1K-kCG1ZmBS9pMaM0z4uRXLK4OGOzrGAzOp3kFS0LWvEKG86bkpEpxVZINVHq1EbfI-lcwOWcT_PpSIkSlUtfeIxpPEOaJIzFDz67jDbjMhwcmVIlnXdXFC-9wuWn1YdfItP7sxI-HVHD6rKF0sHvaA3WsBEa1ggfhqMI61GwavmQJumPoZxUpiVsF90Nr3FnzR9xt9guBekI2yUSfwYAAP__YZoBPg">