Scott Manley via llvm-dev
2019-Jul-10 19:27 UTC
[llvm-dev] RFC: change -fp-contract=off to actually disable FMAs
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: $ clang --help | grep fp-contract -ffp-contract=<value> Form fused FP ops (e.g. FMAs): fast (everywhere) | on (according to FP_CONTRACT pragma, default) | off (never fuse) Current behaviour in LLVM 8.0 below: $ cat fma.ll define double @fmadd(double %a, double %b, double %c) { %mul = fmul fast double %b, %a %add = fadd fast double %mul, %c ret double %add } $ llc -mattr=+fma fma.ll -fp-contract=off -o - | grep vfmadd vfmadd213sd %xmm2, %xmm1, %xmm0 # xmm0 = (xmm1 * xmm0) + xmm2 It still generates an fma due to the logic in DAGCombiner: bool CanFuse = Options.UnsafeFPMath || isContractable(N); bool AllowFusionGlobally = (Options.AllowFPOpFusion == FPOpFusion::Fast || CanFuse || HasFMAD); 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: 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". Which is it supposed to be? At a minimum we should clear up the discrepancy, but there are two general approaches I see: Option 1: - rename Strict to Off in llvm and always diable FMAs with this option - does not require changes to Clang Example logic: bool AllowFusionGlobally = Options.AllowFPOpFusion != FPOpFusion::Off && (Options.AllowFPOpFusion == FPOpFusion::Fast || CanFuse || HasFMAD); Option 2: - keep =strict, add =off to turn off FMAs - add =strict to clang as it does not currently exist - tie uses of ::Strict to the presence of FMAD (which might have been the intention?) Example logic: bool AllowFusionGlobally = Options.AllowFPOpFusion != FPOpFusion::Off && (Options.AllowFPOpFusion == FPOpFusion::Fast || CanFuse || (HasFMAD && Options.AllowFPOpFusion =FPOpFusion::Strict)); 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. Thanks, Scott -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190710/4012c144/attachment.html>
Matt Arsenault via llvm-dev
2019-Jul-10 19:52 UTC
[llvm-dev] RFC: change -fp-contract=off to actually disable FMAs
> On Jul 10, 2019, at 15:27, Scott Manley via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > 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. >FMAD Is not FMA, and should not be part of any discussion related to fusion rules. It is defined to be identical to the separate fmul and fadd -Matt -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190710/144901e4/attachment.html>
Scott Manley via llvm-dev
2019-Jul-10 20:09 UTC
[llvm-dev] RFC: change -fp-contract=off to actually disable FMAs
Numerically identical, sure. But, there are other reasons to disable FMAD fusion -- namely for performance comparisons. On Wed, Jul 10, 2019 at 2:52 PM Matt Arsenault <arsenm2 at gmail.com> wrote:> > > On Jul 10, 2019, at 15:27, Scott Manley via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > > 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. > > > FMAD Is not FMA, and should not be part of any discussion related to > fusion rules. It is defined to be identical to the separate fmul and fadd > > -Matt >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190710/8ad011cb/attachment.html>
Apparently Analagous Threads
- RFC: change -fp-contract=off to actually disable FMAs
- RFC: change -fp-contract=off to actually disable FMAs
- RFC: change -fp-contract=off to actually disable FMAs
- [cfe-dev] RFC: change -fp-contract=off to actually disable FMAs
- [LLVMdev] RFC: Add ISD nodes for mad