Workaround for missing icmp{,_imm}.i128 legalizations

Fixes #667
This commit is contained in:
bjorn3 2019-08-15 11:36:06 +02:00
parent 9505d60a24
commit 7c7a8e8367
6 changed files with 103 additions and 160 deletions

View File

@ -1,112 +0,0 @@
From e87977477e8507a5749e64ea49ee503e706d7178 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 1 Mar 2019 18:36:21 +0100
Subject: [PATCH] Disable u128 and i128 in libcore
---
src/libcore/sync/atomic.rs | 32 --------
src/libcore/time.rs | 123 -------------------------------
src/libstd/num.rs | 2 +-
src/libstd/panic.rs | 6 --
20 files changed, 63 insertions(+), 363 deletions(-)
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 6b657b1..5add3f3 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -127,8 +127,8 @@ macro_rules! from_str_radix_nzint_impl {
)*}
}
-from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
- NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
+from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroUsize
+ NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroIsize }
/// Provides intentionally-wrapped arithmetic on `T`.
///
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index d0ee5fa..d02c454 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -2012,38 +2012,6 @@ atomic_int! {
"AtomicU64::new(0)",
u64 AtomicU64 ATOMIC_U64_INIT
}
-#[cfg(target_has_atomic = "128")]
-atomic_int! {
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- "i128", "../../../std/primitive.i128.html",
- "#![feature(integer_atomics)]\n\n",
- atomic_min, atomic_max,
- 16,
- "AtomicI128::new(0)",
- i128 AtomicI128 ATOMIC_I128_INIT
-}
-#[cfg(target_has_atomic = "128")]
-atomic_int! {
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- "u128", "../../../std/primitive.u128.html",
- "#![feature(integer_atomics)]\n\n",
- atomic_umin, atomic_umax,
- 16,
- "AtomicU128::new(0)",
- u128 AtomicU128 ATOMIC_U128_INIT
-}
#[cfg(target_pointer_width = "16")]
macro_rules! ptr_width {
() => { 2 }
diff --git a/src/libstd/num.rs b/src/libstd/num.rs
index 828d572..bc04fb1 100644
--- a/src/libstd/num.rs
+++ b/src/libstd/num.rs
@@ -12,7 +12,7 @@ pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError}
pub use core::num::Wrapping;
#[stable(feature = "nonzero", since = "1.28.0")]
-pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize};
+pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};
#[stable(feature = "signed_nonzero", since = "1.34.0")]
-pub use core::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize};
+pub use core::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroIsize};
#[cfg(test)] use crate::fmt;
#[cfg(test)] use crate::ops::{Add, Sub, Mul, Div, Rem};
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 6a16414..f027102 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -254,9 +254,6 @@ impl RefUnwindSafe for atomic::AtomicI32 {}
#[cfg(target_has_atomic = "64")]
#[unstable(feature = "integer_atomics", issue = "32976")]
impl RefUnwindSafe for atomic::AtomicI64 {}
-#[cfg(target_has_atomic = "128")]
-#[unstable(feature = "integer_atomics", issue = "32976")]
-impl RefUnwindSafe for atomic::AtomicI128 {}
#[cfg(target_has_atomic = "ptr")]
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
@@ -273,9 +270,6 @@ impl RefUnwindSafe for atomic::AtomicU32 {}
#[cfg(target_has_atomic = "64")]
#[unstable(feature = "integer_atomics", issue = "32976")]
impl RefUnwindSafe for atomic::AtomicU64 {}
-#[cfg(target_has_atomic = "128")]
-#[unstable(feature = "integer_atomics", issue = "32976")]
-impl RefUnwindSafe for atomic::AtomicU128 {}
#[cfg(target_has_atomic = "8")]
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
--
2.17.2 (Apple Git-113)

View File

