gcc currently ignores FENV_ACCESS pragma set to ON, and generate incorrect code
in such cases. Before gcc recognizes this pragma, the -frounding-math option
should probably be on by default. For instance, consider the following code.

#include <stdio.h>
#include <float.h>
#include <math.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON

static void tstall (void)
{
  volatile double x = DBL_MIN;

  printf ("%.20g = %.20g\n", 1.0 + DBL_MIN, 1.0 + x);
  printf ("%.20g = %.20g\n", 1.0 - DBL_MIN, 1.0 - x);
}

int main (void)
{
#ifdef FE_TONEAREST
  printf ("Rounding to nearest\n");
  if (fesetround (FE_TONEAREST))
    printf ("Error\n");
  else
    tstall ();
#endif

#ifdef FE_TOWARDZERO
  printf ("Rounding toward 0\n");
  if (fesetround (FE_TOWARDZERO))
    printf ("Error\n");
  else
    tstall ();
#endif

#ifdef FE_DOWNWARD
  printf ("Rounding toward -inf\n");
  if (fesetround (FE_DOWNWARD))
    printf ("Error\n");
  else
    tstall ();
#endif

#ifdef FE_UPWARD
  printf ("Rounding toward +inf\n");
  if (fesetround (FE_UPWARD))
    printf ("Error\n");
  else
    tstall ();
#endif

  return 0;
}

By default, I get incorrect results:

Rounding to nearest
1 = 1
1 = 1
Rounding toward 0
1 = 1
1 = 0.99999999999999988898
Rounding toward -inf
1 = 1
1 = 0.99999999999999988898
Rounding toward +inf
1 = 1.000000000000000222
1 = 1

If I add the -frounding-math option, I get correct results:

Rounding to nearest
1 = 1
1 = 1
Rounding toward 0
1 = 1
0.99999999999999988898 = 0.99999999999999988898
Rounding toward -inf
1 = 1
0.99999999999999988898 = 0.99999999999999988898
Rounding toward +inf
1.000000000000000222 = 1.000000000000000222
1 = 1


-- 
           Summary: gcc ignores FENV_ACCESS pragma set to ON
           Product: gcc
           Version: 4.3.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: vincent at vinc17 dot org


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

Reply via email to