Use Cranelift legalization for icmp.i128
The previous translation was wrong for signed 128bit comparisions This fixes several libcore tests
This commit is contained in:
parent
5c6bf836fe
commit
ef4186a85b
6 changed files with 14 additions and 166 deletions
|
@ -81,6 +81,12 @@ fn main() {
|
||||||
assert_eq!(houndred_f32 as i128, 100);
|
assert_eq!(houndred_f32 as i128, 100);
|
||||||
assert_eq!(houndred_f64 as i128, 100);
|
assert_eq!(houndred_f64 as i128, 100);
|
||||||
|
|
||||||
|
// Test signed 128bit comparing
|
||||||
|
let max = usize::MAX as i128;
|
||||||
|
if 100i128 < 0i128 || 100i128 > max {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
|
||||||
let _a = 1u32 << 2u8;
|
let _a = 1u32 << 2u8;
|
||||||
|
|
||||||
let empty: [i32; 0] = [];
|
let empty: [i32; 0] = [];
|
||||||
|
|
|
@ -119,25 +119,5 @@ index 6609bc3..241b497 100644
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "index 0 greater than length of slice")]
|
#[should_panic(expected = "index 0 greater than length of slice")]
|
||||||
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
|
--
|
||||||
index b73b621..d6cc3f8 100644
|
|
||||||
--- a/src/libcore/tests/iter.rs
|
|
||||||
+++ b/src/libcore/tests/iter.rs
|
|
||||||
@@ -2541,6 +2541,7 @@ fn test_steps_between() {
|
|
||||||
|
|
||||||
// Skip u64/i64 to avoid differences with 32-bit vs 64-bit platforms
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
assert_eq!(Step::steps_between(&20_u128, &200_u128), Some(180_usize));
|
|
||||||
assert_eq!(Step::steps_between(&-20_i128, &80_i128), Some(100_usize));
|
|
||||||
if cfg!(target_pointer_width = "64") {
|
|
||||||
@@ -2552,6 +2553,7 @@ fn test_steps_between() {
|
|
||||||
Step::steps_between(&-0x1_0000_0000_0000_0000_i128, &0x1_0000_0000_0000_0000_i128,),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
+ */
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
--
|
|
||||||
2.21.0 (Apple Git-122)
|
2.21.0 (Apple Git-122)
|
||||||
|
|
|
@ -66,87 +66,6 @@ index c9096b7..be37fcd 100644
|
||||||
fn test_successors() {
|
fn test_successors() {
|
||||||
let mut powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10));
|
let mut powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10));
|
||||||
assert_eq!(powers_of_10.by_ref().collect::<Vec<_>>(), &[1, 10, 100, 1_000, 10_000]);
|
assert_eq!(powers_of_10.by_ref().collect::<Vec<_>>(), &[1, 10, 100, 1_000, 10_000]);
|
||||||
diff --git a/src/libcore/tests/num/bignum.rs b/src/libcore/tests/num/bignum.rs
|
|
||||||
index b9e15ec..32f6de8 100644
|
|
||||||
--- a/src/libcore/tests/num/bignum.rs
|
|
||||||
+++ b/src/libcore/tests/num/bignum.rs
|
|
||||||
@@ -3,6 +3,7 @@ use core::num::bignum::tests::Big8x3 as Big;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
+#[ignore]
|
|
||||||
fn test_from_u64_overflow() {
|
|
||||||
Big::from_u64(0x1000000);
|
|
||||||
}
|
|
||||||
@@ -19,12 +20,14 @@ fn test_add() {
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
+#[ignore]
|
|
||||||
fn test_add_overflow_1() {
|
|
||||||
Big::from_small(1).add(&Big::from_u64(0xffffff));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
+#[ignore]
|
|
||||||
fn test_add_overflow_2() {
|
|
||||||
Big::from_u64(0xffffff).add(&Big::from_small(1));
|
|
||||||
}
|
|
||||||
@@ -42,6 +45,7 @@ fn test_add_small() {
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
+#[ignore]
|
|
||||||
fn test_add_small_overflow() {
|
|
||||||
Big::from_u64(0xffffff).add_small(1);
|
|
||||||
}
|
|
||||||
@@ -76,6 +80,7 @@ fn test_mul_small() {
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
+#[ignore]
|
|
||||||
fn test_mul_small_overflow() {
|
|
||||||
Big::from_u64(0x800000).mul_small(2);
|
|
||||||
}
|
|
||||||
@@ -118,12 +123,14 @@ fn test_mul_pow5() {
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
+#[ignore]
|
|
||||||
fn test_mul_pow5_overflow_1() {
|
|
||||||
Big::from_small(1).mul_pow5(12);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
+#[ignore]
|
|
||||||
fn test_mul_pow5_overflow_2() {
|
|
||||||
Big::from_small(230).mul_pow5(8);
|
|
||||||
}
|
|
||||||
@@ -141,12 +148,14 @@ fn test_mul_digits() {
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
+#[ignore]
|
|
||||||
fn test_mul_digits_overflow_1() {
|
|
||||||
Big::from_u64(0x800000).mul_digits(&[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
+#[ignore]
|
|
||||||
fn test_mul_digits_overflow_2() {
|
|
||||||
Big::from_u64(0x1000).mul_digits(&[0, 0x10]);
|
|
||||||
}
|
|
||||||
@@ -206,6 +215,7 @@ fn test_get_bit() {
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
+#[ignore]
|
|
||||||
fn test_get_bit_out_of_range() {
|
|
||||||
Big::from_small(42).get_bit(24);
|
|
||||||
}
|
|
||||||
diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs
|
diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs
|
||||||
index a17c094..5bb11d2 100644
|
index a17c094..5bb11d2 100644
|
||||||
--- a/src/libcore/tests/num/mod.rs
|
--- a/src/libcore/tests/num/mod.rs
|
||||||
|
@ -159,18 +78,6 @@ index a17c094..5bb11d2 100644
|
||||||
fn from_str_issue7588() {
|
fn from_str_issue7588() {
|
||||||
let u: Option<u8> = u8::from_str_radix("1000", 10).ok();
|
let u: Option<u8> = u8::from_str_radix("1000", 10).ok();
|
||||||
assert_eq!(u, None);
|
assert_eq!(u, None);
|
||||||
@@ -613,11 +614,9 @@ test_impl_try_from_signed_to_unsigned_err! { test_try_i64u32, i64, u32 }
|
|
||||||
test_impl_try_from_signed_to_unsigned_err! { test_try_i128u8, i128, u8 }
|
|
||||||
test_impl_try_from_signed_to_unsigned_err! { test_try_i128u16, i128, u16 }
|
|
||||||
test_impl_try_from_signed_to_unsigned_err! { test_try_i128u32, i128, u32 }
|
|
||||||
-test_impl_try_from_signed_to_unsigned_err! { test_try_i128u64, i128, u64 }
|
|
||||||
|
|
||||||
assume_usize_width! {
|
|
||||||
test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu8, isize, u8 }
|
|
||||||
- test_impl_try_from_signed_to_unsigned_err! { test_try_i128usize, i128, usize }
|
|
||||||
|
|
||||||
cfg_block! {
|
|
||||||
#[cfg(target_pointer_width = "16")] {
|
|
||||||
@@ -640,6 +639,7 @@ macro_rules! test_float {
|
@@ -640,6 +639,7 @@ macro_rules! test_float {
|
||||||
mod $modname {
|
mod $modname {
|
||||||
// FIXME(nagisa): these tests should test for sign of -0.0
|
// FIXME(nagisa): these tests should test for sign of -0.0
|
||||||
|
|
|
@ -81,51 +81,6 @@ pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn codegen_icmp(
|
|
||||||
fx: &mut FunctionCx<'_, '_, impl Backend>,
|
|
||||||
intcc: IntCC,
|
|
||||||
lhs: Value,
|
|
||||||
rhs: Value,
|
|
||||||
) -> Value {
|
|
||||||
let lhs_ty = fx.bcx.func.dfg.value_type(lhs);
|
|
||||||
let rhs_ty = fx.bcx.func.dfg.value_type(rhs);
|
|
||||||
assert_eq!(lhs_ty, rhs_ty);
|
|
||||||
if lhs_ty == types::I128 {
|
|
||||||
// FIXME legalize `icmp.i128` in Cranelift
|
|
||||||
|
|
||||||
let (lhs_lsb, lhs_msb) = fx.bcx.ins().isplit(lhs);
|
|
||||||
let (rhs_lsb, rhs_msb) = fx.bcx.ins().isplit(rhs);
|
|
||||||
|
|
||||||
match intcc {
|
|
||||||
IntCC::Equal => {
|
|
||||||
let lsb_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_lsb, rhs_lsb);
|
|
||||||
let msb_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_msb, rhs_msb);
|
|
||||||
fx.bcx.ins().band(lsb_eq, msb_eq)
|
|
||||||
}
|
|
||||||
IntCC::NotEqual => {
|
|
||||||
let lsb_ne = fx.bcx.ins().icmp(IntCC::NotEqual, lhs_lsb, rhs_lsb);
|
|
||||||
let msb_ne = fx.bcx.ins().icmp(IntCC::NotEqual, lhs_msb, rhs_msb);
|
|
||||||
fx.bcx.ins().bor(lsb_ne, msb_ne)
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// if msb_eq {
|
|
||||||
// lsb_cc
|
|
||||||
// } else {
|
|
||||||
// msb_cc
|
|
||||||
// }
|
|
||||||
|
|
||||||
let msb_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_msb, rhs_msb);
|
|
||||||
let lsb_cc = fx.bcx.ins().icmp(intcc, lhs_lsb, rhs_lsb);
|
|
||||||
let msb_cc = fx.bcx.ins().icmp(intcc, lhs_msb, rhs_msb);
|
|
||||||
|
|
||||||
fx.bcx.ins().select(msb_eq, lsb_cc, msb_cc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fx.bcx.ins().icmp(intcc, lhs, rhs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn codegen_icmp_imm(
|
pub(crate) fn codegen_icmp_imm(
|
||||||
fx: &mut FunctionCx<'_, '_, impl Backend>,
|
fx: &mut FunctionCx<'_, '_, impl Backend>,
|
||||||
intcc: IntCC,
|
intcc: IntCC,
|
||||||
|
|
|
@ -126,7 +126,7 @@ macro atomic_minmax($fx:expr, $cc:expr, <$T:ident> ($ptr:ident, $src:ident) -> $
|
||||||
let old = $fx.bcx.ins().load(clif_ty, MemFlags::new(), $ptr, 0);
|
let old = $fx.bcx.ins().load(clif_ty, MemFlags::new(), $ptr, 0);
|
||||||
|
|
||||||
// Compare
|
// Compare
|
||||||
let is_eq = codegen_icmp($fx, IntCC::SignedGreaterThan, old, $src);
|
let is_eq = $fx.bcx.ins().icmp(IntCC::SignedGreaterThan, old, $src);
|
||||||
let new = $fx.bcx.ins().select(is_eq, old, $src);
|
let new = $fx.bcx.ins().select(is_eq, old, $src);
|
||||||
|
|
||||||
// Write new
|
// Write new
|
||||||
|
@ -257,7 +257,7 @@ macro simd_cmp {
|
||||||
if let Some(vector_ty) = vector_ty {
|
if let Some(vector_ty) = vector_ty {
|
||||||
let x = $x.load_scalar($fx);
|
let x = $x.load_scalar($fx);
|
||||||
let y = $y.load_scalar($fx);
|
let y = $y.load_scalar($fx);
|
||||||
let val = codegen_icmp($fx, IntCC::$cc, x, y);
|
let val = $fx.bcx.ins().icmp(IntCC::$cc, x, y);
|
||||||
|
|
||||||
// HACK This depends on the fact that icmp for vectors represents bools as 0 and !0, not 0 and 1.
|
// HACK This depends on the fact that icmp for vectors represents bools as 0 and !0, not 0 and 1.
|
||||||
let val = $fx.bcx.ins().raw_bitcast(vector_ty, val);
|
let val = $fx.bcx.ins().raw_bitcast(vector_ty, val);
|
||||||
|
@ -271,7 +271,7 @@ macro simd_cmp {
|
||||||
$ret,
|
$ret,
|
||||||
|fx, lane_layout, res_lane_layout, x_lane, y_lane| {
|
|fx, lane_layout, res_lane_layout, x_lane, y_lane| {
|
||||||
let res_lane = match lane_layout.ty.kind {
|
let res_lane = match lane_layout.ty.kind {
|
||||||
ty::Uint(_) | ty::Int(_) => codegen_icmp(fx, IntCC::$cc, x_lane, y_lane),
|
ty::Uint(_) | ty::Int(_) => fx.bcx.ins().icmp(IntCC::$cc, x_lane, y_lane),
|
||||||
_ => unreachable!("{:?}", lane_layout.ty),
|
_ => unreachable!("{:?}", lane_layout.ty),
|
||||||
};
|
};
|
||||||
bool_to_zero_or_max_uint(fx, res_lane_layout, res_lane)
|
bool_to_zero_or_max_uint(fx, res_lane_layout, res_lane)
|
||||||
|
@ -288,8 +288,8 @@ macro simd_cmp {
|
||||||
$ret,
|
$ret,
|
||||||
|fx, lane_layout, res_lane_layout, x_lane, y_lane| {
|
|fx, lane_layout, res_lane_layout, x_lane, y_lane| {
|
||||||
let res_lane = match lane_layout.ty.kind {
|
let res_lane = match lane_layout.ty.kind {
|
||||||
ty::Uint(_) => codegen_icmp(fx, IntCC::$cc_u, x_lane, y_lane),
|
ty::Uint(_) => fx.bcx.ins().icmp(IntCC::$cc_u, x_lane, y_lane),
|
||||||
ty::Int(_) => codegen_icmp(fx, IntCC::$cc_s, x_lane, y_lane),
|
ty::Int(_) => fx.bcx.ins().icmp(IntCC::$cc_s, x_lane, y_lane),
|
||||||
_ => unreachable!("{:?}", lane_layout.ty),
|
_ => unreachable!("{:?}", lane_layout.ty),
|
||||||
};
|
};
|
||||||
bool_to_zero_or_max_uint(fx, res_lane_layout, res_lane)
|
bool_to_zero_or_max_uint(fx, res_lane_layout, res_lane)
|
||||||
|
@ -869,7 +869,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
|
||||||
let old = fx.bcx.ins().load(clif_ty, MemFlags::new(), ptr, 0);
|
let old = fx.bcx.ins().load(clif_ty, MemFlags::new(), ptr, 0);
|
||||||
|
|
||||||
// Compare
|
// Compare
|
||||||
let is_eq = codegen_icmp(fx, IntCC::Equal, old, test_old);
|
let is_eq = fx.bcx.ins().icmp(IntCC::Equal, old, test_old);
|
||||||
let new = fx.bcx.ins().select(is_eq, new, old); // Keep old if not equal to test_old
|
let new = fx.bcx.ins().select(is_eq, new, old); // Keep old if not equal to test_old
|
||||||
|
|
||||||
// Write new
|
// Write new
|
||||||
|
|
|
@ -46,7 +46,7 @@ fn codegen_compare_bin_op<'tcx>(
|
||||||
rhs: Value,
|
rhs: Value,
|
||||||
) -> CValue<'tcx> {
|
) -> CValue<'tcx> {
|
||||||
let intcc = crate::num::bin_op_to_intcc(bin_op, signed).unwrap();
|
let intcc = crate::num::bin_op_to_intcc(bin_op, signed).unwrap();
|
||||||
let val = codegen_icmp(fx, intcc, lhs, rhs);
|
let val = fx.bcx.ins().icmp(intcc, lhs, rhs);
|
||||||
let val = fx.bcx.ins().bint(types::I8, val);
|
let val = fx.bcx.ins().bint(types::I8, val);
|
||||||
CValue::by_val(val, fx.layout_of(fx.tcx.types.bool))
|
CValue::by_val(val, fx.layout_of(fx.tcx.types.bool))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue