For example, LLVM provides two related intrinsics. The first one is llvm.fma which guarantees a fused multiply-add operation with a single rounding step, but it may be significantly slower on targets without a hardware FMA instruction. The second one is llvm.fmuladd which is relaxed version, which allows llvm to choose the most efficient lowering. It may be lowered either to a hardware FMA or to a regular a * b + c sequence with separate multiply and add operations, so it does not guarantee single-rounding semantics.
|
llvm.fma |
llvm.fmuladd |
| Strictness |
Mandatory. |
Optional / Permission to fuse. |
| Fallback |
Lowers to a slow software call, e.g. libm's fmaf. |
Decays back into separate fmul and fadd instructions. |
| Rounding Steps |
Exactly one rounding step. |
One if fused, two if split into separate operations. |
| Precision |
Higher/consistent across hardware. |
Platform-dependent floating-point behavior. |
For example Julia lang has two versions:
So, you need to decide what the semantics of the fallback are? What is more important rounding precision or performance? Or both? If its's both (perf & rounding) than spec should define two fused mul+add operations like Julia & LLVM does
For example, LLVM provides two related intrinsics. The first one is
llvm.fmawhich guarantees a fused multiply-add operation with a single rounding step, but it may be significantly slower on targets without a hardware FMA instruction. The second one isllvm.fmuladdwhich is relaxed version, which allows llvm to choose the most efficient lowering. It may be lowered either to a hardware FMA or to a regular a * b + c sequence with separate multiply and add operations, so it does not guarantee single-rounding semantics.llvm.fmallvm.fmuladdlibm'sfmaf.fmulandfaddinstructions.For example Julia lang has two versions:
So, you need to decide what the semantics of the fallback are? What is more important rounding precision or performance? Or both? If its's both (perf & rounding) than spec should define two fused mul+add operations like Julia & LLVM does