Bug 83235 - IAND sometimes doesn't take bitwise-and of sign bit with -O2
Summary: IAND sometimes doesn't take bitwise-and of sign bit with -O2
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 7.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2017-11-30 21:54 UTC by Paul Romano
Modified: 2017-12-01 13:28 UTC (History)
2 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed:

Minimal example of IAND bug (180 bytes, text/plain)
2017-11-30 21:54 UTC, Paul Romano

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Romano 2017-11-30 21:54:09 UTC
Created attachment 42760 [details]
Minimal example of IAND bug

I ran into what appears to be a strange bug where the IAND intrinsic function sometimes doesn't take the bitwise-and of the sign bit for 64-bit integers. I've attached a MWE that demonstrates the bug, which can be reproduced by compiling with -O2 or higher. The example writes the bit representation of two 64-bit integers and the result of taking IAND() on them and you can see that the result of IAND doesn't handle the sign bit correctly. Several slight changes seem to suppress the bug, e.g. having the second argument to IAND not be and integer parameter and putting the body of foo in the main program.

I produced this bug using the default gcc from APT in Ubuntu 17.10, as follows:

Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.2.0-8ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.2.0 (Ubuntu 7.2.0-8ubuntu3)
Comment 1 kargl 2017-12-01 07:46:44 UTC
A modification of your code to print decimal shows

  x = 2806196910506780709
x*x = -5105260488395614887
  y = 9223372036854775807

The bit model specifically states that "The interpretation of a
negative integer as a sequence of bits is processor dependent."
The definition of the IAND intrinsic also states "The model for the
interpretation of an integer value as a sequence of bits is in
13.3". Unfortunately, Fortran does not have an unsigned integer
Comment 2 Jakub Jelinek 2017-12-01 08:35:47 UTC
For such a large x like 2806196910506780709 x*x overflows and thus it is undefined behavior.
Comment 3 Paul Romano 2017-12-01 12:40:26 UTC
Thank you both for your quick responses. I understand that the bit model for negative numbers is undefined and that x*x overflows and is thus also undefined. However, the second argument to IAND is well-defined: it's a bit mask with only the most significant bit zeroed. I would have thought that this would guarantee that the resulting number would have its most significant bit zeroed, regardless of whatever was passed as the first argument to IAND. Is there really no way to guarantee that?
Comment 4 Jakub Jelinek 2017-12-01 13:23:21 UTC
That is a bad understanding of what undefined behavior means.  After you invoke undefined behavior anywhere in your program, anything can happen, there are no constraints on what can happen.
Comment 5 Paul Romano 2017-12-01 13:28:18 UTC
Got it; thanks for the clarification, and sorry for the noise! Guess I'll just have to stop relying on this "feature" of previous versions.