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>
Possibly Parallel 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