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:
commit
27eb6d7018
1 changed files with 17 additions and 2 deletions
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue