This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC 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]

[Bug c/53857] New: Possible problem with arithmetic overflow in optimizer


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

             Bug #: 53857
           Summary: Possible problem with arithmetic overflow in optimizer
    Classification: Unclassified
           Product: gcc
           Version: 4.7.1
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: 00wuwu@gmail.com


Created attachment 27743
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=27743
Program showing the problem

Hi

We found unusual behaviour of compilator which probably assumes there is no
arithmetic overflow and then simplifies the code too much.

We attach the simplest code which illustrates the problem. Make will create
several binaries including: "testo1" and "testo2". The first is compiled with
-O1 option, the other with -O2.

For the gcc 4.6 (or clang'a 3.1) everything is fine. Both programs write:
x: 2147483648, y: 2147483648

For gcc 4.7.1 (also 4.7) program "testo1" writes the same as above but "testo2"
will write:
x: 18446744071562067968, y: 18446744071562067968

What is interesting the problem appears on both architectures: x86_64 (Intel
64-bit) and i386 (Intel 32-bit).

We made tests with options "-fno-strict-overflow" and "-fwrapv". Compilation
with only "-fno-strict-overflow" option still generates the code which gives
wrong results. Compilation with "-fwrapv" gived the proper code. But still the
behaviour differs from 4.6 version.

According to us code
"x64|=(uint32_t)(some_arithmetic_operations_on_signed_integers_with_overflow)"
should in no case set high 32 bits of x64 variable independently of options
used.

Even if overflow result in
"some_arithmetic_operations_on_signed_integers_with_overflow" fragment is not
specified, then type casting to uint32_t should never return negative number,
which expanded to 64 bits will cause setting high 32 bits of x64 variable. We
need to take into account that
"some_arithmetic_operations_on_signed_integers_with_overflow" may return a
negative number (even without any overflows), so treatment of overflows should
not change anything here - after casting to uint32_t we should always get a
32-bit unsigned number which by the "|=" operation with 64-bit number with no
sign should also expand to 64-bit number with no sign by adding 32 high bits
filled with zeros. 

Even when we assume that the result of
"some_arithmetic_operations_on_signed_integers_with_overflow" has "undefined
behavior", then after casting it to uint32_t only lower 32 bits should remain
undefined but here we can see that the result has also impact on the high bits
(even without any warning).

What is suspicious compilation behaves in very unpredictable way. The same
expression compiled with the same options may give different results. When we
change this fragment "y = get64bit(&rp);" to: "y = 0;" then the second variable
"x" will return proper results. 


MooseFS Team
http://www.moosefs.org/


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