The following shows a problem on the Alpha whereby the division 2/3 made on floats is flagged as exact. Here are the details: $ cat sf.cc #include <fenv.h> #include <cstdio> int main() { float x = 2; float y = 3; feclearexcept(FE_INEXACT); x = x / y; printf("%d %.1000g\n", fetestexcept(FE_INEXACT) != 0, x); } $ g++ -v Using built-in specs. Target: alpha-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --disable-libssp --with-long-double-128 --enable-checking=release --build=alpha-linux-gnu --host=alpha-linux-gnu --target=alpha-linux-gnu Thread model: posix gcc version 4.2.4 (Debian 4.2.4-3) $ g++ -mieee-with-inexact sf.cc $ ./a.out 0 0.666666686534881591796875 $ cat /proc/cpuinfo cpu : Alpha cpu model : EV56 cpu variation : 7 cpu revision : 0 cpu serial number : system type : Rawhide system variation : Tincup system revision : 0 system serial number : AY74642662 cycle frequency [Hz] : 399642346 est. timer frequency [Hz] : 1200.00 page size [bytes] : 8192 phys. address bits : 40 max. addr. space # : 127 BogoMIPS : 705.16 kernel unaligned acc : 0 (pc=0,va=0) user unaligned acc : 31 (pc=20000074c18,va=87) platform string : AlphaServer 1200 5/400 4MB cpus detected : 1 cpus active : 1 cpu active mask : 0000000000000001 L1 Icache : 8K, 1-way, 32b line L1 Dcache : 8K, 1-way, 32b line L2 cache : 96K, 3-way, 64b line L3 cache : 4096K, 1-way, 64b line $ I attach the generated assembly code, which shows this is not a constant propagation issue.
Created attachment 16359 [details] Assembly code generated with g++ -S -mieee-with-inexact sf.cc
Works for me with: --cut here-- #define _GNU_SOURCE #include <fenv.h> #include <signal.h> #include <stdlib.h> static void foo (int sig) { exit (0); } float __attribute__((noinline)) test (float x) { return 2.0f / x; }; int main() { volatile float x; signal (SIGFPE, foo); feclearexcept (FE_ALL_EXCEPT); feenableexcept (FE_INEXACT); x = test (3.0f); abort (); } --cut here-- $ gcc -O2 -lm -mieee-with-inexact sf.c $ ./a.out $
The test case you have used it's different from the original that showed the bug. Nevertheless it's useful to understand the possible nature of the bug. It seems that if feenableexcept(FE_INEXACT) is not called fetestexcept(FE_INEXACT) doesn't work as expected (and as C99 standard provides). Please note that according to documentation GNU extension feenableexcept/fedisablexcept does not enable/disable inexact detection, but does enable/disable inexact *trapping* via SIGFPE signal. Here below there is a new test case that shows the wrong behaviour. $ cat sf2.c #define _GNU_SOURCE #include <fenv.h> #include <signal.h> #include <stdio.h> static void foo (int sig) { printf("inexact\n"); } float __attribute__((noinline)) test (float x) { printf("%f / %f\n", 2.0f, x); return 2.0f / x; } void t() { volatile float x; feclearexcept (FE_ALL_EXCEPT); x = test (3.0f); printf("fetestexcept(FE_INEXACT) = %d\n", fetestexcept(FE_INEXACT)); feclearexcept (FE_ALL_EXCEPT); x = test (2.0f); printf("fetestexcept(FE_INEXACT) = %d\n", fetestexcept(FE_INEXACT)); } int main() { printf("\nWith FE_INEXACT SIGFPE disabled\n"); t(); printf("\nWith FE_INEXACT SIGFPE enabled\n"); signal (SIGFPE, foo); feenableexcept (FE_INEXACT); t(); } $ gcc -O2 -lm -mieee-with-inexact sf2.c $ ./a.out With FE_INEXACT SIGFPE disabled 2.000000 / 3.000000 fetestexcept(FE_INEXACT) = 0 2.000000 / 2.000000 fetestexcept(FE_INEXACT) = 0 With FE_INEXACT SIGFPE enabled 2.000000 / 3.000000 inexact fetestexcept(FE_INEXACT) = 2097152 2.000000 / 2.000000 fetestexcept(FE_INEXACT) = 0 $
I don't know why the bug was closed: I can confirm the erroneous behavior is present also in GCC 4.3.2.
(In reply to comment #4) > I don't know why the bug was closed: I can confirm the erroneous behavior is > present also in GCC 4.3.2. Because it looks to me that this is libc problem with fetestexcept. As far as the compiler is concerned, GCC correctly decorates trapping instructions with /sui and puts trap barrier to expected place: ... jsr $26,($27),__nldbl_printf !lituse_jsr!5 ldah $29,0($26) !gpdisp!6 divs/sui $f3,$f2,$f0 trapb ...
(In reply to comment #5) > Because it looks to me that this is libc problem with fetestexcept. As far as > the compiler is concerned, GCC correctly decorates trapping instructions with > /sui and puts trap barrier to expected place: > > ... > jsr $26,($27),__nldbl_printf !lituse_jsr!5 > ldah $29,0($26) !gpdisp!6 > divs/sui $f3,$f2,$f0 > trapb > ... I've reported a bug according to the valuable info you provide. http://sourceware.org/bugzilla/show_bug.cgi?id=9783
Not a GCC bug.