Use native scalar fma
instruction (#1267)
Cranelift 0.87 now supports lowering `fma` as a libcall on x86 [0].
With 0.88 enabling the native x86 instruction under the `has_fma` flag.
aarch64 and s390x already support this as a native instruction, so it's
nice that we emit it for those.
We can't lower the SIMD version using the `fma` instruction since the
lowering can fail if the x86 `has_fma` flag is not enabled. Cranelift
doesn't yet know how to fallback for these cases
[0]: 709716bb8e
This commit is contained in:
parent
156bda8bc7
commit
48c45c481c
@ -303,6 +303,12 @@ fn codegen_float_intrinsic_call<'tcx>(
|
||||
|
||||
let layout = fx.layout_of(ty);
|
||||
let res = match intrinsic {
|
||||
sym::fmaf32 | sym::fmaf64 => {
|
||||
let a = args[0].load_scalar(fx);
|
||||
let b = args[1].load_scalar(fx);
|
||||
let c = args[2].load_scalar(fx);
|
||||
CValue::by_val(fx.bcx.ins().fma(a, b, c), layout)
|
||||
}
|
||||
sym::copysignf32 | sym::copysignf64 => {
|
||||
let a = args[0].load_scalar(fx);
|
||||
let b = args[1].load_scalar(fx);
|
||||
|
@ -397,21 +397,15 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
|
||||
let layout = a.layout();
|
||||
let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
|
||||
let res_lane_layout = fx.layout_of(lane_ty);
|
||||
|
||||
for lane in 0..lane_count {
|
||||
let a_lane = a.value_lane(fx, lane);
|
||||
let b_lane = b.value_lane(fx, lane);
|
||||
let c_lane = c.value_lane(fx, lane);
|
||||
let a_lane = a.value_lane(fx, lane).load_scalar(fx);
|
||||
let b_lane = b.value_lane(fx, lane).load_scalar(fx);
|
||||
let c_lane = c.value_lane(fx, lane).load_scalar(fx);
|
||||
|
||||
let res_lane = match lane_ty.kind() {
|
||||
ty::Float(FloatTy::F32) => {
|
||||
fx.easy_call("fmaf", &[a_lane, b_lane, c_lane], lane_ty)
|
||||
}
|
||||
ty::Float(FloatTy::F64) => {
|
||||
fx.easy_call("fma", &[a_lane, b_lane, c_lane], lane_ty)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let res_lane = fx.bcx.ins().fma(a_lane, b_lane, c_lane);
|
||||
let res_lane = CValue::by_val(res_lane, res_lane_layout);
|
||||
|
||||
ret.place_lane(fx, lane).write_cvalue(fx, res_lane);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user