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

    <tr>
        <th>Summary</th>
        <td>
            [clang] Option -frounding-math not working as expected on x86
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          sfc-gh-lvolker
      </td>
    </tr>
</table>

<pre>
    I'm trying to change the rounding mode using `fesetround` and it looks like Clang is still changing the order of instructions in a way that causes wrong results for floating point operations. This happens even when setting [-frounding-math](https://clang.llvm.org/docs/UsersManual.html#cmdoption-f-no-rounding-math).

To reproduce, consider this code (from GCC's [Bug 34678](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34678) which describes the same issue):

```
#include <cstdio>
#include <cstdlib>
#include <cfenv>

#include <cassert>

/**
 * With GCC
 * g++82 -O3 -lm -frounding-math -o round round.cc && ./round
 *
 * With Clang
 * clang++ -O3 -frounding-math -o round round.cc && ./round
 */


int main()
{
   double op;
   double down;
   double up;
   double near;

   op = atof("0.2");

   fesetround(FE_DOWNWARD);
   down = 1.0 / op;

   fesetround(FE_UPWARD);
   up = 1.0 / op;

 fesetround(FE_TONEAREST);
   near = 1.0 / op;

   printf("1/%.16g: down = %.16g near = %.16g up = %.16g\n", op, down, near, up);

 assert(down <= 5.0);
   assert(down <= near);
   assert(near <= up);
   assert(5.0 <= up);

   return 0;
}
```

Compiling and running this produces
```
clang++ -O3 -frounding-math -o round round.cc && ./round
1/0.2: down = 4.999999999999999 near = 4.999999999999999 up = 4.999999999999999
round: round.cc:39: int main(): Assertion `5.0 <= up' failed.
[1]    10797 abort (core dumped)  ./round
```

The `clang++` version was `15.0.3`.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVs1u4zYQfhr6MrBAkZZsHXyw5ajooZtim8UeFxRFSWwoUiCpeLdPX5BSYsfxYg9tIDDWzPCbb37EIXNOdlqIPcqOKDut2OR7Y_eu5euuX6sXo56FXdWm-bH_HZHtAN7-kLoDb4D3THcCfC_Amkk3QTyYRsDkwk-U41Y44aMO5RiYbkB6UMY8O1DyWUCpmO5AOnBeKjUDRvBegLGNsGBakNp5O3EvjXYgNTA4sx_ge-aBs8kJB2drdAdWuEl5B62x0CrDfEAajdQezCgsiwAJPPXSQc_GUWgH4kVoOPdCgxM-bkDZcd2-hrMemO9RdkJk13s_OkQPiFSIVDwQT5R6GRJjO0SqxnCHSPXFCev-YHpiKun9oBChfGjMGHyv27U26_fQpEgQPiF8mNcnA1aM1jQTF4iUwI12MqTBB9I85BaRXWvNAL-VJSJbF_gepw7oJt_u7jHtOE86PS0066n7RyrFEKlcb87f6qlLeCcRrWSD6GlGIQWce8l7aITjVtbCxYI4NgiQzk0CkSLgXxFHOV6e-ZVQqbmaAl9acucbaRB9-JlSyfpn2lbol4vungVzTlj_waZC5BCe-AqIHOCr9H1M20XUIXJE5LgjsH6ksFYD3NQe1mbu7XlNOAdEckRySBCp5s5-g7v1Fbv7ShibZvY4-_svvkj1Lt64hlYfmNSIhCIumu1x2QXQmKlWAsyI6AdhY876jni6Z6sFs2_iN6UZAdETMG_aSIDghCBCYrPc2l4dDGRXPXw7PX799PXw-XRtHP2ddQRNEwyIVNfUf4r15c87SNP4C5xblKfHTw-Hzw9_Pd0Ahdh_SWm0UvslC2nsxSxJ8w7RwyWkRXYBfBUsVF_3ZKWOWSyDJ1LOhSLlXARShgp9zPDyUZDd4q4MiFmCb4K5azYD37dbyEa7946vrbKQmntGb6ZW-MlqwBfN9nT_JIlraYZRqnA8hxliJ63nKSEdLKelu7v7__riQg1DN1_Xb5MU7_8ulfyoWmr6QTHDz57o4Y0Gogcajli4-aLpAQ4xydLoMF9vEr2FlkklmteZkh1TlJ0AAFK8LbbAamN9mCDcWAHNNIyiCaf9bbh3a_DUi-DyKqVhpr8I6wKZM3NBm2YJTijKcbJq9rQpaMFWYp_mW4zxJsPZqt_nzY7uSJGztNikO1Zvizwt6iZvCcUZaeqV3BNMSEowSXd4R7KE1jXLMK_rTUPTNC3QBouBSfU2f1dxKu2zguJspVgtlHu9zth9MFrXU-fQBivpvLts89KrePGZg8pO8Bgn9Yc-0cbD2djn2IEOxPdRcC8aMBq-7_LVZNX-ZupK3091ws2ASBX8Lf_WozV_C-4RqSLncGeItP8NAAD__zNbvUY">