Skip to content

Support f16 and f128Β #1461

Description

@tgross35

As of rust-lang/rust#121728, the backends now have stubs for f16 and f128: 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.

Activity

  1. bjorn3 commented on Mar 1, 2024

    @bjorn3
    Member

    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.

  2. tgross35 commented on Mar 5, 2024

    @tgross35
    MemberAuthor

    What all would be needed for clif to support these in a minimal state?

  3. bjorn3 commented on Mar 5, 2024

    @bjorn3
    Member

    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

    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())
    }
    and
    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,
    };
    .

  4. added
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    on May 12, 2024
  5. Nemo157 commented on Oct 25, 2024

    @Nemo157

    It seems like the frontend is now hooked up and this is used in some sysroot crates like compiler-builtins so using -Zbuild-std with cranelift fails, is there some way to avoid this now?

  6. tgross35 commented on Oct 25, 2024

    @tgross35
    MemberAuthor

    compiler-builtins has the no-f16-f128 feature 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?

  7. Nemo157 commented on Oct 25, 2024

    @Nemo157

    Ah yes, I'd found the compiler-builtins feature but missed the std one, this works now:

    export CARGO_UNSTABLE_BUILD_STD_FEATURES=compiler-builtins-no-f16-f128
    export CARGO_UNSTABLE_BUILD_STD=std,panic_abort
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-enhancementCategory: An issue proposing an enhancement or a PR with one.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions