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

    <tr>
        <th>Summary</th>
        <td>
            Difference between compile-time and runtime float precision on 32-bit x86 without SSE can cause miscompilation leading to segfault
        </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 program (based on the Rust version from [here](https://github.com/rust-lang/rust/issues/114479#issuecomment-2072945866), which is based on @comex's example from a different issue; they gave an explanation of they found it [here](https://github.com/rust-lang/unsafe-code-guidelines/issues/471#issuecomment-1774261953))

```c
#include <stdio.h>
#include <stddef.h>

void print_vals(float x, size_t i, int vals_i) {
        printf("x=%f i=%zu vals[i]=%i\n", x, i, vals_i);
}

void out_of_bounds(float x, size_t i) {
        printf("x=%f i=%zu vals[i]=out of bounds\n", x, i);
}

void evil(int vals[300]) {
        float x = 0.0;
        size_t i = 0;

        while (x != 90.0) {
                // At compile time, LLVM will brute-force the loop and discover that it
                // terminates after 90 iterations, with `i` always less than 300. This bounds
                // check therefore gets optimised out.
                if (i < 300) {
                        print_vals(x, i, vals[i]);
                } else {
                        out_of_bounds(x, i);
                }
                x += 1.0;
                // This addition is too small to have any effect on the value of `x` with
                // regular `float` precision, which is what LLVM uses at compile-time.
                // However, with the extra precision offered by x87 floating point registers,
                // the value of `x` will change slightly, meaning it will never hit exactly
                // 90.0 and therefore the loop will never terminate at runtime.
                x += 2.9802322387695312e-08;
                i += 2;
        }
}

int main() {
        int vals[300];
        for (int i = 0; i < 300; i++) {
                vals[i] = i;
        }
        evil(vals);
}
```

compiled with `clang -O3 --target=i686-unknown-linux-gnu -mno-sse code.c` will segfault at runtime. This is due to LLVM evaluating floats at standard float precision at compile-time, but outputting machine code that uses x87 extended precision at runtime. Specifically, [llvm/lib/Analysis/ScalarEvolution.cpp](https://github.com/llvm/llvm-project/blob/46b011d0ccb468613bcc7e9e756518f9f383001d/llvm/lib/Analysis/ScalarEvolution.cpp) will brute force the loop using compile-time semantics, causing the bounds check to be optimised out; however the extra precision of x87 extended precision floats will mean that the loop termination condition is never hit at runtime.

The [LangRef](https://llvm.org/docs/LangRef.html#floatenv) appears to imply that the compile-time semantics are correct, so this is a bug in the x86 backend.

Related to #44218.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykV1uPozwS_TXOSykRmEvgIQ-TzrT2YVYrzXza15YxBXjH2JFtkvT361dlcu1O71VCCLB9XJdTp4zwXvUGccOKLSt2CzGFwbpNgxgcol80tn3f_DEgdFZre1Smh72zvRMjMF41wmML1kAYEH5OPsABnVfWQOfsCKzYDuiQFTvGqyGEvWfZN8ZfGX_tVRimZiXtyPirm3xYamH68zPjr8r7CT3jr2ma5-ua8Sx-kXYc0YQlT9a8zouqLBmvGX-B46DkAMrD1SSWJ9KOeGJ87QFPYtxrnM0S0KquQ4cmQERl2ZY8eIdeHBCEATzttTAikCe2m8c6O5kWVPifvJqMFx0upW1x2U-qRa1MdO_qZ75OPzqZrtc5L9O6yKKTNUt2LPl2vpfJfMnzO8-UkXpqEVj24kOr7Gpg2fcvRlvs7ofj_WBVC3unTHg7CO0ZrzptRYATxderP_EtgKJnZQLQjDfFeA1svb2g1HF1x3jFOD-xbMd40YGaH_6c4iJWbBWFLn5TrHgxjHNCjdtE_Cs2yy7Q690nS-0U3mz31lBavjT2_zDPToFyf8b_bOe_tg4PSjNeXULFim2WJJEyjyadrQaW7SBZJTfMpL54MY_djZzHj4PSSFV4AsZTmlQTwocN6IrchG8BpB33tCioEcmNHz_-_lc4Kq2hcVPAZWedxFjM2to9CNNCq7y0B3QQBhFAhSfAAd2ojAjoQXQBHdQJqIAu1o-P1anCAKxMFCsTEPoo3j1o9J5ADWRJsoI_BireOdift5ADyt9kmMPOOoQegwe7D2pUsdynsLpfpTqKC0XuhdCfxeTMhgvVH9l3YcF9kudl6x2g9vgE7iMfn_DkAnH_SsnbUvLSx-zffI-REW2rohwpD8Fa8KPQGoKFYZasd8CuQxkuYnwQekLiLyuTE0WdUvAE3GE_aeFoWqQiTd07lIpU_EFYj5T_SJjJU6avbFoSm1ZPsP9ij3hAdyUA2YWn4MRtB7BRiFto3uFUrSHaEJuMpdJx2Csf0BGJnhHvuaNagxyE6RG8Vv0Q9DuZMKIwhKzCPMWQbTCoQM1B0qTPG1BBxSq4Me9aHHcg1wKgqLjJfArINcl8VVcJzzjPqnVZF1nKcZlUH_KurrMfBq68eZQbitMolImy9sjzz-pzh9dZB2eFukkM3GqGXsgOuj6Vz12RxLXquaVJfdbBucqeSealj927dCZWe9UNSW0Uln_LYLkMwvUYWLZTZVUuJ_Pb2KNZamWm07I3EyxHY5feI1CzXckrJTz2nZh0uM_RXFvKQzshFVOkNxKlZhZGOkau-yBMK1w7f7oj8Ic6IKY11DmmsJ9CBBmFHJSZ7ZlVNBYQ0R1PAU2L7SPe1bpfe5SqU1LomcKs2Gp9oLOFVg3jr9-M0O9e0fHhlxRauO8HqyeSiZXc7__tAeWCpQ_jcu_sP1DSyavRlrDzsknStE2kbPKyKtOskXKNNa6Lskirru6yKkuStL3D-U9s4vVdv4EP_WbyFK_7cILHUZigZGwjUswzaMGss5fGYKHBx35A_B1mAfpCeL7KwDnp0UwSjTlnVyMvxU5TpTU3Wb4JyhMVoDsdo1mx_SFM_xO7Z-mhSK6soxNja8nn1_Pk1RBGzXgWbUNzoDiK_R6Fo3YAatzr95udzyMIwtGQczHPL-AthDP9BTRTD2puHaeqhEbI32jaB_N_ohYBW9qP8SzPeVqtFu0ma-usFgvcpOs0q_N8vc4XwyYpqqYRddPmZSGbpioxSypRSZ7WTZWJfKE2POF5kvM8Wedlmq-SVJQ8S1JZJnWZtsjyBEeh9OoSlEU8HG-quqqKhRYNah__Wjg3eDwf5Dmnnxi3iZxupt6zPNHKB39DCSpo3OzOfwASocFwRDSPUSPRP-fwU8lbAxlfNirEUJFG0Vnx16_vIIWJJEUY6dhEeDNRNIo2MtdedWgxOb35r6vz-r8Qw_DPAAAA__-jlzx1">