Parentheses not honored when using FMA

Marcin Krotkiewski
Wed Aug 12 10:37:00 GMT 2015

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 
   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 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.

This is the assembly generated by 'gcc-5.1.0 -O3 -mfma test.c -c -S'

         vmovsd  8(%rdi), %xmm0
         vmovsd  8(%rsi), %xmm2
         vmovsd  (%rdi), %xmm1
         vsubsd  %xmm0, %xmm2, %xmm3
         vmovsd  (%rdx), %xmm2
         vsubsd  %xmm1, %xmm2, %xmm2
         vmulsd  %xmm2, %xmm3, %xmm2
         vmovsd  (%rsi), %xmm3
         vsubsd  %xmm1, %xmm3, %xmm3
         vmovsd  8(%rdx), %xmm1
         vsubsd  %xmm0, %xmm1, %xmm1
         vfmsub132sd     %xmm1, %xmm2, %xmm3
         vmovapd %xmm3, %xmm0

I believe that in order to honor the parentheses gcc should NOT generate 
the FMA, but stick to the programmed operation order. If I wanted a FMA, 
I would not use parentheses around the multiplications. Current behavior 
of gcc results in inconsistent behavior in my code due to floating point 
arithmetic errors.

As a side note, the Intel compiler does exactly the same thing.

Can this be considered a bug, or is this the expected behavior? If this 
is ok, how can I assure in a portable way the effect that I need?


Marcin Krotkiewski

More information about the Gcc-help mailing list