1
Fork 0

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, &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))

View file

@ -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)?;

View file

@ -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 {

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) { 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),

View file

@ -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)
} }

View file

@ -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;