Skip to content

Commit ff5d860

Browse files
committed
Introduce helper functions for f16<->f32 casts when necessary
1 parent c08e62a commit ff5d860

4 files changed

Lines changed: 120 additions & 184 deletions

File tree

src/codegen_f16_f128.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,40 @@ fn f64_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value {
5151
if ret_ty == types::I16 { fx.bcx.ins().bitcast(types::F16, MemFlags::new(), ret) } else { ret }
5252
}
5353

54+
// FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have
55+
// been added to Cranelift.
56+
pub(crate) fn maybe_with_f16_to_f32(
57+
fx: &mut FunctionCx<'_, '_, '_>,
58+
val: Value,
59+
f: impl FnOnce(&mut FunctionCx<'_, '_, '_>, Value) -> Value,
60+
) -> Value {
61+
if fx.bcx.func.dfg.value_type(val) == types::F16 {
62+
let val = f16_to_f32(fx, val);
63+
let res = f(fx, val);
64+
f32_to_f16(fx, res)
65+
} else {
66+
f(fx, val)
67+
}
68+
}
69+
70+
// FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have
71+
// been added to Cranelift.
72+
pub(crate) fn maybe_with_f16_to_f32_pair(
73+
fx: &mut FunctionCx<'_, '_, '_>,
74+
a: Value,
75+
b: Value,
76+
f: impl FnOnce(&mut FunctionCx<'_, '_, '_>, Value, Value) -> Value,
77+
) -> Value {
78+
if fx.bcx.func.dfg.value_type(a) == types::F16 {
79+
let a = f16_to_f32(fx, a);
80+
let b = f16_to_f32(fx, b);
81+
let res = f(fx, a, b);
82+
f32_to_f16(fx, res)
83+
} else {
84+
f(fx, a, b)
85+
}
86+
}
87+
5488
pub(crate) fn fcmp(fx: &mut FunctionCx<'_, '_, '_>, cc: FloatCC, lhs: Value, rhs: Value) -> Value {
5589
let ty = fx.bcx.func.dfg.value_type(lhs);
5690
match ty {

src/intrinsics/mod.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,12 +1197,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
11971197
let a = a.load_scalar(fx);
11981198
let b = b.load_scalar(fx);
11991199

1200-
// FIXME(bytecodealliance/wasmtime#8312): Use `fmin` directly once
1201-
// Cranelift backend lowerings are implemented.
1202-
let a = codegen_f16_f128::f16_to_f32(fx, a);
1203-
let b = codegen_f16_f128::f16_to_f32(fx, b);
1204-
let val = fx.bcx.ins().fmin(a, b);
1205-
let val = codegen_f16_f128::f32_to_f16(fx, val);
1200+
let val = codegen_f16_f128::maybe_with_f16_to_f32_pair(fx, a, b, |fx, a, b| {
1201+
fx.bcx.ins().fmin(a, b)
1202+
});
12061203
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f16));
12071204
ret.write_cvalue(fx, val);
12081205
}
@@ -1240,12 +1237,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
12401237
let a = a.load_scalar(fx);
12411238
let b = b.load_scalar(fx);
12421239

1243-
// FIXME(bytecodealliance/wasmtime#8312): Use `fmax` directly once
1244-
// Cranelift backend lowerings are implemented.
1245-
let a = codegen_f16_f128::f16_to_f32(fx, a);
1246-
let b = codegen_f16_f128::f16_to_f32(fx, b);
1247-
let val = fx.bcx.ins().fmax(a, b);
1248-
let val = codegen_f16_f128::f32_to_f16(fx, val);
1240+
let val = codegen_f16_f128::maybe_with_f16_to_f32_pair(fx, a, b, |fx, a, b| {
1241+
fx.bcx.ins().fmax(a, b)
1242+
});
12491243
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f16));
12501244
ret.write_cvalue(fx, val);
12511245
}

src/intrinsics/simd.rs

Lines changed: 74 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -422,80 +422,65 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
422422

