Skip to content

Commit

Permalink
Correctly zero extend operand of fcvt_from_uint for 8ints and 16bit ints
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Sep 14, 2019
1 parent 8945b82 commit f447161
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 19 deletions.
16 changes: 3 additions & 13 deletions cranelift-codegen/meta/src/shared/legalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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 use 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)),
Expand Down
21 changes: 15 additions & 6 deletions cranelift-codegen/src/isa/x86/enc_tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,12 +406,21 @@ 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 => {
let wide = pos.ins().uextend(ir::types::I64, x);
pos.func.dfg.replace(inst).fcvt_from_sint(ty, wide);
return;
}
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);
Expand Down
13 changes: 13 additions & 0 deletions filetests/isa/x86/saturating-float-cast.clif
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit f447161

Please sign in to comment.