https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34678

--- Comment #36 from Richard Biener <rguenth at gcc dot gnu.org> ---
Created attachment 46396
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46396&action=edit
poor mans solution^Whack

So this is what a hack looks like, basically sprinkling those asm()s throughout
the code automatically.

Note I need to protect inputs, not outputs, otherwise the last
testcase isn't fixed.

Improving this poor-mans solution by writing in some flow-sensitivity
like tracking which values are already protected and if there's a possibly
harmful FENV access inbetween maybe in a similar way tree-complex.c tracks
complex components might work.

Note that the FENV pragma does _not_ enable -frounding-math (it really has
no effect!) so you need to supply -frounding-math yourself (or fix the
frontends to do that).

It's a hack of course.

But it fixes the testcase:

> ./xgcc -B. t.c -O3 -lm
> ./a.out
1/0.2: down = 4.999999999999999 near = 4.999999999999999 up = 4.999999999999999
a.out: t.c:32: main: Assertion `5.0 <= up' failed.
Aborted
> ./xgcc -B. t.c -O3 -lm -frounding-math
> ./a.out
1/0.2: down = 4.999999999999999 near = 5 up = 5

IL after the lowering:

main ()
{
  static const char __PRETTY_FUNCTION__[5] = "main";
  double near;
  double up;
  double down;
  double op;
  int D.3058;

  op = atof ("0.2");
  fesetround (1024);
  __asm__ __volatile__("" : "=g" op : "0" op);
  down = 1.0e+0 / op;
  fesetround (2048);
  __asm__ __volatile__("" : "=g" op : "0" op);
  up = 1.0e+0 / op;
  fesetround (0);
  __asm__ __volatile__("" : "=g" op : "0" op);
  near = 1.0e+0 / op;
  printf ("1/%.16g: down = %.16g near = %.16g up = %.16g\n", op, down, near,
up);
...

Reply via email to