This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Compiling functions which change rounding mode
- From: "Nadezhda I. Viyukova" <niva at niisi dot msk dot ru>
- To: gcc-help at gcc dot gnu dot org
- Date: Fri, 14 May 2004 12:49:04 +0400 (MSK)
- Subject: Compiling functions which change rounding mode
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>