On 8/12/2015 10:03 AM, 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. >>> 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. > > Speaking of compilers requiring options to achieve standard behavior: > icl -Qprotect-parens or icl -fp:strict will suppress the fma on this > example. > > Neither gcc nor icc are capable of always optimizing use (or not) of > fma. We've done a lot of benchmarking of -mno-fma vs. (default) > -mfma. icc is improving in this respect. > g++ inner_product is slow with fma. Altering the template seems > hopeless, as it doesn't optimize without -ffast-math (which discards > this aspect of -std=c99). > > Why did gcc reject -fprotect-parens? This is one of the reasons I find > I must split my gcc compiled source code into files which are to be > built with or without -ffast-math . > > Going the other way, to cases where fma is preferable, I find it > annoying that gfortran translates > s(i)*aa(i)+aa(i) > the same as > (s(i)+1.)*aa(i) > and requires (what I don't consider obvious) > (s(i)*aa(i))+aa(i) > to implement by fma. gcc doesn't try this non-optimization. Fortran > rules do encourage the replacement > a*b + c*b => b*(a+c) (avoiding a questionable use of fma) > but I dislike this variant of that optimization. The current Microsoft compiler makes the +1f replacement at /fp:fast. Without :fast, it doesn't use fma.