Skip to content

Commit 595dd97

Browse files
committed
interpret: don't rely on ScalarPair for overflowed arithmetic
1 parent baf382e commit 595dd97

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

compiler/rustc_const_eval/src/interpret/operator.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_middle::mir;
55
use rustc_middle::mir::interpret::{InterpResult, Scalar};
66
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
77
use rustc_middle::ty::{self, FloatTy, Ty};
8+
use rustc_target::abi::Abi;
89

910
use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy};
1011

@@ -25,8 +26,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
2526
"type mismatch for result of {:?}",
2627
op,
2728
);
28-
let val = Immediate::ScalarPair(val.into(), Scalar::from_bool(overflowed).into());
29-
self.write_immediate(val, dest)
29+
if let Abi::ScalarPair(..) = dest.layout.abi {
30+
// We can use the optimized path and avoid `place_field` (which might do
31+
// `force_allocation`).
32+
let pair = Immediate::ScalarPair(val.into(), Scalar::from_bool(overflowed).into());
33+
self.write_immediate(pair, dest)?;
34+
} else {
35+
// With randomized layout, `(int, bool)` might cease to be a `ScalarPair`, so we have to
36+
// do a component-wise write here. This code path is slower than the above because
37+
// `place_field` will have to `force_allocate` locals here.
38+
let val_field = self.place_field(&dest, 0)?;
39+
self.write_scalar(val, &val_field)?;
40+
let overflowed_field = self.place_field(&dest, 1)?;
41+
self.write_scalar(Scalar::from_bool(overflowed), &overflowed_field)?;
42+
}
43+
Ok(())
3044
}
3145

3246
/// Applies the binary operation `op` to the arguments and writes the result to the

0 commit comments

Comments
 (0)