From 595dd976bdcf54f9de336fcf4665d87e426ffc35 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 28 Jun 2022 11:39:22 -0400 Subject: [PATCH 1/2] interpret: don't rely on ScalarPair for overflowed arithmetic --- .../rustc_const_eval/src/interpret/operator.rs | 18 ++++++++++++++++-- 1 file 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 85ee88e9e474e..5d044a7fcd169 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 From 0850bad94dab9499a6dde0f303a73220a21a2f71 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 4 Jul 2022 09:12:22 -0400 Subject: [PATCH 2/2] extra assertion, extra sure --- compiler/rustc_const_eval/src/interpret/operator.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 5d044a7fcd169..dec7fa8c4aa96 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -32,6 +32,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { 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.