https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34678
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org
--- Comment #39 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #36)
> Created attachment 46396 [details]
> 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);
> ...
How does this work if op is a SSA_NAME?