423423
// FIXME use vector instructions when possible
424424
simd_pair_for_each_lane(fx, x, y, ret, &|fx, lane_ty, _ret_lane_ty, x_lane, y_lane| {
425-
// FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have
426-
// been added to Cranelift.
427-
let (x_lane, y_lane) = if *lane_ty.kind() == ty::Float(FloatTy::F16) {
428-
(
429-
codegen_f16_f128::f16_to_f32(fx, x_lane),
430-
codegen_f16_f128::f16_to_f32(fx, y_lane),
431-
)
432-
} else {
433-
(x_lane, y_lane)
434-
};
435-
436-
let res = match (lane_ty.kind(), intrinsic) {
437-
(ty::Uint(_), sym::simd_add) => fx.bcx.ins().iadd(x_lane, y_lane),
438-
(ty::Uint(_), sym::simd_sub) => fx.bcx.ins().isub(x_lane, y_lane),
439-
(ty::Uint(_), sym::simd_mul) => fx.bcx.ins().imul(x_lane, y_lane),
440-
(ty::Uint(_), sym::simd_div) => fx.bcx.ins().udiv(x_lane, y_lane),
441-
(ty::Uint(_), sym::simd_rem) => fx.bcx.ins().urem(x_lane, y_lane),
442-
443-
(ty::Int(_), sym::simd_add) => fx.bcx.ins().iadd(x_lane, y_lane),
444-
(ty::Int(_), sym::simd_sub) => fx.bcx.ins().isub(x_lane, y_lane),
445-
(ty::Int(_), sym::simd_mul) => fx.bcx.ins().imul(x_lane, y_lane),
446-
(ty::Int(_), sym::simd_div) => fx.bcx.ins().sdiv(x_lane, y_lane),
447-
(ty::Int(_), sym::simd_rem) => fx.bcx.ins().srem(x_lane, y_lane),
448-
449-
(ty::Float(_), sym::simd_add) => fx.bcx.ins().fadd(x_lane, y_lane),
450-
(ty::Float(_), sym::simd_sub) => fx.bcx.ins().fsub(x_lane, y_lane),
451-
(ty::Float(_), sym::simd_mul) => fx.bcx.ins().fmul(x_lane, y_lane),
452-
(ty::Float(_), sym::simd_div) => fx.bcx.ins().fdiv(x_lane, y_lane),
453-
(ty::Float(FloatTy::F16), sym::simd_rem) => fx.lib_call(
454-
"fmodf",
455-
vec![AbiParam::new(types::F32), AbiParam::new(types::F32)],
456-
vec![AbiParam::new(types::F32)],
457-
// FIXME(bytecodealliance/wasmtime#8312): Already converted
458-
// by the FIXME above.
459-
// fx.bcx.ins().fpromote(types::F32, lhs),
460-
// fx.bcx.ins().fpromote(types::F32, rhs),
461-
&[x_lane, y_lane],
462-
)[0],
463-
(ty::Float(FloatTy::F32), sym::simd_rem) => fx.lib_call(
464-
"fmodf",
465-
vec![AbiParam::new(types::F32), AbiParam::new(types::F32)],
466-
vec![AbiParam::new(types::F32)],
467-
&[x_lane, y_lane],
468-
)[0],
469-
(ty::Float(FloatTy::F64), sym::simd_rem) => fx.lib_call(
470-
"fmod",
471-
vec![AbiParam::new(types::F64), AbiParam::new(types::F64)],
472-
vec![AbiParam::new(types::F64)],
473-
&[x_lane, y_lane],
474-
)[0],
475-
476-
(ty::Uint(_), sym::simd_shl) => fx.bcx.ins().ishl(x_lane, y_lane),
477-
(ty::Uint(_), sym::simd_shr) => fx.bcx.ins().ushr(x_lane, y_lane),
478-
(ty::Uint(_), sym::simd_and) => fx.bcx.ins().band(x_lane, y_lane),
479-
(ty::Uint(_), sym::simd_or) => fx.bcx.ins().bor(x_lane, y_lane),
480-
(ty::Uint(_), sym::simd_xor) => fx.bcx.ins().bxor(x_lane, y_lane),
481-
482-
(ty::Int(_), sym::simd_shl) => fx.bcx.ins().ishl(x_lane, y_lane),
483-
(ty::Int(_), sym::simd_shr) => fx.bcx.ins().sshr(x_lane, y_lane),
484-
(ty::Int(_), sym::simd_and) => fx.bcx.ins().band(x_lane, y_lane),
485-
(ty::Int(_), sym::simd_or) => fx.bcx.ins().bor(x_lane, y_lane),
486-
(ty::Int(_), sym::simd_xor) => fx.bcx.ins().bxor(x_lane, y_lane),
487-
488-
_ => unreachable!(),
489-
};
490-
491-
if *lane_ty.kind() == ty::Float(FloatTy::F16) {
492-
// FIXME(bytecodealliance/wasmtime#8312): Use native Cranelift
493-
// operation once Cranelift backend lowerings have been
494-
// implemented.
495-
codegen_f16_f128::f32_to_f16(fx, res)
496-
} else {
497-
res
498-
}
425+
codegen_f16_f128::maybe_with_f16_to_f32_pair(
426+
fx,
427+
x_lane,
428+
y_lane,
429+
|fx, x_lane, y_lane| match (lane_ty.kind(), intrinsic) {
430+
(ty::Uint(_), sym::simd_add) => fx.bcx.ins().iadd(x_lane, y_lane),
431+
(ty::Uint(_), sym::simd_sub) => fx.bcx.ins().isub(x_lane, y_lane),
432+
(ty::Uint(_), sym::simd_mul) => fx.bcx.ins().imul(x_lane, y_lane),
433+
(ty::Uint(_), sym::simd_div) => fx.bcx.ins().udiv(x_lane, y_lane),
434+
(ty::Uint(_), sym::simd_rem) => fx.bcx.ins().urem(x_lane, y_lane),
435+
436+
(ty::Int(_), sym::simd_add) => fx.bcx.ins().iadd(x_lane, y_lane),
437+
(ty::Int(_), sym::simd_sub) => fx.bcx.ins().isub(x_lane, y_lane),
438+
(ty::Int(_), sym::simd_mul) => fx.bcx.ins().imul(x_lane, y_lane),
439+
(ty::Int(_), sym::simd_div) => fx.bcx.ins().sdiv(x_lane, y_lane),
440+
(ty::Int(_), sym::simd_rem) => fx.bcx.ins().srem(x_lane, y_lane),
441+
442+
(ty::Float(_), sym::simd_add) => fx.bcx.ins().fadd(x_lane, y_lane),
443+
(ty::Float(_), sym::simd_sub) => fx.bcx.ins().fsub(x_lane, y_lane),
444+
(ty::Float(_), sym::simd_mul) => fx.bcx.ins().fmul(x_lane, y_lane),
445+
(ty::Float(_), sym::simd_div) => fx.bcx.ins().fdiv(x_lane, y_lane),
446+
(ty::Float(FloatTy::F16), sym::simd_rem) => fx.lib_call(
447+
"fmodf",
448+
vec![AbiParam::new(types::F32), AbiParam::new(types::F32)],
449+
vec![AbiParam::new(types::F32)],
450+
// FIXME(bytecodealliance/wasmtime#8312): Already converted
451+
// by the FIXME above.
452+
// fx.bcx.ins().fpromote(types::F32, lhs),
453+
// fx.bcx.ins().fpromote(types::F32, rhs),
454+
&[x_lane, y_lane],
455+
)[0],
456+
(ty::Float(FloatTy::F32), sym::simd_rem) => fx.lib_call(
457+
"fmodf",
458+
vec![AbiParam::new(types::F32), AbiParam::new(types::F32)],
459+
vec![AbiParam::new(types::F32)],
460+
&[x_lane, y_lane],
461+
)[0],
462+
(ty::Float(FloatTy::F64), sym::simd_rem) => fx.lib_call(
463+
"fmod",
464+
vec![AbiParam::new(types::F64), AbiParam::new(types::F64)],
465+
vec![AbiParam::new(types::F64)],
466+
&[x_lane, y_lane],
467+
)[0],
468+
469+
(ty::Uint(_), sym::simd_shl) => fx.bcx.ins().ishl(x_lane, y_lane),
470+
(ty::Uint(_), sym::simd_shr) => fx.bcx.ins().ushr(x_lane, y_lane),
471+
(ty::Uint(_), sym::simd_and) => fx.bcx.ins().band(x_lane, y_lane),
472+
(ty::Uint(_), sym::simd_or) => fx.bcx.ins().bor(x_lane, y_lane),
473+
(ty::Uint(_), sym::simd_xor) => fx.bcx.ins().bxor(x_lane, y_lane),
474+
475+
(ty::Int(_), sym::simd_shl) => fx.bcx.ins().ishl(x_lane, y_lane),
476+
(ty::Int(_), sym::simd_shr) => fx.bcx.ins().sshr(x_lane, y_lane),
477+
(ty::Int(_), sym::simd_and) => fx.bcx.ins().band(x_lane, y_lane),
478+
(ty::Int(_), sym::simd_or) => fx.bcx.ins().bor(x_lane, y_lane),
479+
(ty::Int(_), sym::simd_xor) => fx.bcx.ins().bxor(x_lane, y_lane),
480+
481+
_ => unreachable!(),
482+
},
483+
)
499484
});
500485
}
501486

