This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/30360] New: Complex divide bug
- From: "jakub at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 3 Jan 2007 21:19:34 -0000
- Subject: [Bug c/30360] New: Complex divide bug
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
/* { dg-options "-O0 -std=gnu99" } */
int
main (void)
{
_Complex double d;
__real__ d = 1.0;
__imag__ d = 1.0;
d = d / 0.0;
if (!__builtin_isinf (__real__ d) || !__builtin_isinf (__imag__ d))
__builtin_abort ();
return 0;
}
fails when compiled with -O0 -std=c99 but succeeds when compiled with -O2
-std=c99. ISO C99 says it should be (inf, inf) always in G.5.1 (4):
"if the first operand is a nonzero finite number or an infinity and the second
operand is a zero, then the result of the / operator is an infinity."
The problem is that libgcc _divdc3 doesn't do logarithmic scaling:
/* ??? We can get better behavior from logarithmic scaling instead of
the division. But that would mean starting to link libgcc against
libm. We could implement something akin to ldexp/frexp as gcc builtins
fairly easily... */
if (FABS (c) < FABS (d))
{
ratio = c / d;
denom = (c * ratio) + d;
x = ((a * ratio) + b) / denom;
y = ((b * ratio) - a) / denom;
}
else
{
ratio = d / c;
denom = (d * ratio) + c;
x = ((b * ratio) + a) / denom;
y = (b - (a * ratio)) / denom;
}
so when c == d == 0.0, denom is not 0.0 as later code is testing, but NaN.
To fix this, I think we either need to switch to logarithmic scaling,
or we need to special case FABS (c) == FABS (d) case, or the denom == 0.0
change ought should change (would c == 0.0 && d == 0.0 be enough?).
--
Summary: Complex divide bug
Product: gcc
Version: 4.1.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: jakub at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30360