[Bug rtl-optimization/85811] New: Invalid optimization with fmax, fabs and nan
mpeddie at gmail dot com
gcc-bugzilla@gcc.gnu.org
Wed May 16 21:18:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85811
Bug ID: 85811
Summary: Invalid optimization with fmax, fabs and nan
Product: gcc
Version: 8.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: mpeddie at gmail dot com
Target Milestone: ---
Created attachment 44139
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44139&action=edit
Preprocessed source file
I apologize in advance if I've chosen the wrong category for this bug; I have
to choose a category and don't know what's correct.
The output from my small test program varies depending on whether I enable
optimizations with -O. The un-preprocessed program is the following
(preprocessed output attached):
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc __attribute__((unused)), char **argv
__attribute__((unused))) {
const double negval = -1.0;
const double nanval = 0.0 / 0.0;
const double val = fmax(negval, nanval);
const double absval = fabs(val);
printf("fabs(%.16e) = %.16e\n", val, absval);
return absval >= 0 ? 0 : 1;
}
With optimizations enabled, this prints
fabs(-1.0000000000000000e+00) = -1.0000000000000000e+00
and returns 1. This result is wrong (the absolute value must be positive).
Without optimizations, it prints
fabs(1.0000000000000000e+00) = 1.0000000000000000e+00
and returns 0 as expected. If I make the arguments to fmax() depend on inputs,
for example the value of argc, the program behaves correctly. If I call fmin()
instead of fmax(), the program behaves correctly. If neither of the arguments
to fmax() is NaN, the program behaves correctly; the correct behavior happens
if one argument is -NaN, INFINITY or -INFINITY. The order of arguments to
fmax() does not affect the result of the program.
If I look at the generated assembly, substituting fmin() for fmax() in the test
program results in an andpd instruction immediately after fmin() that isn't
emitted when fmax() is called.
The attached file test.i is the preprocessed source file. The test program
compiles without errors or warnings and never triggers the undefined-behavior
sanitizer. I've observed the same problem with gcc version 7.3.0 and 6.4.0 for
x86_64 as well as gcc version 6.3.0 for arm32. I don't see the problem with
gcc version 5.5.0 for x86_64. Below is the command-line invocation of gcc
along with its complete output.
gcc-8 -v -save-temps -O -Wall -Wextra -Werror -fsanitize=undefined
-fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations -lm test.c -o
test
Using built-in specs.
COLLECT_GCC=gcc-8
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 8.1.0-3'
--with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs
--enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr
--with-gcc-major-version-only --program-suffix=-8
--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 8.1.0 (Debian 8.1.0-3)
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O' '-Wall' '-Wextra' '-Werror'
'-fsanitize=undefined' '-fno-strict-aliasing' '-fwrapv'
'-fno-aggressive-loop-optimizations' '-o' 'test' '-mtune=generic'
'-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/8/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu
test.c -mtune=generic -march=x86-64 -Wall -Wextra -Werror -fsanitize=undefined
-fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations -O
-fpch-preprocess -o test.i
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/8/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O' '-Wall' '-Wextra' '-Werror'
'-fsanitize=undefined' '-fno-strict-aliasing' '-fwrapv'
'-fno-aggressive-loop-optimizations' '-o' 'test' '-mtune=generic'
'-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/8/cc1 -fpreprocessed test.i -quiet -dumpbase
test.c -mtune=generic -march=x86-64 -auxbase test -O -Wall -Wextra -Werror
-version -fsanitize=undefined -fno-strict-aliasing -fwrapv
-fno-aggressive-loop-optimizations -o test.s
GNU C17 (Debian 8.1.0-3) version 8.1.0 (x86_64-linux-gnu)
compiled by GNU C version 8.1.0, GMP version 6.1.2, MPFR version 4.0.1,
MPC version 1.1.0, isl version isl-0.19-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C17 (Debian 8.1.0-3) version 8.1.0 (x86_64-linux-gnu)
compiled by GNU C version 8.1.0, GMP version 6.1.2, MPFR version 4.0.1,
MPC version 1.1.0, isl version isl-0.19-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: bbc65a5a9118b9b79402871f4ead4543
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O' '-Wall' '-Wextra' '-Werror'
'-fsanitize=undefined' '-fno-strict-aliasing' '-fwrapv'
'-fno-aggressive-loop-optimizations' '-o' 'test' '-mtune=generic'
'-march=x86-64'
as -v --64 -o test.o test.s
GNU assembler version 2.30 (x86_64-linux-gnu) using BFD version (GNU Binutils
for Debian) 2.30
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/8/:/usr/lib/gcc/x86_64-linux-gnu/8/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/8/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/8/:/usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/8/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/8/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O' '-Wall' '-Wextra' '-Werror'
'-fsanitize=undefined' '-fno-strict-aliasing' '-fwrapv'
'-fno-aggressive-loop-optimizations' '-o' 'test' '-mtune=generic'
'-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/8/collect2 -plugin
/usr/lib/gcc/x86_64-linux-gnu/8/liblto_plugin.so
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper
-plugin-opt=-fresolution=test.res -plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/
--build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker
/lib64/ld-linux-x86-64.so.2 -pie -o test
/usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/Scrt1.o
/usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/8/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/8
-L/usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu
-L/usr/lib/gcc/x86_64-linux-gnu/8/../../../../lib -L/lib/x86_64-linux-gnu
-L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib
-L/usr/lib/gcc/x86_64-linux-gnu/8/../../.. -lm test.o -lubsan -lgcc
--push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed
-lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/8/crtendS.o
/usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/crtn.o
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O' '-Wall' '-Wextra' '-Werror'
'-fsanitize=undefined' '-fno-strict-aliasing' '-fwrapv'
'-fno-aggressive-loop-optimizations' '-o' 'test' '-mtune=generic'
'-march=x86-64'
More information about the Gcc-bugs
mailing list