@ -73,39 +73,7 @@ pub fn maybe_codegen<'a, 'tcx>(
}
BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => {
assert!(!checked);
let (lhs_lsb, lhs_msb) = fx.bcx.ins().isplit(lhs_val);
let (rhs_lsb, rhs_msb) = fx.bcx.ins().isplit(rhs_val);
let res = match bin_op {
BinOp::Eq => {
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)
}
BinOp::Ne => {
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 cc = crate::num::bin_op_to_intcc(bin_op, is_signed).unwrap();
let msb_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_msb, rhs_msb);
let lsb_cc = fx.bcx.ins().icmp(cc, lhs_lsb, rhs_lsb);
let msb_cc = fx.bcx.ins().icmp(cc, lhs_msb, rhs_msb);
fx.bcx.ins().select(msb_eq, lsb_cc, msb_cc)
}
};
let res = fx.bcx.ins().bint(types::I8, res);
let res = CValue::by_val(res, fx.layout_of(fx.tcx.types.bool));
return Some(res);
return None;
}
BinOp::Shl | BinOp::Shr => {
let is_overflow = if checked {

View File

@ -73,6 +73,95 @@ pub fn codegen_select(bcx: &mut FunctionBuilder, cond: Value, lhs: Value, rhs: V
}
}
pub fn codegen_icmp<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, 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 fn codegen_icmp_imm<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
intcc: IntCC,
lhs: Value,
rhs: i128,
) -> Value {
let lhs_ty = fx.bcx.func.dfg.value_type(lhs);
if lhs_ty == types::I128 {
// FIXME legalize `icmp_imm.i128` in Cranelift
let (lhs_lsb, lhs_msb) = fx.bcx.ins().isplit(lhs);
let (rhs_lsb, rhs_msb) = (rhs as u128 as u64 as i64, (rhs as u128 >> 64) as u64 as i64);
match intcc {
IntCC::Equal => {
let lsb_eq = fx.bcx.ins().icmp_imm(IntCC::Equal, lhs_lsb, rhs_lsb);
let msb_eq = fx.bcx.ins().icmp_imm(IntCC::Equal, lhs_msb, rhs_msb);
fx.bcx.ins().band(lsb_eq, msb_eq)
}
IntCC::NotEqual => {
let lsb_ne = fx.bcx.ins().icmp_imm(IntCC::NotEqual, lhs_lsb, rhs_lsb);
let msb_ne = fx.bcx.ins().icmp_imm(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_imm(IntCC::Equal, lhs_msb, rhs_msb);
let lsb_cc = fx.bcx.ins().icmp_imm(intcc, lhs_lsb, rhs_lsb);
let msb_cc = fx.bcx.ins().icmp_imm(intcc, lhs_msb, rhs_msb);
fx.bcx.ins().select(msb_eq, lsb_cc, msb_cc)
}
}
} else {
let rhs = i64::try_from(rhs).expect("codegen_icmp_imm rhs out of range for <128bit int");
fx.bcx.ins().icmp_imm(intcc, lhs, rhs)
}
}
fn resolve_normal_value_imm(func: &Function, val: Value) -> Option<i64> {
if let ValueDef::Result(inst, 0 /*param*/) = func.dfg.value_def(val) {
if let InstructionData::UnaryImm {

View File

@ -102,10 +102,7 @@ pub fn codegen_get_discriminant<'tcx>(
let niche_llty = fx.clif_type(discr_ty).unwrap();
let dest_clif_ty = fx.clif_type(dest_layout.ty).unwrap();
if niche_variants.start() == niche_variants.end() {
let b = fx
.bcx
.ins()
.icmp_imm(IntCC::Equal, lldiscr, *niche_start as u64 as i64);
let b = codegen_icmp_imm(fx, IntCC::Equal, lldiscr, *niche_start as i128);
let if_true = fx
.bcx
.ins()
@ -121,10 +118,11 @@ pub fn codegen_get_discriminant<'tcx>(
let delta = niche_start.wrapping_sub(niche_variants.start().as_u32() as u128);
let delta = fx.bcx.ins().iconst(niche_llty, delta as u64 as i64);
let lldiscr = fx.bcx.ins().isub(lldiscr, delta);
let b = fx.bcx.ins().icmp_imm(
let b = codegen_icmp_imm(
fx,
IntCC::UnsignedLessThanOrEqual,
lldiscr,
niche_variants.end().as_u32() as i64,
i128::from(niche_variants.end().as_u32()),
);
let if_true =
clif_intcast(fx, lldiscr, fx.clif_type(dest_layout.ty).unwrap(), false);

View File

@ -119,8 +119,8 @@ macro_rules! atomic_minmax {
let old = $fx.bcx.ins().load(clif_ty, MemFlags::new(), $ptr, 0);
// Compare
let is_eq = $fx.bcx.ins().icmp(IntCC::SignedGreaterThan, old, $src);
let new = crate::common::codegen_select(&mut $fx.bcx, is_eq, old, $src);
let is_eq = codegen_icmp($fx, IntCC::SignedGreaterThan, old, $src);
let new = codegen_select(&mut $fx.bcx, is_eq, old, $src);
// Write new
$fx.bcx.ins().store(MemFlags::new(), new, $ptr, 0);
@ -198,7 +198,7 @@ macro_rules! simd_cmp {
($fx:expr, $intrinsic:expr, $cc:ident($x:ident, $y:ident) -> $ret:ident) => {
simd_for_each_lane($fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, res_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) | ty::Int(_) => fx.bcx.ins().icmp(IntCC::$cc, x_lane, y_lane),
ty::Uint(_) | ty::Int(_) => codegen_icmp(fx, IntCC::$cc, x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
bool_to_zero_or_max_uint(fx, res_lane_layout, res_lane)
@ -207,8 +207,8 @@ macro_rules! simd_cmp {
($fx:expr, $intrinsic:expr, $cc_u:ident|$cc_s:ident($x:ident, $y:ident) -> $ret:ident) => {
simd_for_each_lane($fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, res_lane_layout, x_lane, y_lane| {
let res_lane = match lane_layout.ty.sty {
ty::Uint(_) => fx.bcx.ins().icmp(IntCC::$cc_u, x_lane, y_lane),
ty::Int(_) => fx.bcx.ins().icmp(IntCC::$cc_s, x_lane, y_lane),
ty::Uint(_) => codegen_icmp(fx, IntCC::$cc_u, x_lane, y_lane),
ty::Int(_) => codegen_icmp(fx, IntCC::$cc_s, x_lane, y_lane),
_ => unreachable!("{:?}", lane_layout.ty),
};
bool_to_zero_or_max_uint(fx, res_lane_layout, res_lane)
@ -791,7 +791,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
let old = fx.bcx.ins().load(clif_ty, MemFlags::new(), ptr, 0);
// Compare
let is_eq = fx.bcx.ins().icmp(IntCC::Equal, old, test_old);
let is_eq = codegen_icmp(fx, IntCC::Equal, old, test_old);
let new = crate::common::codegen_select(&mut fx.bcx, is_eq, new, old); // Keep old if not equal to test_old
// Write new

View File

@ -21,7 +21,8 @@ fn codegen_compare_bin_op<'tcx>(
lhs: Value,
rhs: Value,
) -> CValue<'tcx> {
let val = fx.bcx.ins().icmp(bin_op_to_intcc(bin_op, signed).unwrap(), lhs, rhs);
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().bint(types::I8, val);
CValue::by_val(val, fx.layout_of(fx.tcx.types.bool))
}
@ -35,7 +36,6 @@ pub fn codegen_binop<'tcx>(
match bin_op {
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
match in_lhs.layout().ty.sty {
ref sty if *sty == fx.tcx.types.u128.sty || *sty == fx.tcx.types.i128.sty => {}
ty::Bool | ty::Uint(_) | ty::Int(_) | ty::Char => {
let signed = type_sign(in_lhs.layout().ty);
let lhs = in_lhs.load_scalar(fx);
@ -310,7 +310,7 @@ pub fn trans_ptr_binop<'a, 'tcx: 'a>(
let lhs = in_lhs.load_scalar(fx);
let rhs = in_rhs.load_scalar(fx);
return codegen_compare_bin_op(fx, bin_op, false, lhs, rhs);
return codegen_compare_bin_op(fx, bin_op, false, lhs, rhs);;
}
BinOp::Offset => {
let (base, offset) = (in_lhs, in_rhs.load_scalar(fx));