To be conform to the ISO C standard (when FLT_EVAL_METHOD is 0, 1 or 2, which is the case of gcc), gcc should either take FP_CONTRACT pragmas into account or (in the mean time) assume they are set to OFF, i.e. disallow the contraction of floating expressions. This means in particular that -mno-fused-madd should be the default (with processors for which this option is supported, e.g. PowerPC). I've tested with gcc-4.4-20081010 on ia64 that this bug is still present.
Confirmed. The FP_CONTRACT macro is not implemented, but the default behavior of GCC is to behave like it was set to OFF. This is a target issue (sofar ia64 is identified as buggy).
The fma patterns on ia64 are not guarded properly. They should be off as long as flag_unsafe_math_optimizations is not specified.
(In reply to comment #1) > Confirmed. The FP_CONTRACT macro is not implemented, but the default behavior > of GCC is to behave like it was set to OFF. The problem is that on PowerPC, x*y+z is fused (contracted) by default (which is forbidden when FP_CONTRACT is OFF). I could test only with Apple's gcc 4.0.1, but the man page of the gcc snapshot implies that the problem remains with the current versions: IBM RS/6000 and PowerPC Options -mfused-madd -mno-fused-madd Generate code that uses (does not use) the floating point multiply and accumulate instructions. These instructions are generated by default if hardware floating is used. But the correct behavior would be that these instructions should not be generated by default. On http://www.vinc17.org/software/tst-ieee754.c compiled with gcc -Wall -O2 -std=c99 tst-ieee754.c -o tst-ieee754 -lm I get: $ ./tst-ieee754 | grep fused x * y + z with FP_CONTRACT OFF is fused. I need to add -mno-fused-madd to get the correct behavior: $ ./tst-ieee754 | grep fused x * y + z with FP_CONTRACT OFF is not fused.
Subject: Re: gcc ignores FP_CONTRACT pragma set to OFF Sent from my iPhone On Oct 16, 2008, at 2:42 AM, "rguenth at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org > wrote: > > > ------- Comment #2 from rguenth at gcc dot gnu dot org 2008-10-16 > 09:42 ------- > The fma patterns on ia64 are not guarded properly. They should be off > as long as flag_unsafe_math_optimizations is not specified. No that is not true. They should be on by default. > > > > -- > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37845 >
Subject: Re: gcc ignores FP_CONTRACT pragma set to OFF On Thu, 16 Oct 2008, rguenth at gcc dot gnu dot org wrote: > Confirmed. The FP_CONTRACT macro is not implemented, but the default behavior > of GCC is to behave like it was set to OFF. No, the default is to behave like it is ON, on targets with fused operations, with target-specific options to turn it off. A default of ON is fine according to C99. It so happens that GCC's version of "ON" is buggy, in that it contracts even outside the bounds of source language expressions - those boundaries are lost at gimplification, long before the insn patterns are applied. Fixing this would probably require fused operations to be identified in the front end in conforming mode, and the only insn patterns in conforming mode for the fused instructions to have RTL describing them precisely as fused operations so non-fused ones don't get combined. This situation is much like the other floating-point pragmas: * GCC doesn't support any of the pragmas, and doesn't claim to support those parts of C99; the features can only be enabled or disabled for a whole translation unit on the command line. * The features for a whole translation unit are in practice rather buggy and incomplete. -fno-cx-limited-range (on by default) doesn't work for constant arithmetic (bug 30789). -ftrapping-math (on by default) doesn't cause all required exceptions to be generated, and spurious exceptions are generated in some cases; no real effort has been made to get it to work properly in all cases. -frounding-math (off by default) comes with a specific warning in the manual that it's experimental and incomplete, which is quite correct. Yes, there should be a target-independent option to disable contracting rather than needing separate options for each target, and in conformance mode (flag_iso) contracting, if enabled, should be restricted to source language expressions. I'm not aware of anyone working on this, or on the other issues with the options approximating to the standard pragmas, or on the pragmas themselves.
This bug has been fixed by: r204460 | jsm28 | 2013-11-06 17:52:47 +0100 (Wed, 06 Nov 2013) | 9 lines Changed paths: M /trunk/gcc/c-family/ChangeLog M /trunk/gcc/c-family/c-cppbuiltin.c M /trunk/gcc/c-family/c-opts.c M /trunk/gcc/testsuite/ChangeLog A /trunk/gcc/testsuite/gcc.dg/torture/c99-contract-1.c c-family: * c-opts.c (c_common_post_options): Set -ffp-contract=off in C standards modes. * c-cppbuiltin.c (cpp_iec_559_value): Consider -ffp-contract=fast to mean lack of IEEE 754 support. testsuite: * gcc.dg/torture/c99-contract-1.c: New test. gcc/c-family/c-opts.c now contains: /* ISO C restricts floating-point expression contraction to within source-language expressions (-ffp-contract=on, currently an alias for -ffp-contract=off). */ if (flag_iso && !c_dialect_cxx () && (global_options_set.x_flag_fp_contract_mode == (enum fp_contract_mode) 0) && flag_unsafe_math_optimizations == 0) flag_fp_contract_mode = FP_CONTRACT_OFF; I tested, and this works as expected. Note: This bug was about FP contraction being done despite the use of: #pragma STDC FP_CONTRACT OFF not about the pragma being ignored (the implementation of this pragma is not required by the ISO C standard if the default is OFF, which is now the case with GCC). So, this bug is really fixed. A new enhancement bug could be opened (if not already done) for the implementation of the STDC FP_CONTRACT pragma.
Created attachment 45464 [details] [GCOV] Wrong frequencies when a global variable is in a while expression in gcov $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.3.0-27ubuntu1~18.04' --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.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04) $ cat small.c int b; void main() { int c = 0; while (b) { c = 1; } } $ gcc small.c --coverage; ./a.out; gcov small.c; cat small.c.gcov File 'small.c' Lines executed:80.00% of 5 Creating 'small.c.gcov' -: 0:Source:small.c -: 0:Graph:small.gcno -: 0:Data:small.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:int b; -: 2: 1: 3:void main() -: 4:{ 1: 5: int c = 0; 2: 6: while (b) { #####: 7: c = 1; -: 8: } 1: 9:} We can find that Line #6 is wrongly marked as executed twice.