https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108318
Alexander Monakov <amonakov at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |amonakov at gcc dot gnu.org --- Comment #1 from Alexander Monakov <amonakov at gcc dot gnu.org> --- Please see documentation for the -frounding-math option, but even with that option added, your testcase still has the faux-invariant moved by RTL PRE (-fno-gcse). Interestingly, if your testcase is modified to compute the sum before the call: #include <fenv.h> void foo (double res[4], double a, double b, double x[]) { a = x[0]; b = x[1]; static const int rm[4] = { FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD }; for (int i = 0; i < 4; ++i) { double t = a + b; fesetround (rm[i]); res[i] = t; } fesetround (FE_TONEAREST); // restore default } Then it demonstrates how a few *other* optimizations also perform unwanted motion: * SSA PRE (-fno-tree-pre) * TER (-fno-tree-ter) * RTL LIM (-fno-move-loop-invariants) * and finally the register allocator (unavoidable)