Bug 22394 - floating point comparison fails with -O2
Summary: floating point comparison fails with -O2
Status: RESOLVED DUPLICATE of bug 323
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.1
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-07-10 15:13 UTC by Glenn Burkhardt
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host:
Target: i586-mandrake-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
save-temps file that demonstrates problem (7.74 KB, text/plain)
2005-07-10 15:15 UTC, Glenn Burkhardt
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Glenn Burkhardt 2005-07-10 15:13:19 UTC
This problem exists in version 3.4.1; it doesn't in version 3.3.2 or 4.0.1, on
Intel 586 architecture (both AMD Athlon and P4 cpus).

I'm posting this note for reference, in case the change in the code generation
inadvertently (as opposed to intentionally) fixed the problem.

This program has different behavior when compiled with or without -O2.  The code
generated for the floating point comparison at line 32 is different.

[glenn@DepotSt ras]$ g++ -v
Reading specs from /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/specs
Configured with: ../configure --prefix=/usr --libdir=/usr/lib
--with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info
--enable-shared --enable-threads=posix --disable-checking --enable-long-long
--enable-__cxa_atexit --enable-clocale=gnu --disable-libunwind-exceptions
--enable-languages=c,c++,ada,f77,objc,java --host=i586-mandrake-linux-gnu
--with-system-zlib
Thread model: posix
gcc version 3.4.1 (Mandrakelinux 10.1 3.4.1-4mdk)

Intel(R) Pentium(R) 4 CPU 2.80GHz
AMD Athlon(tm) Processor

#include <math.h>
#include <stdio.h>

#define irint(x)   ((int)((x) > 0 ? ((x) + .5):((x) - .5)))
#define sqr(x)      ((x)*(x))
#define NUM_ARC_PTS 9

main()
{
    struct {
	int x, y;
    } start, xy, ij, center;
    double startAng, endAng, radius, theta, dTheta;

    start.x = 7078039;
    start.y = 2942821;
    xy.x = 7078039;
    xy.y = 2942821;
    ij.x = -87702;
    ij.y = 702547;

    center.x = start.x + ij.x;
    center.y = start.y + ij.y;
	
    startAng = atan2(-ij.y, -ij.x);
    if (startAng < 0) startAng += 2*M_PI;

    endAng = atan2(xy.y - center.y, xy.x - center.x);
    if (endAng < 0) endAng += 2*M_PI;

    // clockwise traversal
    if (startAng > endAng) {
	printf("angles not equal\n");
	dTheta = (startAng - endAng) / (NUM_ARC_PTS + 1);
    } else
	dTheta = (2*M_PI - (endAng - startAng)) / (NUM_ARC_PTS + 1);
    
    printf("startAng %f, endAng %f, dTheta %f\n",
	   startAng, endAng, dTheta);
    printf("startAng > endAng: %d\n", startAng > endAng);
    printf("startAng < endAng: %d\n", startAng < endAng);
    printf("startAng == endAng: %d\n", startAng == endAng);
    printf("startAng: %x %x\n", *((unsigned int*)&startAng),
	   *((unsigned int*)&startAng+1));
    printf("endAng:   %x %x\n", *((unsigned int*)&endAng),
	   *((unsigned int*)&endAng+1));
    printf("dTheta:   %x %x\n", *((unsigned int*)&dTheta),
	   *((unsigned int*)&dTheta+1));
}

Correct output:

[glenn@DepotSt ras]$ g++ ttt.cc -o ttt; ttt
startAng 4.836581, endAng 4.836581, dTheta 0.628319
startAng > endAng: 0
startAng < endAng: 0
startAng == endAng: 1
startAng: a803a092 401358a8
endAng:   a803a092 401358a8
dTheta:   769cf0e0 3fe41b2f

Incorrect output:

[glenn@DepotSt ras]$ g++ -O2 ttt.cc -o ttt; ttt
angles not equal
startAng 4.836581, endAng 4.836581, dTheta 0.000000
startAng > endAng: 0
startAng < endAng: 0
startAng == endAng: 1
startAng: a803a092 401358a8
endAng:   a803a092 401358a8
dTheta:   0 0
Comment 1 Glenn Burkhardt 2005-07-10 15:15:20 UTC
Created attachment 9239 [details]
save-temps file that demonstrates problem
Comment 2 Andrew Pinski 2005-07-10 18:09:23 UTC

*** This bug has been marked as a duplicate of 323 ***