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?