<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Hi Ana,</div><div class=""><br class=""></div>It would change the behavior of a lot of existing software in subtle ways to let -std=gnu11 license fp-contract=fast.  I’m honestly rather surprised that GCC made that choice.<br class=""><br class="">I’m not sure what you mean by "We know the instruction produces results with higher precision and compliant to IEEE 754 standard.”  FMA produces *different* results than FMUL + FADD, but they are not always more accurate.  The classical example of naive FMA formation gone wrong is multiplying a complex number by its conjugate.  The imaginary part *should* be zero, but when FMA formation is licensed, one generally gets a small non-zero imaginary part.<br class=""><br class="">IEEE doesn’t actually license fma formation.  I’m not sure where you got the idea that it does.  It doesn’t expressly forbid it either.  Rather it makes the following recommendations:<br class=""><br class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class="">"A language standard should require that by default, when no optimizations are enabled and no alternate exception handling is enabled, language implementations preserve the literal meaning of the source code.”</blockquote><br class="">This means that by--default--an implementation should not transform FMUL + FADD into FMADD.  It encourages this transform to be available as an option, however:<br class=""><br class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">"A language standard should also define, and require implementations to provide, attributes that allow and disallow value-changing optimizations, separately or collectively, for a block. These optimizations might include, but are not limited to:</div><div class=""><br class=""></div><div class="">―  Applying the associative or distributive laws.</div><div class="">―  Synthesis of a fusedMultiplyAdd operation from a multiplication and an addition. </div><div class="">―  Synthesis of a formatOf operation from an operation and a conversion of the result of the operation.</div><div class="">―  Use of wider intermediate results in expression evaluation."</div></blockquote><div class=""><br class=""></div><div class="">Note that the other transforms that IEEE-754 groups in with FMA formation here are all things that we license only under fast-math.</div><div class=""><br class=""></div>Now, it so happens that fma formation makes results more accurate more often than it makes them less accurate.  It is *usually* a good thing, so the case isn’t quite a cut and dry as I’m presenting it to be.  It’s also quite beneficial for performance on many platforms (but rather detrimental to performance on some other platforms with hardware FMA support, so again the case is not terribly clear).<div class=""><br class=""></div><div class="">It should also be noted that -ffp-contract=fast goes beyond what is allowed by the C rules for #pragma STDC FP_CONTRACT ON (which allows fma formation only within an expression):</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><b class="">scanon</b>$ cat foo.c</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class="">#pragma STDC FP_CONTRACT ON</div></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><br class=""></div></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class="">float foo(float x, float y, float z) {</div></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class="">  return x*y + z; // fma formation is licensed here.</div></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class="">}</div></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><br class=""></div></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class="">float bar(float x, float y, float z) {</div></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class="">  float p = x*y;</div></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class="">  return p + z;<span class="Apple-tab-span" style="white-space:pre">      </span>// fma formation is not licensed here.</div></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class="">}</div></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><b class="">scanon</b>$ clang fma.c -Os -c -arch arm64 && otool -tvV fma.o</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">fma.o:</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">(__TEXT,__text) section</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">_foo:</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">0000000000000000<span class="Apple-tab-span" style="white-space:pre">   </span>fmadd<span class="Apple-tab-span" style="white-space:pre">       </span>s0, s0, s1, s2 // fma only where licensed</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">0000000000000004<span class="Apple-tab-span" style="white-space:pre">      </span>ret</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">_bar:</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">0000000000000008<span class="Apple-tab-span" style="white-space:pre">  </span>fmul<span class="Apple-tab-span" style="white-space:pre">        </span>s0, s0, s1</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">000000000000000c<span class="Apple-tab-span" style="white-space:pre">     </span>fadd<span class="Apple-tab-span" style="white-space:pre">        </span>s0, s0, s2</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">0000000000000010<span class="Apple-tab-span" style="white-space:pre">     </span>ret</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><b class="">scanon</b>$ clang fma.c -Os -c -arch arm64 -ffp-contract=fast && otool -tvV fma.o</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">fma.o:</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">(__TEXT,__text) section</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">_foo:</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">0000000000000000<span class="Apple-tab-span" style="white-space:pre">   </span>fmadd<span class="Apple-tab-span" style="white-space:pre">       </span>s0, s0, s1, s2</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">0000000000000004<span class="Apple-tab-span" style="white-space:pre"> </span>ret</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">_bar:</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">0000000000000008<span class="Apple-tab-span" style="white-space:pre">  </span>fmadd<span class="Apple-tab-span" style="white-space:pre">       </span>s0, s0, s1, s2 // fma even where not licensed</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">000000000000000c<span class="Apple-tab-span" style="white-space:pre">  </span>ret</div></div></blockquote><div class=""><br class=""></div><div class="">Now, it *does* appear to me that we do not default to having STDC FP_CONTRACT ON, which is inhibiting fma formation *even within an expression*.  Given that we support STDC FP_CONTRACT OFF, we could certainly choose to make ON the default, and I would encourage doing so.</div><div class=""><br class=""></div><div class="">– Steve</div><div class=""><br class=""><blockquote type="cite" class="">On Sep 18, 2015, at 4:52 PM, Ana Pazos via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:<br class=""><br class="">Hi folks,<br class=""> <br class="">GNU GCC allows fused multiply add instruction generation in –std=gnu* modes (default  mode in GCC) on both ARM 32-bit and 64-bit targets. See outputs below.<br class=""> <br class="">Clang 3.8 defaults to gnu11 for C programs, according to <a href="http://clang.llvm.org/docs/UsersManual.html#c-language-features" class="">http://clang.llvm.org/docs/UsersManual.html#c-language-features</a>  and function  CompilerInvocation::setLangDefaults in ./lib/Frontend/CompilerInvocation.cpp in the Clang source code.<br class=""> <br class="">So why  fp-contract=fast is not made default in Clang as it is done in GNU GCC?<br class=""> <br class="">Just trying to understand the rationale behind this decision. We know the instruction  produces results with higher precision and compliant to IEEE 754 standard.<br class=""> <br class="">This difference in default behavior in Clang/LLVM compared to GNU GCC is a performance disadvantage.<br class=""> <br class="">Thanks!<br class="">Ana.<br class=""> <br class="">$ cat t.c<br class="">double f(double a, double b)<br class="">{<br class="">return b*b+a*a;<br class="">}<br class=""> <br class="">$ gcc-linaro-4.9-2015.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -S -O3 -o- -std=c99 t.c<br class="">        .cpu generic+fp+simd<br class="">        .file   "t.c"<br class="">        .text<br class="">        .align  2<br class="">        .global f<br class="">        .type   f, %function<br class="">f:<br class="">        fmul    d1, d1, d1<br class="">        fmul    d0, d0, d0<br class="">        fadd    d0, d1, d0<br class="">        ret<br class="">        .size   f, .-f<br class="">        .ident  "GCC: (Linaro GCC 4.9-2015.05) 4.9.3 20150413 (prerelease)"<br class="">        .section        .note.GNU-stack,"",%progbits<br class="">$ gcc-linaro-4.9-2015.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -S -O3 -o- -std=gnu99 t.c<br class="">        .cpu generic+fp+simd<br class="">        .file   "t.c"<br class="">        .text<br class="">        .align  2<br class="">        .global f<br class="">        .type   f, %function<br class="">f:<br class="">        fmul    d0, d0, d0<br class="">        fmadd   d0, d1, d1, d0<br class="">        ret<br class="">        .size   f, .-f<br class="">        .ident  "GCC: (Linaro GCC 4.9-2015.05) 4.9.3 20150413 (prerelease)"<br class="">        .section        .note.GNU-stack,"",%progbits<br class="">$ gcc-linaro-4.9-2015.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -S -O3 -o-  t.c<br class="">        .cpu generic+fp+simd<br class="">        .file   "t.c"<br class="">        .text<br class="">        .align  2<br class="">        .global f<br class="">        .type   f, %function<br class="">f:<br class="">        fmul    d0, d0, d0<br class="">        fmadd   d0, d1, d1, d0<br class="">        ret<br class="">        .size   f, .-f<br class="">        .ident  "GCC: (Linaro GCC 4.9-2015.05) 4.9.3 20150413 (prerelease)"<br class="">        .section        .note.GNU-stack,"",%progbits<br class=""> <br class=""> <br class="">Ana Pazos<br class="">Qualcomm Innovation Center, Inc.<br class="">The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, <br class="">a Linux Foundation Collaborative Project.<br class=""><br class=""> <br class=""> <br class="">_______________________________________________<br class="">cfe-dev mailing list<br class="">cfe-dev@lists.llvm.org<br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev<br class=""></blockquote><br class=""></div></body></html>