diff --git a/cranelift/codegen/meta/src/shared/legalize.rs b/cranelift/codegen/meta/src/shared/legalize.rs index f9cec3557e..30de84a198 100644 --- a/cranelift/codegen/meta/src/shared/legalize.rs +++ b/cranelift/codegen/meta/src/shared/legalize.rs @@ -64,7 +64,6 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro 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_cin = insts.by_name("iadd_cin"); @@ -542,21 +541,12 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro ], ); - // 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 + // Expansion for fcvt_from_sint for smaller integer types. + // This uses expand and not widen because the controlling type variable for + // this instruction is f32/f64, which is legalized as part of the expand // group. for &dest_ty in &[F32, F64] { for &src_ty in &[I8, I16] { - let bound_inst = fcvt_from_uint.bind(dest_ty).bind(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 = fcvt_from_sint.bind(dest_ty).bind(src_ty); expand.legalize( def!(a = bound_inst(b)), diff --git a/cranelift/codegen/src/isa/x86/enc_tables.rs b/cranelift/codegen/src/isa/x86/enc_tables.rs index f67d7f0b69..732fcd9628 100644 --- a/cranelift/codegen/src/isa/x86/enc_tables.rs +++ b/cranelift/codegen/src/isa/x86/enc_tables.rs @@ -406,12 +406,16 @@ fn expand_fcvt_from_uint( let mut pos = FuncCursor::new(func).at_inst(inst); pos.use_srcloc(inst); - // Conversion from unsigned 32-bit is easy on x86-64. - // TODO: This should be guarded by an ISA check. - if xty == ir::types::I32 { - let wide = pos.ins().uextend(ir::types::I64, x); - pos.func.dfg.replace(inst).fcvt_from_sint(ty, wide); - return; + // Conversion from an unsigned int smaller than 64bit is easy on x86-64. + match xty { + ir::types::I8 | ir::types::I16 | ir::types::I32 => { + // TODO: This should be guarded by an ISA check. + let wide = pos.ins().uextend(ir::types::I64, x); + pos.func.dfg.replace(inst).fcvt_from_sint(ty, wide); + return; + } + ir::types::I64 => {} + _ => unimplemented!(), } let old_ebb = pos.func.layout.pp_ebb(inst); diff --git a/cranelift/filetests/filetests/isa/x86/saturating-float-cast.clif b/cranelift/filetests/filetests/isa/x86/saturating-float-cast.clif new file mode 100644 index 0000000000..5986e1f864 --- /dev/null +++ b/cranelift/filetests/filetests/isa/x86/saturating-float-cast.clif @@ -0,0 +1,13 @@ +test compile +target x86_64 + +function u0:0() -> f32 system_v { +ebb0: + v0 = iconst.i8 255 +; check: v2 = iconst.i32 255 +; nextln: v0 = ireduce.i8 v2 + v1 = fcvt_from_uint.f32 v0 +; nextln: v3 = uextend.i64 v0 +; nextln: v1 = fcvt_from_sint.f32 v3 + return v1 +}