This is the mail archive of the cygwin mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

possible compiler optimization error

On Windows I have found that a program I wrote fails when compiled with
-O1 and -O2 but runs fine with -O0.
The program behaves correctly on Linux and Solaris with or without

The place it starts behaving differently on Windows is where two numbers
(which should be equal) are failing a greater than or equal to (>=) if
statement, but on Solaris and Linux it passes.

My first thought was that this had to do with floating point
representation differences on the systems but it doesn't appear to be.
It appears to be a compiler error.

The first thing I did was start to print out an equality matrix of the
double array I was using.
I was expecting to find a difference in the equality matrices between
Linux/Solaris and Windows.
There was none.
This meant that two numbers which pass an equality (==) check (for the
purposes of printing the matrix), later failed on a greater than or
equal to (>=) check which actually affected program flow.
I then created a corresponding else statement and did some more checking
of the two numbers and they then pass a greater than or equal to (>=)

So, in summary two doubles pass on ==, then fail on >=, then pass ==,
>=, <= while never being modified.  Does this imply compiler error?

I have attached two files example.c and example.out which are just
excerpts from the code and output.
In example.c I have two versions of the function where the problem is
happening.  One is the original and one has all of the debugging fprintf
statements that produced the example.out.  Both versions have the same
bad behavior, I just wanted to include the clean one so you can see what
it is doing.

The function in example.c that is failing is called combineOverlaps
which just takes line sections (on a circle) and combines them if they
overlap into a bigger section.
A section is a simple structure with a double "from" and a double "to".
The equality matrix for the failing iteration (Lines 214 to 223 from
example.out) is...
  0 1 2 3

This shows that section[0]'s "to" is equal to section[1]'s "from"
It actually passed twice since I'm printing the full matrix.

Lines 228 to 230 of example.out are being printed from else clause
(lines 129 to 136 in example.c) after it fails the >= check and shows
that afterwards it passes all those other equality checks.

Here is a summary of where it works and where it doesn't.

OS      Env         GCC     Options         Pass/Fail

Windows Msys/mingw  3.4.5   -O2             Fail

Windows Cygwin      3.4.4   -mno-cygwin -02 Fail
Windows Cygwin      3.4.4   -02             Fail
Windows Cygwin      4.1.1   -02             Fail

Windows Cygwin      3.4.4   -mno-cygwin -00 Pass
Windows Cygwin      3.4.4   -00             Pass
Windows Cygwin      4.1.1   -00             Pass

Linux               4.1.1   -02             Pass
Linux               3.4.6   -O2             Pass

Solaris             4.1.1   -02             Pass

It fails on Windows with any optimization in both 3.4.4 and 4.1.1, so it
is not just happening on one particular version of the compiler.

If a program compiled with -O0 has different output than the same
program compiled with -O1 or -O2, is that defiantly a compile error?
I do realize that it could be a combination of compiler optimizations
along with the platform's representation of floating point numbers, but
isn't that something the compiler should be aware of be careful about?

Any insight is appreciated.


Attachment: example.c
Description: example.c

Attachment: example.out
Description: example.out

Unsubscribe info:
Problem reports:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]