Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemente overflowing_sh* with new unchecked_sh* intrinsics #40521

Merged
merged 2 commits into from
Mar 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/libcompiler_builtins/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ pub mod reimpls {
macro_rules! ashl {
($a:expr, $b:expr, $ty:ty) => {{
let (a, b) = ($a, $b);
let bits = (::core::mem::size_of::<$ty>() * 8) as $ty;
let half_bits = bits >> 1;
let bits = ::core::mem::size_of::<$ty>().wrapping_mul(8) as $ty;
let half_bits = bits.wrapping_shr(1);
if b & half_bits != 0 {
<$ty>::from_parts(0, a.low().wrapping_shl(
b.wrapping_sub(half_bits) as u32))
Expand All @@ -58,8 +58,8 @@ pub mod reimpls {
macro_rules! ashr {
($a: expr, $b: expr, $ty:ty) => {{
let (a, b) = ($a, $b);
let bits = (::core::mem::size_of::<$ty>() * 8) as $ty;
let half_bits = bits >> 1;
let bits = ::core::mem::size_of::<$ty>().wrapping_mul(8) as $ty;
let half_bits = bits.wrapping_shr(1);
if b & half_bits != 0 {
<$ty>::from_parts(a.high().wrapping_shr(b.wrapping_sub(half_bits) as u32)
as <$ty as LargeInt>::LowHalf,
Expand All @@ -83,8 +83,8 @@ pub mod reimpls {
macro_rules! lshr {
($a: expr, $b: expr, $ty:ty) => {{
let (a, b) = ($a, $b);
let bits = (::core::mem::size_of::<$ty>() * 8) as $ty;
let half_bits = bits >> 1;
let bits = ::core::mem::size_of::<$ty>().wrapping_mul(8) as $ty;
let half_bits = bits.wrapping_shr(1);
if b & half_bits != 0 {
<$ty>::from_parts(a.high().wrapping_shr(b.wrapping_sub(half_bits) as u32), 0)
} else if b == 0 {
Expand Down Expand Up @@ -370,7 +370,7 @@ pub mod reimpls {
macro_rules! mul {
($a:expr, $b:expr, $ty: ty, $tyh: ty) => {{
let (a, b) = ($a, $b);
let half_bits = ((::core::mem::size_of::<$tyh>() * 8) / 2) as u32;
let half_bits = ::core::mem::size_of::<$tyh>().wrapping_mul(4) as u32;
let lower_mask = (!0u64).wrapping_shr(half_bits);
let mut low = (a.low() & lower_mask).wrapping_mul(b.low() & lower_mask);
let mut t = low.wrapping_shr(half_bits);
Expand Down Expand Up @@ -478,7 +478,7 @@ pub mod reimpls {
let mantissa_fraction = repr & <$fromty as FloatStuff>::MANTISSA_MASK;
let mantissa = mantissa_fraction | <$fromty as FloatStuff>::MANTISSA_LEAD_BIT;
if sign == -1.0 || exponent < 0 { return 0 as u128; }
if exponent > ::core::mem::size_of::<$outty>() as i32 * 8 {
if exponent > ::core::mem::size_of::<$outty>().wrapping_mul(8) as i32 {
return !(0 as u128);
}
(if exponent < (<$fromty as FloatStuff>::MANTISSA_BITS) as i32 {
Expand All @@ -503,7 +503,7 @@ pub mod reimpls {
let mantissa = mantissa_fraction | <$fromty as FloatStuff>::MANTISSA_LEAD_BIT;

if exponent < 0 { return 0 as i128; }
if exponent > ::core::mem::size_of::<$outty>() as i32 * 8 {
if exponent > ::core::mem::size_of::<$outty>().wrapping_mul(8) as i32 {
let ret = if sign > 0.0 { <$outty>::max_value() } else { <$outty>::min_value() };
return ret
}
Expand Down
9 changes: 9 additions & 0 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,15 @@ extern "rust-intrinsic" {
/// undefined behavior where y = 0 or x = `T::min_value()` and y = -1
pub fn unchecked_rem<T>(x: T, y: T) -> T;

/// Performs an unchecked left shift, resulting in undefined behavior when
/// y < 0 or y >= N, where N is the width of T in bits.
#[cfg(not(stage0))]
pub fn unchecked_shl<T>(x: T, y: T) -> T;
/// Performs an unchecked right shift, resulting in undefined behavior when
/// y < 0 or y >= N, where N is the width of T in bits.
#[cfg(not(stage0))]
pub fn unchecked_shr<T>(x: T, y: T) -> T;

/// Returns (a + b) mod 2^N, where N is the width of T in bits.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `wrapping_add` method. For example,
Expand Down
117 changes: 99 additions & 18 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ macro_rules! checked_op {

// `Int` + `SignedInt` implemented for signed integers
macro_rules! int_impl {
($ActualT:ident, $UnsignedT:ty, $BITS:expr,
($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr,
$add_with_overflow:path,
$sub_with_overflow:path,
$mul_with_overflow:path) => {
Expand Down Expand Up @@ -850,6 +850,17 @@ macro_rules! int_impl {
/// ```
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[inline(always)]
#[cfg(not(stage0))]
pub fn wrapping_shl(self, rhs: u32) -> Self {
unsafe {
intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
}
}

/// Stage 0
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[inline(always)]
#[cfg(stage0)]
pub fn wrapping_shl(self, rhs: u32) -> Self {
self.overflowing_shl(rhs).0
}
Expand All @@ -875,6 +886,17 @@ macro_rules! int_impl {
/// ```
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[inline(always)]
#[cfg(not(stage0))]
pub fn wrapping_shr(self, rhs: u32) -> Self {
unsafe {
intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
}
}

/// Stage 0
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[inline(always)]
#[cfg(stage0)]
pub fn wrapping_shr(self, rhs: u32) -> Self {
self.overflowing_shr(rhs).0
}
Expand Down Expand Up @@ -1089,6 +1111,15 @@ macro_rules! int_impl {
/// ```
#[inline]
#[stable(feature = "wrapping", since = "1.7.0")]
#[cfg(not(stage0))]
pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
(self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
}

/// Stage 0
#[inline]
#[stable(feature = "wrapping", since = "1.7.0")]
#[cfg(stage0)]
pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
(self << (rhs & ($BITS - 1)), (rhs > ($BITS - 1)))
}
Expand All @@ -1111,6 +1142,15 @@ macro_rules! int_impl {
/// ```
#[inline]
#[stable(feature = "wrapping", since = "1.7.0")]
#[cfg(not(stage0))]
pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
(self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
}

/// Stage 0
#[inline]
#[stable(feature = "wrapping", since = "1.7.0")]
#[cfg(stage0)]
pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
(self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1)))
}
Expand Down Expand Up @@ -1268,39 +1308,39 @@ macro_rules! int_impl {

#[lang = "i8"]
impl i8 {
int_impl! { i8, u8, 8,
int_impl! { i8, i8, u8, 8,
intrinsics::add_with_overflow,
intrinsics::sub_with_overflow,
intrinsics::mul_with_overflow }
}

#[lang = "i16"]
impl i16 {
int_impl! { i16, u16, 16,
int_impl! { i16, i16, u16, 16,
intrinsics::add_with_overflow,
intrinsics::sub_with_overflow,
intrinsics::mul_with_overflow }
}

#[lang = "i32"]
impl i32 {
int_impl! { i32, u32, 32,
int_impl! { i32, i32, u32, 32,
intrinsics::add_with_overflow,
intrinsics::sub_with_overflow,
intrinsics::mul_with_overflow }
}

#[lang = "i64"]
impl i64 {
int_impl! { i64, u64, 64,
int_impl! { i64, i64, u64, 64,
intrinsics::add_with_overflow,
intrinsics::sub_with_overflow,
intrinsics::mul_with_overflow }
}

#[lang = "i128"]
impl i128 {
int_impl! { i128, u128, 128,
int_impl! { i128, i128, u128, 128,
intrinsics::add_with_overflow,
intrinsics::sub_with_overflow,
intrinsics::mul_with_overflow }
Expand All @@ -1309,7 +1349,7 @@ impl i128 {
#[cfg(target_pointer_width = "16")]
#[lang = "isize"]
impl isize {
int_impl! { i16, u16, 16,
int_impl! { isize, i16, u16, 16,
intrinsics::add_with_overflow,
intrinsics::sub_with_overflow,
intrinsics::mul_with_overflow }
Expand All @@ -1318,7 +1358,7 @@ impl isize {
#[cfg(target_pointer_width = "32")]
#[lang = "isize"]
impl isize {
int_impl! { i32, u32, 32,
int_impl! { isize, i32, u32, 32,
intrinsics::add_with_overflow,
intrinsics::sub_with_overflow,
intrinsics::mul_with_overflow }
Expand All @@ -1327,15 +1367,15 @@ impl isize {
#[cfg(target_pointer_width = "64")]
#[lang = "isize"]
impl isize {
int_impl! { i64, u64, 64,
int_impl! { isize, i64, u64, 64,
intrinsics::add_with_overflow,
intrinsics::sub_with_overflow,
intrinsics::mul_with_overflow }
}

// `Int` + `UnsignedInt` implemented for unsigned integers
macro_rules! uint_impl {
($ActualT:ty, $BITS:expr,
($SelfT:ty, $ActualT:ty, $BITS:expr,
$ctpop:path,
$ctlz:path,
$cttz:path,
Expand Down Expand Up @@ -1978,6 +2018,17 @@ macro_rules! uint_impl {
/// ```
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[inline(always)]
#[cfg(not(stage0))]
pub fn wrapping_shl(self, rhs: u32) -> Self {
unsafe {
intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
}
}

/// Stage 0
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[inline(always)]
#[cfg(stage0)]
pub fn wrapping_shl(self, rhs: u32) -> Self {
self.overflowing_shl(rhs).0
}
Expand All @@ -2003,6 +2054,17 @@ macro_rules! uint_impl {
/// ```
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[inline(always)]
#[cfg(not(stage0))]
pub fn wrapping_shr(self, rhs: u32) -> Self {
unsafe {
intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
}
}

/// Stage 0
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[inline(always)]
#[cfg(stage0)]
pub fn wrapping_shr(self, rhs: u32) -> Self {
self.overflowing_shr(rhs).0
}
Expand Down Expand Up @@ -2170,6 +2232,15 @@ macro_rules! uint_impl {
/// ```
#[inline]
#[stable(feature = "wrapping", since = "1.7.0")]
#[cfg(not(stage0))]
pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
(self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
}

/// Stage 0
#[inline]
#[stable(feature = "wrapping", since = "1.7.0")]
#[cfg(stage0)]
pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
(self << (rhs & ($BITS - 1)), (rhs > ($BITS - 1)))
}
Expand All @@ -2192,6 +2263,16 @@ macro_rules! uint_impl {
/// ```
#[inline]
#[stable(feature = "wrapping", since = "1.7.0")]
#[cfg(not(stage0))]
pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
(self.wrapping_shr(rhs), (rhs > ($BITS - 1)))

}

/// Stage 0
#[inline]
#[stable(feature = "wrapping", since = "1.7.0")]
#[cfg(stage0)]
pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
(self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1)))
}
Expand Down Expand Up @@ -2292,7 +2373,7 @@ macro_rules! uint_impl {

#[lang = "u8"]
impl u8 {
uint_impl! { u8, 8,
uint_impl! { u8, u8, 8,
intrinsics::ctpop,
intrinsics::ctlz,
intrinsics::cttz,
Expand All @@ -2304,7 +2385,7 @@ impl u8 {

#[lang = "u16"]
impl u16 {
uint_impl! { u16, 16,
uint_impl! { u16, u16, 16,
intrinsics::ctpop,
intrinsics::ctlz,
intrinsics::cttz,
Expand All @@ -2316,7 +2397,7 @@ impl u16 {

#[lang = "u32"]
impl u32 {
uint_impl! { u32, 32,
uint_impl! { u32, u32, 32,
intrinsics::ctpop,
intrinsics::ctlz,
intrinsics::cttz,
Expand All @@ -2328,7 +2409,7 @@ impl u32 {

#[lang = "u64"]
impl u64 {
uint_impl! { u64, 64,
uint_impl! { u64, u64, 64,
intrinsics::ctpop,
intrinsics::ctlz,
intrinsics::cttz,
Expand All @@ -2340,7 +2421,7 @@ impl u64 {

#[lang = "u128"]
impl u128 {
uint_impl! { u128, 128,
uint_impl! { u128, u128, 128,
intrinsics::ctpop,
intrinsics::ctlz,
intrinsics::cttz,
Expand All @@ -2353,7 +2434,7 @@ impl u128 {
#[cfg(target_pointer_width = "16")]
#[lang = "usize"]
impl usize {
uint_impl! { u16, 16,
uint_impl! { usize, u16, 16,
intrinsics::ctpop,
intrinsics::ctlz,
intrinsics::cttz,
Expand All @@ -2365,7 +2446,7 @@ impl usize {
#[cfg(target_pointer_width = "32")]
#[lang = "usize"]
impl usize {
uint_impl! { u32, 32,
uint_impl! { usize, u32, 32,
intrinsics::ctpop,
intrinsics::ctlz,
intrinsics::cttz,
Expand All @@ -2378,7 +2459,7 @@ impl usize {
#[cfg(target_pointer_width = "64")]
#[lang = "usize"]
impl usize {
uint_impl! { u64, 64,
uint_impl! { usize, u64, 64,
intrinsics::ctpop,
intrinsics::ctlz,
intrinsics::cttz,
Expand Down
9 changes: 8 additions & 1 deletion src/librustc_trans/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
"ctlz" | "cttz" | "ctpop" | "bswap" |
"add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" |
"overflowing_add" | "overflowing_sub" | "overflowing_mul" |
"unchecked_div" | "unchecked_rem" => {
"unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" => {
let sty = &arg_tys[0].sty;
match int_type_width_signed(sty, ccx) {
Some((width, signed)) =>
Expand Down Expand Up @@ -311,6 +311,13 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
} else {
bcx.urem(llargs[0], llargs[1])
},
"unchecked_shl" => bcx.shl(llargs[0], llargs[1]),
"unchecked_shr" =>
if signed {
bcx.ashr(llargs[0], llargs[1])
} else {
bcx.lshr(llargs[0], llargs[1])
},
_ => bug!(),
},
None => {
Expand Down
Loading