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

Reply via email to