diff options
| author | Ralf Jung <post@ralfj.de> | 2022-06-28 11:39:22 -0400 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2022-07-03 09:56:31 -0400 |
| commit | 595dd976bdcf54f9de336fcf4665d87e426ffc35 (patch) | |
| tree | b00a3c1b7efb0091ce4825d2c27aaffbcd28e40f | |
| parent | baf382e63c023259fa1f9042f8f479f183ca6ed3 (diff) | |
| download | rust-595dd976bdcf54f9de336fcf4665d87e426ffc35.tar.gz rust-595dd976bdcf54f9de336fcf4665d87e426ffc35.zip | |
interpret: don't rely on ScalarPair for overflowed arithmetic
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/operator.rs | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 85ee88e9e47..5d044a7fcd1 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -5,6 +5,7 @@ use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, Ty}; +use rustc_target::abi::Abi; use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy}; @@ -25,8 +26,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { "type mismatch for result of {:?}", op, ); - let val = Immediate::ScalarPair(val.into(), Scalar::from_bool(overflowed).into()); - self.write_immediate(val, dest) + if let Abi::ScalarPair(..) = dest.layout.abi { + // 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 { + // 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 |
