Move unsigned_max etc into Size again

This commit is contained in:
Andreas Liljeqvist 2021-09-06 20:11:29 +02:00
parent 459c9108e4
commit 9129f4306f
6 changed files with 37 additions and 37 deletions

View File

@ -234,7 +234,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
&r,
)?;
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() {
// 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
@ -259,10 +260,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// unsigned
if is_add {
// max unsigned
Scalar::from_uint(
u128::MAX >> (128 - num_bits),
Size::from_bits(num_bits),
)
Scalar::from_uint(size.unsigned_max(), Size::from_bits(num_bits))
} else {
// underflow to 0
Scalar::from_uint(0u128, Size::from_bits(num_bits))

View File

@ -627,7 +627,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
// At least one value is excluded.
let valid_range = scalar_layout.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);
// Determine the allowed range
let value = self.read_scalar(op)?;

View File

@ -512,9 +512,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
let param_env = self.param_env;
let dl = self.data_layout();
let scalar_unit = |value: Primitive| {
let bits = value.size(dl).bits();
assert!(bits <= 128);
Scalar { value, valid_range: WrappingRange { start: 0, end: (!0 >> (128 - bits)) } }
let size = value.size(dl);
assert!(size.bits() <= 128);
Scalar { value, valid_range: WrappingRange { start: 0, end: size.unsigned_max() } }
};
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 {
value: Int(ity, signed),
valid_range: WrappingRange {

View File

@ -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) {
let (int, signed) = match *ty.kind() {
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) {
let (size, signed) = int_size_and_signed(tcx, self.ty);
let (val, oflo) = if signed {
let min = signed_min(size);
let max = signed_max(size);
let min = size.signed_min();
let max = size.signed_max();
let val = size.sign_extend(self.val) as i128;
assert!(n < (i128::MAX as u128));
let n = n as i128;
@ -86,7 +74,7 @@ impl<'tcx> Discr<'tcx> {
let val = size.truncate(val);
(val, oflo)
} else {
let max = unsigned_max(size);
let max = size.unsigned_max();
let val = self.val;
let oflo = val > max - 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() {
ty::Int(_) | ty::Uint(_) => {
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)
}
ty::Char => Some(std::char::MAX as u128),
@ -640,7 +628,7 @@ impl<'tcx> ty::TyS<'tcx> {
let val = match self.kind() {
ty::Int(_) | ty::Uint(_) => {
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)
}
ty::Char => Some(0),

View File

@ -494,9 +494,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Helper to get a `-1` value of the appropriate type
fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
let param_ty = ty::ParamEnv::empty().and(ty);
let bits = self.tcx.layout_of(param_ty).unwrap().size.bits();
let n = (!0u128) >> (128 - bits);
let literal = ty::Const::from_bits(self.tcx, n, param_ty);
let size = self.tcx.layout_of(param_ty).unwrap().size;
let literal = ty::Const::from_bits(self.tcx, size.unsigned_max(), param_ty);
self.literal_operand(span, literal)
}

View File

@ -392,6 +392,21 @@ impl Size {
// Truncate (shift left to drop out leftover values, shift right to fill with zeroes).
(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.
@ -775,7 +790,7 @@ impl WrappingRange {
/// Returns `true` if `size` completely fills the range.
#[inline]
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);
(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 {
let Scalar { value, valid_range: v } = self.scalar;
let bits = value.size(cx).bits();
assert!(bits <= 128);
let max_value = !0u128 >> (128 - bits);
let size = value.size(cx);
assert!(size.bits() <= 128);
let max_value = size.unsigned_max();
// Find out how many values are outside the valid range.
let niche = v.end.wrapping_add(1)..v.start;
@ -1080,9 +1095,9 @@ impl Niche {
assert!(count > 0);
let Scalar { value, valid_range: v } = self.scalar;
let bits = value.size(cx).bits();
assert!(bits <= 128);
let max_value = !0u128 >> (128 - bits);
let size = value.size(cx);
assert!(size.bits() <= 128);
let max_value = size.unsigned_max();
if count > max_value {
return None;