Repository navigation
Support f16 and f128Β #1461
Description
Activity
This will need direct Cranelift support. Back ib the day before Cranelift had native 128bit int support I had a whole bunch of hacks to make it work. They were really fragile and I don't think they will work anymore for the current structure of cg_clif.
What all would be needed for clif to support these in a minimal state?
At a minimum Cranelift support for the f16 and f128 values. And either Cranelift support for float instructions for these types or emulation in cg_clif using libm calls in
andrustc_codegen_cranelift/src/num.rs
Lines 313 to 363 in 8c46d93
pub(crate) fn codegen_float_binop<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, ) -> CValue<'tcx> { assert_eq!(in_lhs.layout().ty, in_rhs.layout().ty); let lhs = in_lhs.load_scalar(fx); let rhs = in_rhs.load_scalar(fx); let b = fx.bcx.ins(); let res = match bin_op { BinOp::Add => b.fadd(lhs, rhs), BinOp::Sub => b.fsub(lhs, rhs), BinOp::Mul => b.fmul(lhs, rhs), BinOp::Div => b.fdiv(lhs, rhs), BinOp::Rem => { let (name, ty) = match in_lhs.layout().ty.kind() { ty::Float(FloatTy::F32) => ("fmodf", types::F32), ty::Float(FloatTy::F64) => ("fmod", types::F64), _ => bug!(), }; let ret_val = fx.lib_call( name, vec![AbiParam::new(ty), AbiParam::new(ty)], vec![AbiParam::new(ty)], &[lhs, rhs], )[0]; return CValue::by_val(ret_val, in_lhs.layout()); } BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => { let fltcc = match bin_op { BinOp::Eq => FloatCC::Equal, BinOp::Lt => FloatCC::LessThan, BinOp::Le => FloatCC::LessThanOrEqual, BinOp::Ne => FloatCC::NotEqual, BinOp::Ge => FloatCC::GreaterThanOrEqual, BinOp::Gt => FloatCC::GreaterThan, _ => unreachable!(), }; let val = fx.bcx.ins().fcmp(fltcc, lhs, rhs); return CValue::by_val(val, fx.layout_of(fx.tcx.types.bool)); } _ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs, in_rhs), }; CValue::by_val(res, in_lhs.layout()) } .rustc_codegen_cranelift/src/intrinsics/mod.rs
Lines 309 to 349 in 8c46d93
let (name, arg_count, ty, clif_ty) = match intrinsic { sym::expf32 => ("expf", 1, fx.tcx.types.f32, types::F32), sym::expf64 => ("exp", 1, fx.tcx.types.f64, types::F64), sym::exp2f32 => ("exp2f", 1, fx.tcx.types.f32, types::F32), sym::exp2f64 => ("exp2", 1, fx.tcx.types.f64, types::F64), sym::sqrtf32 => ("sqrtf", 1, fx.tcx.types.f32, types::F32), sym::sqrtf64 => ("sqrt", 1, fx.tcx.types.f64, types::F64), sym::powif32 => ("__powisf2", 2, fx.tcx.types.f32, types::F32), // compiler-builtins sym::powif64 => ("__powidf2", 2, fx.tcx.types.f64, types::F64), // compiler-builtins sym::powf32 => ("powf", 2, fx.tcx.types.f32, types::F32), sym::powf64 => ("pow", 2, fx.tcx.types.f64, types::F64), sym::logf32 => ("logf", 1, fx.tcx.types.f32, types::F32), sym::logf64 => ("log", 1, fx.tcx.types.f64, types::F64), sym::log2f32 => ("log2f", 1, fx.tcx.types.f32, types::F32), sym::log2f64 => ("log2", 1, fx.tcx.types.f64, types::F64), sym::log10f32 => ("log10f", 1, fx.tcx.types.f32, types::F32), sym::log10f64 => ("log10", 1, fx.tcx.types.f64, types::F64), sym::fabsf32 => ("fabsf", 1, fx.tcx.types.f32, types::F32), sym::fabsf64 => ("fabs", 1, fx.tcx.types.f64, types::F64), sym::fmaf32 => ("fmaf", 3, fx.tcx.types.f32, types::F32), sym::fmaf64 => ("fma", 3, fx.tcx.types.f64, types::F64), sym::copysignf32 => ("copysignf", 2, fx.tcx.types.f32, types::F32), sym::copysignf64 => ("copysign", 2, fx.tcx.types.f64, types::F64), sym::floorf32 => ("floorf", 1, fx.tcx.types.f32, types::F32), sym::floorf64 => ("floor", 1, fx.tcx.types.f64, types::F64), sym::ceilf32 => ("ceilf", 1, fx.tcx.types.f32, types::F32), sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64, types::F64), sym::truncf32 => ("truncf", 1, fx.tcx.types.f32, types::F32), sym::truncf64 => ("trunc", 1, fx.tcx.types.f64, types::F64), sym::rintf32 => ("rintf", 1, fx.tcx.types.f32, types::F32), sym::rintf64 => ("rint", 1, fx.tcx.types.f64, types::F64), sym::roundf32 => ("roundf", 1, fx.tcx.types.f32, types::F32), sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64), sym::roundevenf32 => ("roundevenf", 1, fx.tcx.types.f32, types::F32), sym::roundevenf64 => ("roundeven", 1, fx.tcx.types.f64, types::F64), sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32), sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64), sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32), sym::cosf64 => ("cos", 1, fx.tcx.types.f64, types::F64), _ => return false, }; - addedC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.
on May 12, 2024 It seems like the frontend is now hooked up and this is used in some sysroot crates like
compiler-builtinsso using-Zbuild-stdwith cranelift fails, is there some way to avoid this now?compiler-builtinshas theno-f16-f128feature to disable both of these https://github.com/rust-lang/compiler-builtins/blob/adaef3265c560998a03b6902bd63d88009d3a132/Cargo.toml#L55, and then std carries a flag to propagate that https://github.com/rust-lang/rust/blob/017ae1b21f7be6dcdcfc95631e54bde806653a8a/library/std/Cargo.toml#L103. Maybe there is a way to automatically set this flag based on codegen backend in build-std?Ah yes, I'd found the
compiler-builtinsfeature but missed thestdone, this works now:export CARGO_UNSTABLE_BUILD_STD_FEATURES=compiler-builtins-no-f16-f128 export CARGO_UNSTABLE_BUILD_STD=std,panic_abortReacted by Finchie
As of rust-lang/rust#121728, the backends now have stubs for
f16andf128: https://github.com/rust-lang/rust/blob/6cbf0926d54c80ea6d15df333be9281f65bbeb36/compiler/rustc_codegen_cranelift/src/common.rs#L36-L39.It will be a while before these codepaths can even be exercised since the frontend isn't hooked up yet, but at some point this should be changed to either gracefully fail or do the right thing.