Parentheses not honored when using FMA

Vincent Lefevre vincent+gcc@vinc17.org
Fri Aug 14 15:13:00 GMT 2015


On 2015-08-12 08:40:47 -0400, Tim Prince wrote:
> On 8/12/2015 7:03 AM, Marc Glisse wrote:
> > On Wed, 12 Aug 2015, Marcin Krotkiewski wrote:
> >
> >> Hello, all,
> >>
> >> I have doubts about asm generated for the following code that
> >> performs orientation test for a point and a segment:
> >>
> >> double orient_test_2d(const double m[2], const double a[2], const
> >> double b[2])
> >> {
> >>  double am1 = a[0]-m[0];
> >>  double bm1 = b[1]-m[1];
> >>  double am2 = a[1]-m[1];
> >>  double bm2 = b[0]-m[0];
> >>
> >>  return ((am1)*(bm1)) - ((am2)*(bm2));
> >> }
> >>
> >> In the return statement the operands are all in parentheses. gcc
> >> optimizes
> >
> > Parentheses don't have the meaning you believe they have in C. All
> > those in your return statement are useless.
> No, this is a -std=gnu99 peculiarity which resembles K&R treatment.  I
> know some people do mean K&R when they say C.

ISO C. The parentheses are useless here. I mean, according to the
ISO C99 standard, they don't change the meaning of the expression.
AFAIK, the C99 standard just says:

  A parenthesized expression is a primary expression. Its type and
  value are identical to those of the unparenthesized expression.

Ditto for the current ISO C11 standard.

> >> the statement and introduces a FMA instruction. I think this is wrong
> >> because FMA causes the subtraction and multiplication to be
> >> effectively executed at the same time, while the source specifies
> >> that the multiplications should be performed before the subtraction.
> >
> > -ffp-contract=off
> >
> Why not gcc -std=c99 .... ?  It appears to answer the original question. 

Probably because with recent GCC versions, -ffp-contract=on is now
an alias for -ffp-contract=off in ISO C mode, due to the fact that
the FP_CONTRACT pragma is not implemented by GCC. This has been
changed (fixed) by:

2013-11-06 16:52:47 (rev 204460, jsm28)

  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;

See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37845

But this may change once the FP_CONTRACT pragma is implemented in GCC.
So, for future GCC versions and other compilers, one *also* needs:

#pragma STDC FP_CONTRACT OFF

An advantage of the pragma is that one may forbid FP contraction
only on some parts of the program.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)



More information about the Gcc-help mailing list