https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93806
--- Comment #22 from Vincent Lefèvre <vincent-gcc at vinc17 dot net> --- (In reply to rguent...@suse.de from comment #21) > Note that GCC does FP contraction across stmt boundaries so > even s = a * b; t = s + c; is contracted. If that is already > a bug in your eyes then of couse value-numbering replacing > t by r is already a bug. Yes, with testing, I've eventually noticed that and mentioned this fact in PR20785 (i.e. this is very important when the STDC FP_CONTRACT pragma will be implemented, as this is not conforming). I haven't found an example with a major inconsistency, but when contraction is enabled, e.g. with "gcc -march=native -O3" on an x86 processor with a FMA, the following program #include <stdio.h> __attribute__((noipa)) // imagine it in a separate TU static double opaque(double d) { return d; } void foo (double a, double b, double c) { double s, t, u, v; s = a * b; t = opaque(s) + c; u = a * opaque(b); v = u + c; printf ("%d %a %a\n", t != v, t, v); } int main (void) { volatile double a = 0x1.000000000001p0, c = -1; foo (a, a, c); return 0; } outputs 1 0x1p-47 0x1.0000000000008p-47 Though t and v are computed from equivalent expressions, their values are different. However, in t != v, GCC correctly notices that they are different: it generates the comparison instruction, without optimizing; and this is still the case if -ffinite-math-only is used (since NaNs could prevent the optimization of t != v). Note that if one adds "if (s == u)" (which is true, and noticed by GCC) before the printf, one correctly gets: 0 0x1p-47 0x1p-47