Move unsigned_max
etc into Size
again
This commit is contained in:
parent
459c9108e4
commit
9129f4306f
6 changed files with 37 additions and 37 deletions
|
@ -234,7 +234,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
&r,
|
&r,
|
||||||
)?;
|
)?;
|
||||||
let val = if overflowed {
|
let val = if overflowed {
|
||||||
let num_bits = l.layout.size.bits();
|
let size = l.layout.size;
|
||||||
|
let num_bits = size.bits();
|
||||||
if l.layout.abi.is_signed() {
|
if l.layout.abi.is_signed() {
|
||||||
// For signed ints the saturated value depends on the sign of the first
|
// For signed ints the saturated value depends on the sign of the first
|
||||||
// term since the sign of the second term can be inferred from this and
|
// term since the sign of the second term can be inferred from this and
|
||||||
|
@ -259,10 +260,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// unsigned
|
// unsigned
|
||||||
if is_add {
|
if is_add {
|
||||||
// max unsigned
|
// max unsigned
|
||||||
Scalar::from_uint(
|
Scalar::from_uint(size.unsigned_max(), Size::from_bits(num_bits))
|
||||||
u128::MAX >> (128 - num_bits),
|
|
||||||
Size::from_bits(num_bits),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
// underflow to 0
|
// underflow to 0
|
||||||
Scalar::from_uint(0u128, Size::from_bits(num_bits))
|
Scalar::from_uint(0u128, Size::from_bits(num_bits))
|
||||||
|
|
|
@ -627,7 +627,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
||||||
// At least one value is excluded.
|
// At least one value is excluded.
|
||||||
let valid_range = scalar_layout.valid_range;
|
let valid_range = scalar_layout.valid_range;
|
||||||
let WrappingRange { start, end } = valid_range;
|
let WrappingRange { start, end } = valid_range;
|
||||||
let max_value = u128::MAX >> (128 - op.layout.size.bits());
|
let max_value = op.layout.size.unsigned_max();
|
||||||
assert!(end <= max_value);
|
assert!(end <= max_value);
|
||||||
// Determine the allowed range
|
// Determine the allowed range
|
||||||
let value = self.read_scalar(op)?;
|
let value = self.read_scalar(op)?;
|
||||||
|
|
|
@ -512,9 +512,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||||
let param_env = self.param_env;
|
let param_env = self.param_env;
|
||||||
let dl = self.data_layout();
|
let dl = self.data_layout();
|
||||||
let scalar_unit = |value: Primitive| {
|
let scalar_unit = |value: Primitive| {
|
||||||
let bits = value.size(dl).bits();
|
let size = value.size(dl);
|
||||||
assert!(bits <= 128);
|
assert!(size.bits() <= 128);
|
||||||
Scalar { value, valid_range: WrappingRange { start: 0, end: (!0 >> (128 - bits)) } }
|
Scalar { value, valid_range: WrappingRange { start: 0, end: size.unsigned_max() } }
|
||||||
};
|
};
|
||||||
let scalar = |value: Primitive| tcx.intern_layout(Layout::scalar(self, scalar_unit(value)));
|
let scalar = |value: Primitive| tcx.intern_layout(Layout::scalar(self, scalar_unit(value)));
|
||||||
|
|
||||||
|
@ -1266,7 +1266,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let tag_mask = !0u128 >> (128 - ity.size().bits());
|
let tag_mask = ity.size().unsigned_max();
|
||||||
let tag = Scalar {
|
let tag = Scalar {
|
||||||
value: Int(ity, signed),
|
value: Int(ity, signed),
|
||||||
valid_range: WrappingRange {
|
valid_range: WrappingRange {
|
||||||
|
|
|
@ -45,18 +45,6 @@ impl<'tcx> fmt::Display for Discr<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signed_min(size: Size) -> i128 {
|
|
||||||
size.sign_extend(1_u128 << (size.bits() - 1)) as i128
|
|
||||||
}
|
|
||||||
|
|
||||||
fn signed_max(size: Size) -> i128 {
|
|
||||||
i128::MAX >> (128 - size.bits())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unsigned_max(size: Size) -> u128 {
|
|
||||||
u128::MAX >> (128 - size.bits())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn int_size_and_signed<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (Size, bool) {
|
fn int_size_and_signed<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (Size, bool) {
|
||||||
let (int, signed) = match *ty.kind() {
|
let (int, signed) = match *ty.kind() {
|
||||||
Int(ity) => (Integer::from_int_ty(&tcx, ity), true),
|
Int(ity) => (Integer::from_int_ty(&tcx, ity), true),
|
||||||
|
@ -74,8 +62,8 @@ impl<'tcx> Discr<'tcx> {
|
||||||
pub fn checked_add(self, tcx: TyCtxt<'tcx>, n: u128) -> (Self, bool) {
|
pub fn checked_add(self, tcx: TyCtxt<'tcx>, n: u128) -> (Self, bool) {
|
||||||
let (size, signed) = int_size_and_signed(tcx, self.ty);
|
let (size, signed) = int_size_and_signed(tcx, self.ty);
|
||||||
let (val, oflo) = if signed {
|
let (val, oflo) = if signed {
|
||||||
let min = signed_min(size);
|
let min = size.signed_min();
|
||||||
let max = signed_max(size);
|
let max = size.signed_max();
|
||||||
let val = size.sign_extend(self.val) as i128;
|
let val = size.sign_extend(self.val) as i128;
|
||||||
assert!(n < (i128::MAX as u128));
|
assert!(n < (i128::MAX as u128));
|
||||||
let n = n as i128;
|
let n = n as i128;
|
||||||
|
@ -86,7 +74,7 @@ impl<'tcx> Discr<'tcx> {
|
||||||
let val = size.truncate(val);
|
let val = size.truncate(val);
|
||||||
(val, oflo)
|
(val, oflo)
|
||||||
} else {
|
} else {
|
||||||
let max = unsigned_max(size);
|
let max = size.unsigned_max();
|
||||||
let val = self.val;
|
let val = self.val;
|
||||||
let oflo = val > max - n;
|
let oflo = val > max - n;
|
||||||
let val = if oflo { n - (max - val) - 1 } else { val + n };
|
let val = if oflo { n - (max - val) - 1 } else { val + n };
|
||||||
|
@ -621,7 +609,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
||||||
let val = match self.kind() {
|
let val = match self.kind() {
|
||||||
ty::Int(_) | ty::Uint(_) => {
|
ty::Int(_) | ty::Uint(_) => {
|
||||||
let (size, signed) = int_size_and_signed(tcx, self);
|
let (size, signed) = int_size_and_signed(tcx, self);
|
||||||
let val = if signed { signed_max(size) as u128 } else { unsigned_max(size) };
|
let val = if signed { size.signed_max() as u128 } else { size.unsigned_max() };
|
||||||
Some(val)
|
Some(val)
|
||||||
}
|
}
|
||||||
ty::Char => Some(std::char::MAX as u128),
|
ty::Char => Some(std::char::MAX as u128),
|
||||||
|
@ -640,7 +628,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
||||||
let val = match self.kind() {
|
let val = match self.kind() {
|
||||||
ty::Int(_) | ty::Uint(_) => {
|
ty::Int(_) | ty::Uint(_) => {
|
||||||
let (size, signed) = int_size_and_signed(tcx, self);
|
let (size, signed) = int_size_and_signed(tcx, self);
|
||||||
let val = if signed { size.truncate(signed_min(size) as u128) } else { 0 };
|
let val = if signed { size.truncate(size.signed_min() as u128) } else { 0 };
|
||||||
Some(val)
|
Some(val)
|
||||||
}
|
}
|
||||||
ty::Char => Some(0),
|
ty::Char => Some(0),
|
||||||
|
|
|
@ -494,9 +494,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// Helper to get a `-1` value of the appropriate type
|
// Helper to get a `-1` value of the appropriate type
|
||||||
fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
|
fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
|
||||||
let param_ty = ty::ParamEnv::empty().and(ty);
|
let param_ty = ty::ParamEnv::empty().and(ty);
|
||||||
let bits = self.tcx.layout_of(param_ty).unwrap().size.bits();
|
let size = self.tcx.layout_of(param_ty).unwrap().size;
|
||||||
let n = (!0u128) >> (128 - bits);
|
let literal = ty::Const::from_bits(self.tcx, size.unsigned_max(), param_ty);
|
||||||
let literal = ty::Const::from_bits(self.tcx, n, param_ty);
|
|
||||||
|
|
||||||
self.literal_operand(span, literal)
|
self.literal_operand(span, literal)
|
||||||
}
|
}
|
||||||
|
|
|
@ -392,6 +392,21 @@ impl Size {
|
||||||
// Truncate (shift left to drop out leftover values, shift right to fill with zeroes).
|
// Truncate (shift left to drop out leftover values, shift right to fill with zeroes).
|
||||||
(value << shift) >> shift
|
(value << shift) >> shift
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn signed_min(&self) -> i128 {
|
||||||
|
self.sign_extend(1_u128 << (self.bits() - 1)) as i128
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn signed_max(&self) -> i128 {
|
||||||
|
i128::MAX >> (128 - self.bits())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn unsigned_max(&self) -> u128 {
|
||||||
|
u128::MAX >> (128 - self.bits())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Panicking addition, subtraction and multiplication for convenience.
|
// Panicking addition, subtraction and multiplication for convenience.
|
||||||
|
@ -775,7 +790,7 @@ impl WrappingRange {
|
||||||
/// Returns `true` if `size` completely fills the range.
|
/// Returns `true` if `size` completely fills the range.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_full_for(&self, size: Size) -> bool {
|
pub fn is_full_for(&self, size: Size) -> bool {
|
||||||
let max_value = u128::MAX >> (128 - size.bits());
|
let max_value = size.unsigned_max();
|
||||||
debug_assert!(self.start <= max_value && self.end <= max_value);
|
debug_assert!(self.start <= max_value && self.end <= max_value);
|
||||||
(self.start == 0 && self.end == max_value) || (self.end + 1 == self.start)
|
(self.start == 0 && self.end == max_value) || (self.end + 1 == self.start)
|
||||||
}
|
}
|
||||||
|
@ -1067,9 +1082,9 @@ impl Niche {
|
||||||
|
|
||||||
pub fn available<C: HasDataLayout>(&self, cx: &C) -> u128 {
|
pub fn available<C: HasDataLayout>(&self, cx: &C) -> u128 {
|
||||||
let Scalar { value, valid_range: v } = self.scalar;
|
let Scalar { value, valid_range: v } = self.scalar;
|
||||||
let bits = value.size(cx).bits();
|
let size = value.size(cx);
|
||||||
assert!(bits <= 128);
|
assert!(size.bits() <= 128);
|
||||||
let max_value = !0u128 >> (128 - bits);
|
let max_value = size.unsigned_max();
|
||||||
|
|
||||||
// Find out how many values are outside the valid range.
|
// Find out how many values are outside the valid range.
|
||||||
let niche = v.end.wrapping_add(1)..v.start;
|
let niche = v.end.wrapping_add(1)..v.start;
|
||||||
|
@ -1080,9 +1095,9 @@ impl Niche {
|
||||||
assert!(count > 0);
|
assert!(count > 0);
|
||||||
|
|
||||||
let Scalar { value, valid_range: v } = self.scalar;
|
let Scalar { value, valid_range: v } = self.scalar;
|
||||||
let bits = value.size(cx).bits();
|
let size = value.size(cx);
|
||||||
assert!(bits <= 128);
|
assert!(size.bits() <= 128);
|
||||||
let max_value = !0u128 >> (128 - bits);
|
let max_value = size.unsigned_max();
|
||||||
|
|
||||||
if count > max_value {
|
if count > max_value {
|
||||||
return None;
|
return None;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue