diff --git a/cranelift/codegen/meta-python/base/legalize.py b/cranelift/codegen/meta-python/base/legalize.py index 96cb355461..3e287a7b4e 100644 --- a/cranelift/codegen/meta-python/base/legalize.py +++ b/cranelift/codegen/meta-python/base/legalize.py @@ -261,23 +261,6 @@ for binop in [iadd_imm, imul_imm, udiv_imm, urem_imm]: for binop in [sdiv_imm, srem_imm]: widen_imm(True, binop) -# Use expand instead of widen, because widen only gets applied for i8 and i16 -# base type vars, but these take f32 and f64 as base type var. -for ty in [types.f32, types.f64]: - for int_ty in [types.i8, types.i16]: - expand.legalize( - a << insts.fcvt_from_uint.bind(ty).bind(int_ty)(b), - Rtl( - x << uextend.i32(b), - a << insts.fcvt_from_uint.bind(ty).i32(x), - )) - expand.legalize( - a << insts.fcvt_from_sint.bind(ty).bind(int_ty)(b), - Rtl( - x << sextend.i32(b), - a << insts.fcvt_from_sint.bind(ty).i32(x), - )) - widen_imm(False, irsub_imm) # bit ops @@ -492,6 +475,26 @@ expand.legalize( b << bor(b1, b2) )) +# Expansions for fcvt_from_{u,s}int for smaller integer types. +# These use expand and not widen because the controlling type variable for +# these instructions are f32/f64, which are legalized as part of the expand +# group. +for dest_ty in [types.f32, types.f64]: + for src_ty in [types.i8, types.i16]: + expand.legalize( + a << insts.fcvt_from_uint.bind(dest_ty).bind(src_ty)(b), + Rtl( + x << uextend.i32(b), + a << insts.fcvt_from_uint.bind(dest_ty).i32(x), + )) + + expand.legalize( + a << insts.fcvt_from_sint.bind(dest_ty).bind(src_ty)(b), + Rtl( + x << sextend.i32(b), + a << insts.fcvt_from_sint.bind(dest_ty).i32(x), + )) + # Expansions for immediate operands that are out of range. for inst_imm, inst in [ (iadd_imm, iadd), diff --git a/cranelift/codegen/meta/src/cdsl/inst.rs b/cranelift/codegen/meta/src/cdsl/inst.rs index d219419c7e..3cd722c260 100644 --- a/cranelift/codegen/meta/src/cdsl/inst.rs +++ b/cranelift/codegen/meta/src/cdsl/inst.rs @@ -373,7 +373,7 @@ fn verify_polymorphic( let tv = operands_in[op_num].type_var().unwrap(); let free_typevar = tv.free_typevar(); if (free_typevar.is_some() && tv == &free_typevar.unwrap()) - || !tv.singleton_type().is_none() + || tv.singleton_type().is_some() { match verify_ctrl_typevar(tv, &value_opnums, &operands_in, &operands_out) { Ok(typevars) => { diff --git a/cranelift/codegen/meta/src/shared/legalize.rs b/cranelift/codegen/meta/src/shared/legalize.rs index 172d6fd981..93819fc430 100644 --- a/cranelift/codegen/meta/src/shared/legalize.rs +++ b/cranelift/codegen/meta/src/shared/legalize.rs @@ -62,6 +62,8 @@ pub fn define(insts: &InstructionGroup, immediates: &OperandKinds) -> TransformG let f32const = insts.by_name("f32const"); let f64const = insts.by_name("f64const"); let fcopysign = insts.by_name("fcopysign"); + let fcvt_from_sint = insts.by_name("fcvt_from_sint"); + let fcvt_from_uint = insts.by_name("fcvt_from_uint"); let fneg = insts.by_name("fneg"); let iadd = insts.by_name("iadd"); let iadd_carry = insts.by_name("iadd_carry"); @@ -512,6 +514,32 @@ pub fn define(insts: &InstructionGroup, immediates: &OperandKinds) -> TransformG ], ); + // Expansions for fcvt_from_{u,s}int for smaller integer types. + // These use expand and not widen because the controlling type variable for + // these instructions are f32/f64, which are legalized as part of the expand + // group. + for &dest_ty in &[F32, F64] { + for &src_ty in &[I8, I16] { + let bound_inst = bind(bind(fcvt_from_uint, dest_ty), src_ty); + expand.legalize( + def!(a = bound_inst(b)), + vec![ + def!(x = uextend.I32(b)), + def!(a = fcvt_from_uint.dest_ty(x)), + ], + ); + + let bound_inst = bind(bind(fcvt_from_sint, dest_ty), src_ty); + expand.legalize( + def!(a = bound_inst(b)), + vec![ + def!(x = sextend.I32(b)), + def!(a = fcvt_from_sint.dest_ty(x)), + ], + ); + } + } + // Expansions for immediate operands that are out of range. for &(inst_imm, inst) in &[ (iadd_imm, iadd),