[Bug c/46180] New: CSE across calls to fesetround()

zimmerma+gcc at loria dot fr gcc-bugzilla@gcc.gnu.org
Tue Oct 26 09:47:00 GMT 2010


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46180

           Summary: CSE across calls to fesetround()
           Product: gcc
           Version: 4.4.4
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: zimmerma+gcc@loria.fr


with this program:

#include <stdio.h>
#include <fenv.h>
int main()
{
  double x = 3.0;
  fesetround (FE_DOWNWARD);
  printf ("1/3 arrondi vers -Inf: %.17f\n", 1.0 / x);
  fesetround (FE_UPWARD);
  printf ("1/3 arrondi vers +Inf: %.17f\n", 1.0 / x);
}

I get with gcc 4.4.4:

tarte% gcc -O1 ex.c -lm
tarte% ./a.out
1/3 arrondi vers -Inf: 0.33333333333333331
1/3 arrondi vers +Inf: 0.33333333333333331

while -O0 gives the expected results:

tarte% ./a.out
1/3 arrondi vers -Inf: 0.33333333333333331
1/3 arrondi vers +Inf: 0.33333333333333337

Kaveh Ghazi believes this is due to incorrect CSE across calls to fesetround().

Also the following program:

#include <stdio.h>
#include <math.h>
#include <fenv.h>
int main()
{
  double x = 3.0;
  fesetround (FE_DOWNWARD);
  printf ("sin(3) arrondi vers -Inf:       %.17f\n", sin (x));
  fesetround (FE_UPWARD);
  printf ("sin(3) arrondi vers +Inf:       %.17f\n", sin (x));
  fesetround (FE_TONEAREST);
  printf ("sin(3) arrondi au plus proche : %.17f\n", sin (x));
  fesetround (FE_TOWARDZERO);
  printf ("sin(3) arrondi vers 0 :         %.17f\n", sin (x));
}

gives with -O0:

tarte% gcc -O0 ex2.c -lm; ./a.out
sin(3) arrondi vers -Inf:       2.78837698122124511
sin(3) arrondi vers +Inf:       0.14112000805986724
sin(3) arrondi au plus proche : 0.14112000805986721
sin(3) arrondi vers 0 :         2.78837698122124511

And with -O1 or -O2:

tarte% gcc -O1 ex2.c -lm ; ./a.out
sin(3) arrondi vers -Inf:       0.14112000805986721
sin(3) arrondi vers +Inf:       0.14112000805986721
sin(3) arrondi au plus proche : 0.14112000805986721
sin(3) arrondi vers 0 :         0.14112000805986721

Kaveh Ghazi found that when compiling the code with  -fdump-tree-all
-frounding-math  -lm -O1 the
body of main() is transformed into the code below:

main ()
{
  double D.4342;

<bb 2>:
  fesetround (1024);
  D.4342_2 = sin (3.0e+0);
  printf (&"sin(3) arrondi vers -Inf:       %.17f\n"[0], D.4342_2);
  fesetround (2048);
  printf (&"sin(3) arrondi vers +Inf:       %.17f\n"[0], D.4342_2);
  fesetround (0);
  printf (&"sin(3) arrondi au plus proche : %.17f\n"[0], D.4342_2);
  fesetround (3072);
  printf (&"sin(3) arrondi vers 0 :         %.17f\n"[0], D.4342_2);
  return;

}

which clearly shows that sin(3.0) is computed only once, although the rounding
mode changed.

Paul Zimmermann

PS: a separate issue is that the rounding of sin(3) towards 0 and -Inf are
completely out of the allowed range [-1,1] for -O0...



More information about the Gcc-bugs mailing list