The following function produces only a single division operation even when
compiling with -frounding-math. I had read in a different PR (29186) that the
pragma FENV_ACCESS is not supported, but that -frounding-math should produce
the same effect (recognizing that the option is experimental as well).

Here's the function:

cat > div.c <<EOF
#include <fenv.h>

void xdiv (double x, double y, double* lo, double* hi)
{
  #pragma STDC FENV_ACCESS ON 

  fesetround(FE_DOWNWARD);
  *lo = x/y;
  fesetround(FE_UPWARD);
  *hi = x/y;
}
EOF
gcc -O -frounding-math div.c -S

I get the following assembly-fragment on 
xdiv:
.LFB2:
        movq    %rbx, -24(%rsp)
.LCFI0:
        movq    %rbp, -16(%rsp)
.LCFI1:
        movq    %r12, -8(%rsp)
.LCFI2:
        subq    $56, %rsp
.LCFI3:
        movsd   %xmm0, 24(%rsp)
        movsd   %xmm1, 16(%rsp)
        movq    %rdi, %rbx
        movq    %rsi, %r12
        movl    $1024, %edi
        call    fesetround
        movsd   24(%rsp), %xmm0
        divsd   16(%rsp), %xmm0
        movsd   %xmm0, 8(%rsp)
        movq    8(%rsp), %rbp
        movq    %rbp, (%rbx)
        movl    $2048, %edi
        call    fesetround
        movq    %rbp, (%r12)
        movq    32(%rsp), %rbx
        movq    40(%rsp), %rbp
        movq    48(%rsp), %r12
        addq    $56, %rsp
        ret
.LFE2:

Here's also a simple driver program:
#include <stdio.h>
#include <assert.h>

extern void xdiv(double x, double y, double* lo, double* hi);

int main(int argc, char** argv)
{
  double z1,z2;

  xdiv(1,10,&z1,&z2);
  printf(" rounding down 1/10 is %30.20g \n", z1);
  printf(" rounding up 1/10 is %30.20g \n", z2);
  assert(z1<z2 && "Rounding mode is not working");
  return 0;
}

I'm sure this is supposed to work in std c, but I'm not sure that it is
supposed to work in gcc yet (according to http://gcc.gnu.org/wiki/GeertBosch it
might). It doesn't work on either x86-64 nor i386.


-- 
           Summary: Optimization generates incorrect code with -frounding-
                    math option
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: merkert at comcast dot net
 GCC build triplet: 4.3.0 20071123


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

Reply via email to