1
Fork 0

Auto merge of #98627 - RalfJung:interpret-arith, r=lcnr

interpret: don't rely on ScalarPair for overflowed arithmetic

This is for https://github.com/rust-lang/rust/pull/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.
This commit is contained in:
bors 2022-07-04 20:00:41 +00:00
commit 27eb6d7018

View file

@ -5,6 +5,7 @@ use rustc_middle::mir;
use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::mir::interpret::{InterpResult, Scalar};
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::{self, FloatTy, Ty}; use rustc_middle::ty::{self, FloatTy, Ty};
use rustc_target::abi::Abi;
use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy}; use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy};
@ -25,8 +26,22 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
"type mismatch for result of {:?}", "type mismatch for result of {:?}",
op, op,
); );
let val = Immediate::ScalarPair(val.into(), Scalar::from_bool(overflowed).into()); if let Abi::ScalarPair(..) = dest.layout.abi {
self.write_immediate(val, dest) // We can use the optimized path and avoid `place_field` (which might do
// `force_allocation`).
let pair = Immediate::ScalarPair(val.into(), Scalar::from_bool(overflowed).into());
self.write_immediate(pair, dest)?;
} else {
assert!(self.tcx.sess.opts.debugging_opts.randomize_layout);
// With randomized layout, `(int, bool)` might cease to be a `ScalarPair`, so we have to
// do a component-wise write here. This code path is slower than the above because
// `place_field` will have to `force_allocate` locals here.
let val_field = self.place_field(&dest, 0)?;
self.write_scalar(val, &val_field)?;
let overflowed_field = self.place_field(&dest, 1)?;
self.write_scalar(Scalar::from_bool(overflowed), &overflowed_field)?;
}
Ok(())
} }
/// Applies the binary operation `op` to the arguments and writes the result to the /// Applies the binary operation `op` to the arguments and writes the result to the