<div dir="ltr">This is just paraphrasing from D26602, so credit to Nicolai for first raising the issue there.<br><br>float foo(float x, float y) {<br>  return x * (y + 1);<br>}<br><br>$ ./clang -O2 xy1.c -S -o - -target aarch64  -ffp-contract=fast | grep fm<br>    fmadd    s0, s1, s0, s0<br><br>Is this a bug? We transformed the original expression into:<br>x * y + x<br><br>When x=INF and y=0, the code returns INF if we don't reassociate. With reassociation to FMA, it returns NAN because 0 * INF = NAN.<br><br>1. I used aarch64 as the example target, but this is not target-dependent (as long as the target has FMA).<br><br>2. This is *not* -ffast-math...or is it? The C standard only shows on/off settings for the associated FP_CONTRACT pragma.<br><br>3. AFAIK, clang has no documentation for -ffp-contract:<br><a href="http://clang.llvm.org/docs/UsersManual.html">http://clang.llvm.org/docs/UsersManual.html</a><br><br>4. GCC says:<br><a href="https://gcc.gnu.org/onlinedocs/gcc-6.2.0/gcc/Optimize-Options.html#Optimize-Options">https://gcc.gnu.org/onlinedocs/gcc-6.2.0/gcc/Optimize-Options.html#Optimize-Options</a><br>"-ffp-contract=fast enables floating-point expression contraction such as forming of fused multiply-add operations if the target has native support for them."<br><br>5. The LLVM backend (where this reassociation currently happens) shows:<br>FPOpFusion::Fast - Enable fusion of FP ops wherever it's profitable.<span class="gmail-transaction-comment"><br><br></span></div>