Compiling functions which change rounding mode
Nadezhda I. Viyukova
niva@niisi.msk.ru
Fri May 14 08:52:00 GMT 2004
We would like to learn how to compile functions which
can change rounding mode or other settings affecting
floating arithmetics.
Below is the example of such function:
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
double ttt (double x)
{
extern double p;
p = x*x*x*x*x*x;
fesetround(FE_TOWARDZERO);
return x*x*x*x*x*x;
}
Here the values of the first and second "x*x*x*x*x*x"
may differ, but gcc eliminates calculation of the
second "x*x*x*x*x*x" during CSE and uses the result
of the first one instead.
We know that #pragma STDC FENV_ACCESS is not currently supported
and have compiled this program as
mips64-none-elf-gcc -v -S -O1 tmp1.c -o tmpmips1.s -frounding-math
but -frounding-math did not solve the problem.
The compiler used is the latest GNU C version 3.4.0 (mips64-none-elf).
Of course it is possible to disable CSE by using -O0, but this
is not a very good solution.
We currently work around such problems in a tricky way by using
of a wrapper function with dummy parameter and result
(see below).
Still we'd like to hear about more straightforward solutions.
Here is the program which calls fesetround via the wrapper:
#include <fenv.h>
#include <assert.h>
#pragma STDC FENV_ACCESS ON
double __attribute__((noinline))
my_fesetround (int rd, double dummy __attribute__((unused)))
{
assert (0 == fesetround(rd));
return 0.0;
}
double ttt (double x)
{
extern double p;
p = x*x*x*x*x*x;
x += my_fesetround (FE_TOWARDZERO, p);
return x*x*x*x*x*x;
}
Here use of dummy parameter (p) and adding of the result
of my_fesetround (which is always zero) to x create
data dependences that prevent elimination of the second
"x*x*x*x*x*x" during CSE.
This works with any level of optimization but requires
extra efforts from the programmer and introduces redundant
code to the resultant executable.
Regards,
Nadezhda I. Viyukova <niva@niisi.msk.ru>
Sergej W. Samborskij <sambor@niisi.msk.ru>
More information about the Gcc-help
mailing list