Skip to content

Commit 6c5dd2d

Browse files
committed
Reuse libm's Caat and CastFrom in compiler-builtins
1 parent 0608b45 commit 6c5dd2d

File tree

8 files changed

+16
-52
lines changed

8 files changed

+16
-52
lines changed

compiler-builtins/src/float/add.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ where
168168
}
169169

170170
// Low three bits are round, guard, and sticky.
171-
let a_significand_i32: i32 = a_significand.cast();
171+
let a_significand_i32: i32 = a_significand.cast_lossy();
172172
let round_guard_sticky: i32 = a_significand_i32 & 0x7;
173173

174174
// Shift the significand into place, and mask off the implicit bit.

compiler-builtins/src/float/conv.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ mod int_to_float {
7474
F::Int: CastFrom<I>,
7575
Conv: Fn(I::Unsigned) -> F::Int,
7676
{
77-
let sign_bit = F::Int::cast_from(i >> (I::BITS - 1)) << (F::BITS - 1);
77+
let sign_bit = F::Int::cast_from_lossy(i >> (I::BITS - 1)) << (F::BITS - 1);
7878
F::from_bits(conv(i.unsigned_abs()) | sign_bit)
7979
}
8080

@@ -166,7 +166,7 @@ mod int_to_float {
166166

167167
// Within the upper `F::BITS`, everything except for the signifcand
168168
// gets truncated
169-
let d1: u32 = (i_m >> (u128::BITS - f32::BITS - f32::SIG_BITS - 1)).cast();
169+
let d1: u32 = (i_m >> (u128::BITS - f32::BITS - f32::SIG_BITS - 1)).cast_lossy();
170170

171171
// The entire rest of `i_m` gets truncated. Zero the upper `F::BITS` then just
172172
// check if it is nonzero.
@@ -371,7 +371,7 @@ where
371371
let m_base = if I::Unsigned::BITS >= F::Int::BITS {
372372
I::Unsigned::cast_from(fbits) << (I::BITS - F::SIG_BITS - 1)
373373
} else {
374-
I::Unsigned::cast_from(fbits >> (F::SIG_BITS - I::BITS + 1))
374+
I::Unsigned::cast_from_lossy(fbits >> (F::SIG_BITS - I::BITS + 1))
375375
};
376376

377377
// Set the implicit 1-bit.

compiler-builtins/src/float/div.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ where
482482

483483
let ret = quotient.wrapping_shr(u32::cast_from(res_exponent.wrapping_neg()) + 1);
484484
residual_lo = a_significand
485-
.wrapping_shl(significand_bits.wrapping_add(CastInto::<u32>::cast(res_exponent)))
485+
.wrapping_shl(significand_bits.wrapping_add(CastInto::<u32>::cast_lossy(res_exponent)))
486486
.wrapping_sub(ret.wrapping_mul(b_significand) << 1);
487487
ret
488488
};

compiler-builtins/src/float/mul.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ where
143143
// a zero of the appropriate sign. Mathematically there is no need to
144144
// handle this case separately, but we make it a special case to
145145
// simplify the shift logic.
146-
let shift: u32 = one.wrapping_sub(product_exponent.cast()).cast();
146+
let shift: u32 = one.wrapping_sub(product_exponent.cast_lossy()).cast();
147147
if shift >= bits {
148148
return F::from_bits(product_sign);
149149
}

compiler-builtins/src/float/trunc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ where
5050
// The exponent of a is within the range of normal numbers in the
5151
// destination format. We can convert by simply right-shifting with
5252
// rounding and adjusting the exponent.
53-
abs_result = (a_abs >> sig_bits_delta).cast();
53+
abs_result = (a_abs >> sig_bits_delta).cast_lossy();
5454
// Cast before shifting to prevent overflow.
5555
let bias_diff: R::Int = src_exp_bias.wrapping_sub(dst_exp_bias).cast();
5656
let tmp = bias_diff << R::SIG_BITS;

compiler-builtins/src/int/trailing_zeros.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ mod implementation {
2020

2121
const { assert!(I::BITS <= 64) };
2222
if I::BITS >= 64 {
23-
r += ((u32::cast_from(x) == 0) as u32) << 5; // if (x has no 32 small bits) t = 32 else 0
23+
r += ((u32::cast_from_lossy(x) == 0) as u32) << 5; // if (x has no 32 small bits) t = 32 else 0
2424
x >>= r; // remove 32 zero bits
2525
}
2626

2727
if I::BITS >= 32 {
28-
t = ((u16::cast_from(x) == 0) as u32) << 4; // if (x has no 16 small bits) t = 16 else 0
28+
t = ((u16::cast_from_lossy(x) == 0) as u32) << 4; // if (x has no 16 small bits) t = 16 else 0
2929
r += t;
3030
x >>= t; // x = [0 - 0xFFFF] + higher garbage bits
3131
}
3232

3333
const { assert!(I::BITS >= 16) };
34-
t = ((u8::cast_from(x) == 0) as u32) << 3;
34+
t = ((u8::cast_from_lossy(x) == 0) as u32) << 3;
3535
x >>= t; // x = [0 - 0xFF] + higher garbage bits
3636
r += t;
3737

compiler-builtins/src/int/traits.rs

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pub use crate::support::{Int, MinInt};
1+
pub use crate::support::{CastFrom, CastInto, Int, MinInt};
22

33
/// Trait for integers twice the bit width of another integer. This is implemented for all
44
/// primitives except for `u8`, because there is not a smaller primitive.
@@ -97,44 +97,3 @@ impl_h_int!(
9797
i32 u32 i64,
9898
i64 u64 i128
9999
);
100-
101-
/// Trait to express (possibly lossy) casting of integers
102-
pub trait CastInto<T: Copy>: Copy {
103-
fn cast(self) -> T;
104-
}
105-
106-
pub trait CastFrom<T: Copy>: Copy {
107-
fn cast_from(value: T) -> Self;
108-
}
109-
110-
impl<T: Copy, U: CastInto<T> + Copy> CastFrom<U> for T {
111-
fn cast_from(value: U) -> Self {
112-
value.cast()
113-
}
114-
}
115-
116-
macro_rules! cast_into {
117-
($ty:ty) => {
118-
cast_into!($ty; usize, isize, u8, i8, u16, i16, u32, i32, u64, i64, u128, i128);
119-
};
120-
($ty:ty; $($into:ty),*) => {$(
121-
impl CastInto<$into> for $ty {
122-
fn cast(self) -> $into {
123-
self as $into
124-
}
125-
}
126-
)*};
127-
}
128-
129-
cast_into!(usize);
130-
cast_into!(isize);
131-
cast_into!(u8);
132-
cast_into!(i8);
133-
cast_into!(u16);
134-
cast_into!(i16);
135-
cast_into!(u32);
136-
cast_into!(i32);
137-
cast_into!(u64);
138-
cast_into!(i64);
139-
cast_into!(u128);
140-
cast_into!(i128);

libm/src/math/support/int_traits.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,14 +374,19 @@ impl_h_int!(
374374
/// Trait to express (possibly lossy) casting of integers
375375
pub trait CastInto<T: Copy>: Copy {
376376
/// By default, casts should be exact.
377+
#[track_caller]
377378
fn cast(self) -> T;
378379

379380
/// Call for casts that are expected to truncate.
381+
///
382+
/// In practice, this is exactly the same as `cast`; the main difference is to document intent
383+
/// in code. `cast` may panic in debug mode.
380384
fn cast_lossy(self) -> T;
381385
}
382386

383387
pub trait CastFrom<T: Copy>: Copy {
384388
/// By default, casts should be exact.
389+
#[track_caller]
385390
fn cast_from(value: T) -> Self;
386391

387392
/// Call for casts that are expected to truncate.

0 commit comments

Comments
 (0)