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:
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)
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
For such a large x like 2806196910506780709 x*x overflows and thus it is undefined behavior.
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?
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.
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.