Fix float -> u/i128 cast
The original test casts were optimized away by rustc, so cg_clif never saw them. cc #668
This commit is contained in:
parent
b2d6705fe2
commit
1f90b04cd6
@ -56,15 +56,18 @@ fn main() {
|
||||
assert_eq!(353985398u128 * 932490u128, 330087843781020u128);
|
||||
|
||||
// Check that all u/i128 <-> float casts work correctly.
|
||||
assert_eq!(100u128 as f32, 100.0);
|
||||
assert_eq!(100u128 as f64, 100.0);
|
||||
assert_eq!(100.0f32 as u128, 100);
|
||||
assert_eq!(100.0f64 as u128, 100);
|
||||
assert_eq!(100i128 as f32, 100.0);
|
||||
assert_eq!(100i128 as f64, 100.0);
|
||||
assert_eq!(100.0f32 as i128, 100);
|
||||
assert_eq!(100.0f64 as i128, 100);
|
||||
|
||||
let houndred_u128 = 100u128;
|
||||
let houndred_i128 = 100i128;
|
||||
let houndred_f32 = 100.0f32;
|
||||
let houndred_f64 = 100.0f64;
|
||||
assert_eq!(houndred_u128 as f32, 100.0);
|
||||
assert_eq!(houndred_u128 as f64, 100.0);
|
||||
assert_eq!(houndred_f32 as u128, 100);
|
||||
assert_eq!(houndred_f64 as u128, 100);
|
||||
assert_eq!(houndred_i128 as f32, 100.0);
|
||||
assert_eq!(houndred_i128 as f64, 100.0);
|
||||
assert_eq!(houndred_f32 as i128, 100);
|
||||
assert_eq!(houndred_f64 as i128, 100);
|
||||
|
||||
let _a = 1u32 << 2u8;
|
||||
|
||||
|
69
src/cast.rs
69
src/cast.rs
@ -55,17 +55,6 @@ pub fn clif_int_or_float_cast(
|
||||
) -> Value {
|
||||
let from_ty = fx.bcx.func.dfg.value_type(from);
|
||||
|
||||
macro call_float_cvt_intrinsic($fmt:literal, $sign_name:literal, $from_ty:expr, $to_ty:expr) {
|
||||
let intrinsic_sign_name = if from_signed { "" } else { $sign_name };
|
||||
let intrinsic_float_name = match to_ty {
|
||||
types::F32 => "s",
|
||||
types::F64 => "d",
|
||||
_ => unreachable!("{:?}", to_ty),
|
||||
};
|
||||
let intrinsic_name = format!($fmt, sign=intrinsic_sign_name, flt=intrinsic_float_name);
|
||||
return fx.easy_call(&intrinsic_name, &[CValue::by_val(from, fx.layout_of($from_ty))], $to_ty).load_scalar(fx);
|
||||
}
|
||||
|
||||
if from_ty.is_int() && to_ty.is_int() {
|
||||
// int-like -> int-like
|
||||
clif_intcast(
|
||||
@ -81,16 +70,37 @@ pub fn clif_int_or_float_cast(
|
||||
// __float tidf: i128 -> f64
|
||||
// __floatuntisf: u128 -> f32
|
||||
// __floatuntidf: u128 -> f64
|
||||
call_float_cvt_intrinsic!("__float{sign}ti{flt}f", "un", if from_signed {
|
||||
|
||||
let name = format!("__float{sign}ti{flt}f",
|
||||
sign=if from_signed {
|
||||
""
|
||||
} else {
|
||||
"un"
|
||||
},
|
||||
flt=match to_ty {
|
||||
types::F32 => "s",
|
||||
types::F64 => "d",
|
||||
_ => unreachable!("{:?}", to_ty),
|
||||
},
|
||||
);
|
||||
|
||||
let from_rust_ty = if from_signed {
|
||||
fx.tcx.types.i128
|
||||
} else {
|
||||
fx.tcx.types.u128
|
||||
},
|
||||
match to_ty {
|
||||
};
|
||||
|
||||
let to_rust_ty = match to_ty {
|
||||
types::F32 => fx.tcx.types.f32,
|
||||
types::F64 => fx.tcx.types.f64,
|
||||
_ => unreachable!(),
|
||||
});
|
||||
};
|
||||
|
||||
return fx.easy_call(
|
||||
&name,
|
||||
&[CValue::by_val(from, fx.layout_of(from_rust_ty))],
|
||||
to_rust_ty,
|
||||
).load_scalar(fx);
|
||||
}
|
||||
|
||||
// int-like -> float
|
||||
@ -106,16 +116,37 @@ pub fn clif_int_or_float_cast(
|
||||
// __fix dfti: f64 -> i128
|
||||
// __fixunssfti: f32 -> u128
|
||||
// __fixunsdfti: f64 -> u128
|
||||
call_float_cvt_intrinsic!("__fix{sign}{flt}fti", "uns", match from_ty {
|
||||
|
||||
let name = format!("__fix{sign}{flt}fti",
|
||||
sign=if to_signed {
|
||||
""
|
||||
} else {
|
||||
"uns"
|
||||
},
|
||||
flt=match from_ty {
|
||||
types::F32 => "s",
|
||||
types::F64 => "d",
|
||||
_ => unreachable!("{:?}", to_ty),
|
||||
},
|
||||
);
|
||||
|
||||
let from_rust_ty = match from_ty {
|
||||
types::F32 => fx.tcx.types.f32,
|
||||
types::F64 => fx.tcx.types.f64,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
if to_signed {
|
||||
};
|
||||
|
||||
let to_rust_ty = if to_signed {
|
||||
fx.tcx.types.i128
|
||||
} else {
|
||||
fx.tcx.types.u128
|
||||
});
|
||||
};
|
||||
|
||||
return fx.easy_call(
|
||||
&name,
|
||||
&[CValue::by_val(from, fx.layout_of(from_rust_ty))],
|
||||
to_rust_ty,
|
||||
).load_scalar(fx);
|
||||
}
|
||||
|
||||
// float -> int-like
|
||||
|
Loading…
x
Reference in New Issue
Block a user