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

    <tr>
        <th>Summary</th>
        <td>
            On `wasm32`, `half` operation results aren't correctly rounded between each operation
        </td>
    </tr>

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

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

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

<pre>
    The following IR ([compiler explorer](https://godbolt.org/z/TbKnj8n4e)):

```llvm
target triple = "wasm32-unknown-wasi"

define half @f(half %x) {
start:
  %y = fmul half %x, 0xH4000 ; 0xH4000 == 2.0
  %z = fdiv half %y, 0xH4000 ; 0xH4000 == 2.0
  ret half %z
}

define half @callf() {
 %res = call half @f(half 0xH7BFF)  ; 0xH7BFF = maximum finite `f16`
 ret half %res
}
```

Is compiled into the following WASM:

```wasm
f:                                      # @f
 local.get       0
        call    __truncsfhf2
        call __extendhfsf2
        local.tee       0
        local.get       0
 f32.add 
        f32.const       0x1p-1
        f32.mul 
 end_function
callf:                                  # @callf
 f32.const       0x1.ffcp15
        call    f
 end_function
```

`callf` should return positive infinity (`0xH7C00`), but on WASM it will return `0xH7BFF` due to the extra range of the `f32` used to store the intermediate result.

This Rust program, when compiled with `rustc 1.81.0-nightly (3cb521a43 2024-06-22)` with `rustc --target wasm32-wasip1 code.rs` and run with `wasmtime`, demonstrates the issue.

```rust
#![feature(f16)]

fn f(x: f16) -> f16 {
        x * 2.0 / 2.0
}

fn main() {
        assert_eq!(f(f16::MAX), 1.0 / 0.0);
}
```

The assertion should succeed, but on WASM it fails.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyMVsFu4zYQ_Rr6MrBAkZZsHXSw4xq7KBYFtgu0t4AShxa3FOmSVOzs1xeUlMTrdYoIQiJTb4ZvZp4fLULQR4tYk2JHiv1CDLFzvm4Qo0cMi8bJ5_pbh6CcMe6s7RE-fwXCNqTYta4_aYMe8HIyzqMnxZ6wTRfjKRC-JexA2OHoZONMzJw_Enb4QdjhW_O7_b6xKySsSjffEron9OVvSafbmKd-WorCHzFC9PpkEAjfA2HsLELP2XKw_1h3tsuzCJowdp1JotIWoRNGAVlRlaiNz6y4EFYBWe8mYIjCx1cakADP4zaqHwxcxTwAvXxaUUqB8N3V8z6BWUavEvyYEkj99Jrg-eMJPMbXsB9zTev9_xTXCmNSgT_VlaI9hpFJAvzaCnr5tN4dDinqhVH6PEb04qL7oQelrY4IpKQqL9NoptzXFD2GW5IvU7zm_DnALBkJ2kYH8Sdd_bX988t7YkjTnpYU4Vv40EUYn4qdCBvXCpMlIU3Xa7Ona2wQADw-Rj_YNqhOsTuIx0e8RLSyU-H2_bRBRLy_wXv7K84yISX8jE6rrbPhFX3JT8v8V0xS6LyKVj6qwbZROzstTar4SL_mXk0Bb7xuGGRKtae8uN849S6Nu2Ig5bxbSSF0bjAySWrwFk4u6KifELQdtfc82k1Jkzgf6JgnGccDNEMEZ0fdgI5w1sa85JjhSdslBTkgzHLDS_QCvLBHBKfGpaRszhJuCCgTMETncXynbUTfo9QiIngMg4nZdRXfOh3g6xAinLw7etEnXucO7ZvSzzp2aQ8_hNhCnm3yjC6tPnbRjJXxtilYLlYcGGWrJS2XjKUCS3oTulzORjhbX7K8Uw6tk5j5kPDCSvCDfY1LwKh7HFv2ABL7NE8vIoapuhAGzO5-4dKW8xLjhOWk2CkUcfBI2CYZAauS21-FKgvJVy5JbxMAloT_lp7fLInQ6gKEbZPZAWGHN9O78TdloRfa3loaoZUIAX18xH8TK7ZRMx--JXz7Zfv3rI18zk-zUS189xGDSufclF47-6LKMLQtorwjOCW0CdlC1lxWvBILrPN1XuXlKq_4oquL1ZqxoqC5qBos1KZgKFS5WfOmWkvB8oWu08RpyXi-5iXnmcz5GoVSa8ZWMseCrCj2QpssnYXpBF2ME6urcsXXCyMaNGE8uBmzeJ7GmQ7BYr_wdYpZNsMxkBU1OsTwliXqaLD-w75oZFR_KpCUNHl60pI7oRdjHybZBxAeLWHrCK3zHtskX-8GK1FCg_GMaAFF271FLgZv6ptfAzp2Q5O1rifsMJ7w07_lybvv2EbCDmMVgbDDVOVTzf4LAAD__44uaIQ">