@@ -622,29 +607,15 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
622607
ty::Float(_) => {}
623608
_ => unreachable!("{:?}", lane_ty),
624609
}
625-
// FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have
626-
// been added to Cranelift.
627-
let lane = if *lane_ty.kind() == ty::Float(FloatTy::F16) {
628-
codegen_f16_f128::f16_to_f32(fx, lane)
629-
} else {
630-
lane
631-
};
632-
let res = match intrinsic {
610+
611+
codegen_f16_f128::maybe_with_f16_to_f32(fx, lane, |fx, lane| match intrinsic {
633612
sym::simd_fabs => fx.bcx.ins().fabs(lane),
634613
sym::simd_fsqrt => fx.bcx.ins().sqrt(lane),
635614
sym::simd_ceil => fx.bcx.ins().ceil(lane),
636615
sym::simd_floor => fx.bcx.ins().floor(lane),
637616
sym::simd_trunc => fx.bcx.ins().trunc(lane),
638617
_ => unreachable!(),
639-
};
640-
if *lane_ty.kind() == ty::Float(FloatTy::F16) {
641-
// FIXME(bytecodealliance/wasmtime#8312): Use native Cranelift
642-
// operation once Cranelift backend lowerings have been
643-
// implemented.
644-
codegen_f16_f128::f32_to_f16(fx, res)
645-
} else {
646-
res
647-
}
618+
})
648619
});
649620
}
650621

