diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 292c8004ef..380ceb25e0 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -297,6 +297,14 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( target.expect("target for simd intrinsic"), source_info.span, ); + } else if intrinsic.as_str().starts_with("fmuladdf") { + let [x, y, z] = args else { unreachable!() }; + + let x = codegen_operand(fx, &x.node).load_scalar(fx); + let y = codegen_operand(fx, &y.node).load_scalar(fx); + let z = codegen_operand(fx, &z.node).load_scalar(fx); + + fx.bcx.ins().fma(x, y, z); } else if codegen_float_intrinsic_call(fx, intrinsic, args, destination) { let ret_block = fx.get_block(target.expect("target for float intrinsic")); fx.bcx.ins().jump(ret_block, &[]); @@ -367,12 +375,6 @@ fn codegen_float_intrinsic_call<'tcx>( sym::fmaf64 => ("fma", 3, fx.tcx.types.f64, types::F64), sym::fmaf128 => ("fmaf128", 3, fx.tcx.types.f128, types::F128), - // FIXME: calling `fma` from libc without FMA target feature uses expensive sofware emulation - sym::fmuladdf16 => ("fmaf16", 3, fx.tcx.types.f16, types::F16), // FIXME: use cranelift intrinsic analogous to llvm.fmuladd.f16 - sym::fmuladdf32 => ("fmaf", 3, fx.tcx.types.f32, types::F32), // FIXME: use cranelift intrinsic analogous to llvm.fmuladd.f32 - sym::fmuladdf64 => ("fma", 3, fx.tcx.types.f64, types::F64), // FIXME: use cranelift intrinsic analogous to llvm.fmuladd.f64 - sym::fmuladdf128 => ("fmaf128", 3, fx.tcx.types.f128, types::F128), // FIXME: use cranelift intrinsic analogous to llvm.fmuladd.f128 - sym::copysignf16 => ("copysignf16", 2, fx.tcx.types.f16, types::F16), sym::copysignf32 => ("copysignf", 2, fx.tcx.types.f32, types::F32), sym::copysignf64 => ("copysign", 2, fx.tcx.types.f64, types::F64), @@ -403,15 +405,16 @@ fn codegen_float_intrinsic_call<'tcx>( sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64), sym::roundf128 => ("roundf128", 1, fx.tcx.types.f128, types::F128), - sym::sinf16 => ("sinf16", 1, fx.tcx.types.f16, types::F16), + sym::sinf16 => return false, // has a fallback via f32 sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32), sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64), sym::sinf128 => ("sinf128", 1, fx.tcx.types.f128, types::F128), - sym::cosf16 => ("cosf16", 1, fx.tcx.types.f16, types::F16), + sym::cosf16 => return false, // has a fallback via f32 sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32), sym::cosf64 => ("cos", 1, fx.tcx.types.f64, types::F64), sym::cosf128 => ("cosf128", 1, fx.tcx.types.f128, types::F128), + _ => return false, };