https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34678
--- Comment #32 from Stefan Vigerske <vigerske at math dot hu-berlin.de> ---
Is there any hope this could actually be improved?
Now, 10 years later, the FENV_ACCESS pragma seems to be implemented, but the
problem here seems to persist.
I run into this with GCC 8.3.0 and code like this:
#pragma STDC FENV_ACCESS ON
#include <stdio.h>
#include <stdlib.h>
#include <fenv.h>
#include <assert.h>
int main()
{
double op;
double down;
double up;
double near;
op = atof("0.2");
fesetround(FE_DOWNWARD);
down = 1.0 / op;
fesetround(FE_UPWARD);
up = 1.0 / op;
fesetround(FE_TONEAREST);
near = 1.0 / op;
printf("1/%.16g: down = %.16g near = %.16g up = %.16g\n", op, down, near,
up);
assert(down <= 5.0);
assert(down <= near);
assert(near <= up);
assert(5.0 <= up);
return 0;
}
$ gcc -O3 -lm div.c && ./a.out
1/0.2: down = 4.999999999999999 near = 4.999999999999999 up = 4.999999999999999
a.out: div.c:32: main: Assertion `5.0 <= up' failed.
Looking at the assembler code, I see that only the first divsd remains and the
other two were optimized away.
The Intel compiler 19.0.0.177 handles this better:
$ icc -O3 div.c -lm && ./a.out
1/0.2: down = 4.999999999999999 near = 5 up = 5