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

    <tr>
        <th>Summary</th>
        <td>
            Misoptimization: `EarlyCSEPass` uses replaces `powi.f16` with `float` result
        </td>
    </tr>

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

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

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

<pre>
    It looks like EarlyCSEPass is transformin the following:

```llvm
  %_6 = alloca [48 x i8], align 8
  %_3 = alloca [2 x i8], align 2
  %0 = call half @llvm.powi.f16.i32(half 0xH3C00, i32 1) ; 0xH3C00 = 1.0f16
  store half %0, ptr %_3, align 2
  %1 = load half, ptr %_3, align 2
  %_4 = fcmp oeq half %1, 0xH3C00
  br i1 %_4, label %bb1, label %bb2
```

Into this:

```llvm
  %_6 = alloca [48 x i8], align 8
  %_3 = alloca [2 x i8], align 2
  store float 1.000000e+00, ptr %_3, align 2
  %0 = load half, ptr %_3, align 2
  %_4 = fcmp oeq half %0, 0xH3C00
  br i1 %_4, label %bb1, label %bb2
```

And later InstCombine folds further into:

```llvm
  %_6 = alloca [48 x i8], align 8
  %_3 = alloca [2 x i8], align 2
  store float 1.000000e+00, ptr %_3, align 2
  br i1 false, label %bb1, label %bb2
```

EarlyCSE seems to be doing an incorrect transformation: the result of `powi.f16(1.0, 1)` should be `half` 1.0 (0x3c00), but it is returning `float` 1.0 (0x3f800000). This is incorrect and UB.

This comes from the following rust code, which fails only when optimizations are enabled:

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

#[inline(never)]
pub fn check_pow(a: f16) {
    assert_eq!(1.0f16.powi(1), 1.0);
}

pub fn main() {
    check_pow(1.0);
 println!("finished");
}
```

Link to compiler explorer: https://rust.godbolt.org/z/zsbzzxGvj

I'm not sure how to reduce to a llc example since the passes appear different. I have been testing on aarch64 since x86 has other f16 ABI bugs, but I don't think this is limited to aarch64.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUVktv4zYX_TX05mIEinovtIiT8fcZaIECbdcBRV1ZnFCkhqRiJ7--IGVP7EwKDNAWaA2_RN3nOZeH4s7Jg0ZsSbElxcOGL340tvUHa5zLik1n-pd270EZ8-RAySeEz9yql_tfP__CnQPpwFuu3WDsJDX4EWEwSpmj1AeS3RH6QOjlu6TrW6nnaV0CIKx4LIFkD8CVMoIDKbZ5DSeQNSkeCLsHruRBQ33tkL1zYN_bsyt7Gs0FVwpGrgYgeSwhmc1RJkNaJjJjhNXxHj39P7unNASSGYOUsAZItr2sx0hpQoe0vCRw3lg8B2ZF9Jy9Xev8uJ40RlGG99HtBzwe8-gyiGkGg1-_ZUuD-aXks3lnQaarU7ireIcqXHZd-u6avePlmqy99gb8KN2_gsQV40EZ7gP68YWEbemPwE3_NrjpPwb3ne5BcY8W9tr5ezN1Used1DsYFutHtCC1N_9xNlawBq4c_gWwLgIEDnFy4A10CL2R-gBcg9TCWIvCvwkT99Jokt1FebLoFuXBDEBKepEAwuo0ieWHHU9KCm40i-pDZFLSODclDd0CYTU9ZSI02wSHbvEgfRBCi36xOpRBShrhufUZ6ggVYU0Cv40yiudbtVz38Ps2uW40GgkzoYPBmulWXcEuzoMwfYTyOEoxwsClcmC0eoHjiBrM7OUkX2P_DrhFQM07hf2fzVGIeV5iGWEpKbYDcr9YJKyOODVhJm4twtQcCasXvTjsb0y-GRZbqZXUIYzGZ7TXVvPSwaBBjCieHucYige21nxAqu1lfgC4c2j9I34NqSNpQcADjeHqTEmksiHZ2Y9UN-Wc001casLq7zJcl_EuEMxWaq_0mpswNkgt3Rh6Zh8n_Gh8f5L6KQytMNMsFVrA06yMRRt6Hr2fo-ayHWG7QEdyMH1nlE-MPRC2ew0f172-nv73_OVGsQmrJtDGg1vCgWSOIYnFfhEY_nFQSgCe-DQrBCd1WB4R5gCpAz7PyC30chjQovYJ7GHkzwgdogaPzoeZMxo4t2Is83OEU13CyB2YKFFDWsLddg_dcnCXvbGH3mjCKh-Ok9D5efKVnKTHPpa2hkw2fZv1TdbwDbZpxWhNizyvNmNbVz2tBppV3SAEy5H3tSjynBaip5yLdCNbRllOq5SlVUbzKqkb3tRlXudVUaUdbUhOceJSJfHkN_awkc4t2DZ1WRabKDwuPgMxpvEI8WZgtXjY2Db4fIo95VRJ591bFC-9wvZn6a63WiCSlPT6QSkowRJwtjgrLtDdqE9J4Sj9eKMbq05tFqva26E4SD8uXSLMRNguCv_682m25gsKT9gulu8I263tPbfsjwAAAP__17jTqQ">