Correctly zero extend operand of fcvt_from_uint for 8ints and 16bit ints (#997)
Fixes #996
This commit is contained in:
@@ -64,7 +64,6 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro
|
|||||||
let f64const = insts.by_name("f64const");
|
let f64const = insts.by_name("f64const");
|
||||||
let fcopysign = insts.by_name("fcopysign");
|
let fcopysign = insts.by_name("fcopysign");
|
||||||
let fcvt_from_sint = insts.by_name("fcvt_from_sint");
|
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 fneg = insts.by_name("fneg");
|
||||||
let iadd = insts.by_name("iadd");
|
let iadd = insts.by_name("iadd");
|
||||||
let iadd_cin = insts.by_name("iadd_cin");
|
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.
|
// Expansion for fcvt_from_sint for smaller integer types.
|
||||||
// These use expand and not widen because the controlling type variable for
|
// This uses expand and not widen because the controlling type variable for
|
||||||
// these instructions are f32/f64, which are legalized as part of the expand
|
// this instruction is f32/f64, which is legalized as part of the expand
|
||||||
// group.
|
// group.
|
||||||
for &dest_ty in &[F32, F64] {
|
for &dest_ty in &[F32, F64] {
|
||||||
for &src_ty in &[I8, I16] {
|
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);
|
let bound_inst = fcvt_from_sint.bind(dest_ty).bind(src_ty);
|
||||||
expand.legalize(
|
expand.legalize(
|
||||||
def!(a = bound_inst(b)),
|
def!(a = bound_inst(b)),
|
||||||
|
|||||||
@@ -406,12 +406,16 @@ fn expand_fcvt_from_uint(
|
|||||||
let mut pos = FuncCursor::new(func).at_inst(inst);
|
let mut pos = FuncCursor::new(func).at_inst(inst);
|
||||||
pos.use_srcloc(inst);
|
pos.use_srcloc(inst);
|
||||||
|
|
||||||
// Conversion from unsigned 32-bit is easy on x86-64.
|
// Conversion from an unsigned int smaller than 64bit is easy on x86-64.
|
||||||
// TODO: This should be guarded by an ISA check.
|
match xty {
|
||||||
if xty == ir::types::I32 {
|
ir::types::I8 | ir::types::I16 | ir::types::I32 => {
|
||||||
let wide = pos.ins().uextend(ir::types::I64, x);
|
// TODO: This should be guarded by an ISA check.
|
||||||
pos.func.dfg.replace(inst).fcvt_from_sint(ty, wide);
|
let wide = pos.ins().uextend(ir::types::I64, x);
|
||||||
return;
|
pos.func.dfg.replace(inst).fcvt_from_sint(ty, wide);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ir::types::I64 => {}
|
||||||
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
let old_ebb = pos.func.layout.pp_ebb(inst);
|
let old_ebb = pos.func.layout.pp_ebb(inst);
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user