<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">