<div dir="ltr"><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">There is no way to disable FMAs with 'fast' ops in LLVM. I would like to propose that LLVM's -fp-contract=off should disable fusion, regardless of any other flags since the Clang option suggests this to be the case: </span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"> </span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">$ clang --help | grep fp-contract<br>  -ffp-contract=<value>   Form fused FP ops (e.g. FMAs): fast (everywhere) | on (according to FP_CONTRACT pragma, default) | off (never fuse)</span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"> </span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">Current behaviour in LLVM 8.0 below:</span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"> </span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">$ cat fma.ll <br>define double @fmadd(double %a, double %b, double %c) {<br>  %mul = fmul fast double %b, %a<br>  %add = fadd fast double %mul, %c<br>  ret double %add<br>}</span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"> </span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">$ llc -mattr=+fma  fma.ll -fp-contract=off </span><span style="color:rgb(0,0,0);font-family:Calibri,sans-serif">-o - </span><span style="color:black;font-family:Calibri,sans-serif;font-size:inherit;font-style:inherit;font-variant-ligatures:inherit;font-variant-caps:inherit;font-weight:inherit">| grep vfmadd</span></p></div><p style="color:rgb(32,31,30);font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">vfmadd213sd %xmm2, %xmm1, %xmm0 # xmm0 = (xmm1 * xmm0) + xmm2</span></p><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"> </span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">It still generates an fma due to the logic in DAGCombiner:</span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"> </span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">  bool CanFuse = Options.UnsafeFPMath || isContractable(N);<br>  bool AllowFusionGlobally = (Options.AllowFPOpFusion == FPOpFusion::Fast ||<br>                              CanFuse || HasFMAD);</span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"> </span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">In this case, UnsafeFPMath is false but isContractable() is true since the FADD node is tagged as 'fast'. A simple fix would just be to check for -fp-contract=off, however, I also found there is disagreement in the LLVM -fp-contract option itself:</span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"> </span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">in TargetOptions.h, =off maps to FPOpFusion::Strict and says "Never fuse FP-ops", yet the actual cl::opt for =off/Strict says: "Only fuse FP ops when the result won't be affected".</span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"> </span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">Which is it supposed to be? At a minimum we should clear up the discrepancy, but there are two general approaches I see:</span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"> </span></p></div><p style="color:rgb(32,31,30);font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">Option 1: </span></p><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">- rename Strict to Off in llvm and always diable FMAs with this option</span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><div style="margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;color:inherit"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">- does not require changes to Clang</span></p><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"><br></span></p><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">Example logic:</span></p><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="color:rgb(34,34,34);font-family:Arial,Helvetica,sans-serif;font-size:small">  bool AllowFusionGlobally = Options.AllowFPOpFusion != FPOpFusion::Off &&</span><br style="color:rgb(34,34,34);font-family:Arial,Helvetica,sans-serif;font-size:small"><span style="color:rgb(34,34,34);font-family:Arial,Helvetica,sans-serif;font-size:small">                             (Options.AllowFPOpFusion == FPOpFusion::Fast ||</span><br style="color:rgb(34,34,34);font-family:Arial,Helvetica,sans-serif;font-size:small"><span style="color:rgb(34,34,34);font-family:Arial,Helvetica,sans-serif;font-size:small">                              CanFuse || HasFMAD</span><span style="color:rgb(34,34,34);font-family:Arial,Helvetica,sans-serif;font-size:small">);</span>  <br></p><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"><br></span></p></div><div style="margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;color:inherit"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"> </span></p></div><div style="margin:0px;padding:0px;border:0px;font:inherit;vertical-align:baseline;color:inherit"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">Option 2: </span></p></div></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">- keep =strict, add =off to turn off FMAs</span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">- add =strict to clang as it does not currently exist </span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;line-height:inherit;vertical-align:baseline"><p style="font-size:12pt;color:rgb(32,31,30);font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">- tie uses of ::Strict to the presence of FMAD (which might have been the intention?) </span></p><p style="font-size:12pt;color:rgb(32,31,30);font-family:"Times New Roman",serif;margin:0px"><br></p><p style="font-size:12pt;margin:0px"><font color="#000000" face="Calibri, sans-serif">Example logic:</font></p><p style="margin:0px">  bool AllowFusionGlobally = Options.AllowFPOpFusion != FPOpFusion::Off &&<br>                             (Options.AllowFPOpFusion == FPOpFusion::Fast ||<br>                              CanFuse || <br>                             (HasFMAD && Options.AllowFPOpFusion == FPOpFusion::Strict));<font color="#000000" face="Calibri, sans-serif" style=""><br></font></p><p style="font-size:12pt;margin:0px"><font color="#000000" face="Calibri, sans-serif"><br></font></p><p style="font-size:12pt;margin:0px"><font color="#000000" face="Calibri, sans-serif"><br></font></p><p style="font-size:12pt;margin:0px"><br></p><p style="font-size:12pt;color:rgb(32,31,30);font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">Is there context I am not aware of for ::Strict and ISD::FMAD? I could see value in generating FMAs when its expanded form would be identical -- but curious if that was actually the intent or not. If it is, perhaps we could allow "Standard/on" to fuse ops if FMAD is available instead of the "Strict" level? In any case, we should still have a way to explicitly turn off FMAs.</span></p><p style="font-size:12pt;color:rgb(32,31,30);font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"><br></span></p><p style="font-size:12pt;color:rgb(32,31,30);font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">Thanks,</span></p><p style="font-size:12pt;color:rgb(32,31,30);font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"><br></span></p><p style="font-size:12pt;color:rgb(32,31,30);font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black">Scott</span></p></div><div style="margin:0px;padding:0px;border:0px;font-variant-numeric:inherit;font-variant-east-asian:inherit;font-stretch:inherit;font-size:15px;line-height:inherit;vertical-align:baseline;color:rgb(32,31,30)"><p style="font-size:12pt;font-family:"Times New Roman",serif;margin:0px"><span style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;font-size:inherit;line-height:inherit;font-family:Calibri,sans-serif;vertical-align:baseline;color:black"> </span></p></div></div>