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