Skip to content

Commit 27eb6d7

Browse files
committed
Auto merge of #98627 - RalfJung:interpret-arith, r=lcnr
interpret: don't rely on ScalarPair for overflowed arithmetic This is for #97861. Cc `@eddyb` I would like to avoid making this depend on `dest.layout.abi` to avoid a branch that we are not usually covering both sides of. Though OTOH this seems like fairly straight-forward code. But let's benchmark this option first to see how bad that extra `force_allocation` really is.
2 parents 17581a7 + 0850bad commit 27eb6d7

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

compiler/rustc_const_eval/src/interpret/operator.rs

+17-2
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,22 @@ 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+
assert!(self.tcx.sess.opts.debugging_opts.randomize_layout);
36+
// With randomized layout, `(int, bool)` might cease to be a `ScalarPair`, so we have to
37+
// do a component-wise write here. This code path is slower than the above because
38+
// `place_field` will have to `force_allocate` locals here.
39+
let val_field = self.place_field(&dest, 0)?;
40+
self.write_scalar(val, &val_field)?;
41+
let overflowed_field = self.place_field(&dest, 1)?;
42+
self.write_scalar(Scalar::from_bool(overflowed), &overflowed_field)?;
43+
}
44+
Ok(())
3045
}
3146

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

0 commit comments

Comments
 (0)