Skip to content

Commit 4bb3659

Browse files
committed
Auto merge of #2094 - dtolnay-contrib:truncate, r=RalfJung
Replace `as` casts in llvm.x86.addcarry.64 implementation Recommended in #2090 (review).
2 parents 49366ab + 8d42a7c commit 4bb3659

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

src/helpers.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
pub mod convert;
2+
13
use std::mem;
24
use std::num::NonZeroUsize;
35
use std::time::Duration;

src/helpers/convert.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use implementations::NarrowerThan;
2+
3+
/// Replacement for `as` casts going from wide integer to narrower integer.
4+
///
5+
/// # Example
6+
///
7+
/// ```ignore
8+
/// let x = 99_u64;
9+
/// let lo = x.truncate::<u16>();
10+
/// // lo is of type u16, equivalent to `x as u16`.
11+
/// ```
12+
pub(crate) trait Truncate: Sized {
13+
fn truncate<To>(self) -> To
14+
where
15+
To: NarrowerThan<Self>,
16+
{
17+
NarrowerThan::truncate_from(self)
18+
}
19+
}
20+
21+
impl Truncate for u16 {}
22+
impl Truncate for u32 {}
23+
impl Truncate for u64 {}
24+
impl Truncate for u128 {}
25+
26+
mod implementations {
27+
pub(crate) trait NarrowerThan<T> {
28+
fn truncate_from(wide: T) -> Self;
29+
}
30+
31+
macro_rules! impl_narrower_than {
32+
($(NarrowerThan<{$($ty:ty),*}> for $self:ty)*) => {
33+
$($(
34+
impl NarrowerThan<$ty> for $self {
35+
fn truncate_from(wide: $ty) -> Self {
36+
wide as Self
37+
}
38+
}
39+
)*)*
40+
};
41+
}
42+
43+
impl_narrower_than! {
44+
NarrowerThan<{u128, u64, u32, u16}> for u8
45+
NarrowerThan<{u128, u64, u32}> for u16
46+
NarrowerThan<{u128, u64}> for u32
47+
NarrowerThan<{u128}> for u64
48+
}
49+
}

src/shims/foreign_items.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc_target::{
2222
};
2323

2424
use super::backtrace::EvalContextExt as _;
25+
use crate::helpers::convert::Truncate;
2526
use crate::*;
2627

2728
/// Returned by `emulate_foreign_item_by_name`.
@@ -677,8 +678,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
677678
let a = this.read_scalar(a)?.to_u64()?;
678679
let b = this.read_scalar(b)?.to_u64()?;
679680

680-
let wide_sum = c_in as u128 + a as u128 + b as u128;
681-
let (c_out, sum) = ((wide_sum >> 64) as u8, wide_sum as u64);
681+
let wide_sum = u128::from(c_in) + u128::from(a) + u128::from(b);
682+
let (c_out, sum) = ((wide_sum >> 64).truncate::<u8>(), wide_sum.truncate::<u64>());
682683

683684
let c_out_field = this.place_field(dest, 0)?;
684685
this.write_scalar(Scalar::from_u8(c_out), &c_out_field)?;

0 commit comments

Comments
 (0)