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

    <tr>
        <th>Summary</th>
        <td>
            __arithmetic_fence() doesn't protect against contract in clang
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang,
            floating-point
      </td>
    </tr>

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

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

<pre>
    clang only generates an intrinsic call for the __arithmetic_fence builtin if reassociation is enabled. That covers most cases, but there are some cases where fp-contract can lead to operations being fused across the fence.

The simplest case occurs like this:
```
float foo(float a, float b, float c) {
  return __arithmetic_fence(a * b) + c;
}
```
When this code is compiled with `clang -O2 -mfma` the fence will be ignored and an FMA instruction will be generated.

https://godbolt.org/z/77KdorPj8

A more complicated case can occur with `-ffp-contract=fast` if I'm trying to use a fence to limit which part of an expression can be contracted.
```
float foo(float a, float b, float c, float d) {
  return a + __arithmetic_fence(b * c + d);
}
```
Here the front end will generate `fmul` and `fadd` instructions with the `contract` flag set, leaving it to the backend to determine what gets contracted. That's usually ok, but if I compile this with `-ffp-contract=fast -fno-signed-zeros` and the optimizer ends up being able to prove that `d` is zero, the expression will get fused as fma(a, b, c). If I compile with `-ffast-math` instead, the `llvm.arithmetic.fence()` intrinsic is generated and the fusion is protected as intended.

https://godbolt.org/z/b1Mq6EeYY
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJycVc1u4zYQfhr6MpCh0D-yDzokmxpdFIv2sECxp4AiRxI3FKmSo6TO0xdDWbFbBC26gG1RMmf4_cyMVEq284i12D2I3eNKTdSHWCtvzs_q7EJcNcGca-2U7yB4d4YOPUZFmEB5sJ6i9clq0Mo5aEME6hGenlS01A9IVj-16DVCM1lH1oNtIaJKKWiryAYPNgF61Tg0a_jaKwIdXjAmGEIi0CphEvITNBNx5oigIkIKA87_wWt-2I6FDp6i0hzjwaEyQAHCyFht8AkatL6DdkpoQOkYUspQM7q1KB9FeT__fu0Rkh1GhxcAELSeYgJnnxGot0lsLlvFvrx88m3rgiJoQxDyMK8VY5-XzXWphTyCqB7mKICINEX_gWpCHhQIec_BRxDyAbTYXMJE9fghiN979Bkl6GAQ8nUYrUMDr5Z6EPtydrP4VUIxtIMS-_IqBbxa56BBsJ0PkbXy_IXTl3uwPlGcdLZt2baUg_mbhj3RmGWSJyFPXTBNcLQOsRPy9Cbkqap-MSH-9v1wG3QPQ4iY4TqrOecsPxuaLXgnULQ3hovNY6sSMQvbwmchqwEontltCjAlBHWhRgGcHSzBa291D6OKBKFldvjnGDElJsanNYxizn4l9sNeL0vzse0qG_uh-U02X-cNHP2f5v_MzZC9jMEToDezUYtLLF47TI7FYmP5VhmTtbuam2ahOQ9Xy6LzvoTWqQ4SEpNyqF5YZEssLG9ulH7mIymAQcI4WI_wyj3dIaVbSXOnC1klmNKknDtDeF7anE1canYu5H-zHYrWhyIPMVO8YQxp4caIwkh2sG8YWYoE03gZAzxvGOYYwwsfoojzzzok4DSMhjPcVMZFSVqGSAJuHnnIxmfLubHX8PmWwA12lagYFPWL2qjMcorYl869DOtrDayXGmDbc8AyaW26Nt070XZKl2E6xkCoaQZoPaE3_7M5m7svf-x_wm_fVqbemOPmqFZY31V3O3ncyu1-1de70twdGimxkaVqTXmoStnKwxblodw2crOytSzlttyVRyk3ldyvq2pX6UaXRu8bfTgYsS1xUNatM-0Qu5VNacL6eLevtiunGnQpv5OkzNNKSCnkJyFlbiXru2IM1hM_3j2uYs1pimbqktiWziZK18RkyWH9YX9xQ5qAyQtZ0aIcqE6xPe_1CtZDBrGaoqv_oZ6lfmrWOgxCnvjIy6UYY_iOmoQ8ZWJJyFPm9lcAAAD__ws7bXQ">