@@ -660,22 +631,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
660631

661632
simd_reduce(fx, v, Some(acc), ret, &|fx, lane_ty, a, b| {
662633
if lane_ty.is_floating_point() {
663-
// FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have
664-
// been added to Cranelift.
665-
let (a, b) = if *lane_ty.kind() == ty::Float(FloatTy::F16) {
666-
(codegen_f16_f128::f16_to_f32(fx, a), codegen_f16_f128::f16_to_f32(fx, b))
667-
} else {
668-
(a, b)
669-
};
670-
let res = fx.bcx.ins().fadd(a, b);
671-
if *lane_ty.kind() == ty::Float(FloatTy::F16) {
672-
// FIXME(bytecodealliance/wasmtime#8312): Use native Cranelift
673-
// operation once Cranelift backend lowerings have been
674-
// implemented.
675-
codegen_f16_f128::f32_to_f16(fx, res)
676-
} else {
677-
res
678-
}
634+
codegen_f16_f128::maybe_with_f16_to_f32_pair(fx, a, b, |fx, a, b| {
635+
fx.bcx.ins().fadd(a, b)
636+
})
679637
} else {
680638
fx.bcx.ins().iadd(a, b)
681639
}
@@ -693,22 +651,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
693651

694652
simd_reduce(fx, v, None, ret, &|fx, lane_ty, a, b| {
695653
if lane_ty.is_floating_point() {
696-
// FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have
697-
// been added to Cranelift.
698-
let (a, b) = if *lane_ty.kind() == ty::Float(FloatTy::F16) {
699-
(codegen_f16_f128::f16_to_f32(fx, a), codegen_f16_f128::f16_to_f32(fx, b))
700-
} else {
701-
(a, b)
702-
};
703-
let res = fx.bcx.ins().fadd(a, b);
704-
if *lane_ty.kind() == ty::Float(FloatTy::F16) {
705-
// FIXME(bytecodealliance/wasmtime#8312): Use native Cranelift
706-
// operation once Cranelift backend lowerings have been
707-
// implemented.
708-
codegen_f16_f128::f32_to_f16(fx, res)
709-
} else {
710-
res
711-
}
654+
codegen_f16_f128::maybe_with_f16_to_f32_pair(fx, a, b, |fx, a, b| {
655+
fx.bcx.ins().fadd(a, b)
656+
})
712657
} else {
713658
fx.bcx.ins().iadd(a, b)
714659
}
@@ -727,22 +672,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
727672

728673
simd_reduce(fx, v, Some(acc), ret, &|fx, lane_ty, a, b| {
729674
if lane_ty.is_floating_point() {
730-
// FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have
731-
// been added to Cranelift.
732-
let (a, b) = if *lane_ty.kind() == ty::Float(FloatTy::F16) {
733-
(codegen_f16_f128::f16_to_f32(fx, a), codegen_f16_f128::f16_to_f32(fx, b))
734-
} else {
735-
(a, b)
736-
};
737-
let res = fx.bcx.ins().fmul(a, b);
738-
if *lane_ty.kind() == ty::Float(FloatTy::F16) {
739-
// FIXME(bytecodealliance/wasmtime#8312): Use native Cranelift
740-
// operation once Cranelift backend lowerings have been
741-
// implemented.
742-
codegen_f16_f128::f32_to_f16(fx, res)
743-
} else {
744-
res
745-
}
675+
codegen_f16_f128::maybe_with_f16_to_f32_pair(fx, a, b, |fx, a, b| {
676+
fx.bcx.ins().fmul(a, b)
677+
})
746678
} else {
747679
fx.bcx.ins().imul(a, b)
748680
}
@@ -760,22 +692,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
760692

761693
simd_reduce(fx, v, None, ret, &|fx, lane_ty, a, b| {
762694
if lane_ty.is_floating_point() {
763-
// FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have
764-
// been added to Cranelift.
765-
let (a, b) = if *lane_ty.kind() == ty::Float(FloatTy::F16) {
766-
(codegen_f16_f128::f16_to_f32(fx, a), codegen_f16_f128::f16_to_f32(fx, b))
767-
} else {
768-
(a, b)
769-
};
770-
let res = fx.bcx.ins().fmul(a, b);
771-
if *lane_ty.kind() == ty::Float(FloatTy::F16) {
772-
// FIXME(bytecodealliance/wasmtime#8312): Use native Cranelift
773-
// operation once Cranelift backend lowerings have been
774-
// implemented.
775-
codegen_f16_f128::f32_to_f16(fx, res)
776-
} else {
777-
res
778-
}
695+
codegen_f16_f128::maybe_with_f16_to_f32_pair(fx, a, b, |fx, a, b| {
696+
fx.bcx.ins().fmul(a, b)
697+
})
779698
} else {
780699
fx.bcx.ins().imul(a, b)
781700
}

src/num.rs

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,6 @@ pub(crate) fn codegen_float_binop<'tcx>(
358358
} else {
359359
(lhs, rhs)
360360
};
361-
let b = fx.bcx.ins();
362361
let res = match bin_op {
363362
// FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings
364363
// have been added to Cranelift.
@@ -367,10 +366,10 @@ pub(crate) fn codegen_float_binop<'tcx>(
367366
{
368367
codegen_f16_f128::codegen_f128_binop(fx, bin_op, lhs, rhs)
369368
}
370-
BinOp::Add => b.fadd(lhs, rhs),
371-
BinOp::Sub => b.fsub(lhs, rhs),
372-
BinOp::Mul => b.fmul(lhs, rhs),
373-
BinOp::Div => b.fdiv(lhs, rhs),
369+
BinOp::Add => fx.bcx.ins().fadd(lhs, rhs),
370+
BinOp::Sub => fx.bcx.ins().fsub(lhs, rhs),
371+
BinOp::Mul => fx.bcx.ins().fmul(lhs, rhs),
372+
BinOp::Div => fx.bcx.ins().fdiv(lhs, rhs),
374373
BinOp::Rem => {
375374
let (name, ty, lhs, rhs) = match in_lhs.layout().ty.kind() {
376375
ty::Float(FloatTy::F16) => (
@@ -389,22 +388,12 @@ pub(crate) fn codegen_float_binop<'tcx>(
389388
_ => bug!(),
390389
};
391390

392-
let ret_val = fx.lib_call(
391+
fx.lib_call(
393392
name,
394393
vec![AbiParam::new(ty), AbiParam::new(ty)],
395394
vec![AbiParam::new(ty)],
396395
&[lhs, rhs],
397-
)[0];
398-
399-
let ret_val = if *in_lhs.layout().ty.kind() == ty::Float(FloatTy::F16) {
400-
// FIXME(bytecodealliance/wasmtime#8312): Use native Cranelift
401-
// operation once Cranelift backend lowerings have been
402-
// implemented.
403-
codegen_f16_f128::f32_to_f16(fx, ret_val)
404-
} else {
405-
ret_val
406-
};
407-
return CValue::by_val(ret_val, in_lhs.layout());
396+
)[0]
408397
}
409398
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
410399
let fltcc = match bin_op {

0 commit comments

Comments
 (0)