Rollup merge of #124874 - jedbrown:float-mul-add-fast, r=saethlin
intrinsics fmuladdf{32,64}: expose llvm.fmuladd.* semantics
Add intrinsics `fmuladd{f32,f64}`. This computes `(a * b) + c`, to be fused if the code generator determines that (i) the target instruction set has support for a fused operation, and (ii) that the fused operation is more efficient than the equivalent, separate pair of `mul` and `add` instructions.
https://llvm.org/docs/LangRef.html#llvm-fmuladd-intrinsic
The codegen_cranelift uses the `fma` function from libc, which is a correct implementation, but without the desired performance semantic. I think this requires an update to cranelift to expose a suitable instruction in its IR.
I have not tested with codegen_gcc, but it should behave the same way (using `fma` from libc).
---
This topic has been discussed a few times on Zulip and was suggested, for example, by `@workingjubilee` in [Effect of fma disabled](274179331
).
This commit is contained in:
commit
3f9aa50b70
11 changed files with 222 additions and 1 deletions
|
@ -884,6 +884,11 @@ impl<'ll> CodegenCx<'ll, '_> {
|
|||
ifn!("llvm.fma.f64", fn(t_f64, t_f64, t_f64) -> t_f64);
|
||||
ifn!("llvm.fma.f128", fn(t_f128, t_f128, t_f128) -> t_f128);
|
||||
|
||||
ifn!("llvm.fmuladd.f16", fn(t_f16, t_f16, t_f16) -> t_f16);
|
||||
ifn!("llvm.fmuladd.f32", fn(t_f32, t_f32, t_f32) -> t_f32);
|
||||
ifn!("llvm.fmuladd.f64", fn(t_f64, t_f64, t_f64) -> t_f64);
|
||||
ifn!("llvm.fmuladd.f128", fn(t_f128, t_f128, t_f128) -> t_f128);
|
||||
|
||||
ifn!("llvm.fabs.f16", fn(t_f16) -> t_f16);
|
||||
ifn!("llvm.fabs.f32", fn(t_f32) -> t_f32);
|
||||
ifn!("llvm.fabs.f64", fn(t_f64) -> t_f64);
|
||||
|
|
|
@ -86,6 +86,11 @@ fn get_simple_intrinsic<'ll>(
|
|||
sym::fmaf64 => "llvm.fma.f64",
|
||||
sym::fmaf128 => "llvm.fma.f128",
|
||||
|
||||
sym::fmuladdf16 => "llvm.fmuladd.f16",
|
||||
sym::fmuladdf32 => "llvm.fmuladd.f32",
|
||||
sym::fmuladdf64 => "llvm.fmuladd.f64",
|
||||
sym::fmuladdf128 => "llvm.fmuladd.f128",
|
||||
|
||||
sym::fabsf16 => "llvm.fabs.f16",
|
||||
sym::fabsf32 => "llvm.fabs.f32",
|
||||
sym::fabsf64 => "llvm.fabs.f64",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue