From 60688500089f8e182e35f7ae540e9941734053a4 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 5 Aug 2023 12:27:58 -0700 Subject: rustdoc: fix test case for generics that look like names --- src/tools/rustdoc-js/tester.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 416517d15f5..c7e6dd3615e 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -23,7 +23,9 @@ function contentToDiffLine(key, value) { } function shouldIgnoreField(fieldName) { - return fieldName === "query" || fieldName === "correction"; + return fieldName === "query" || fieldName === "correction" || + fieldName === "proposeCorrectionFrom" || + fieldName === "proposeCorrectionTo"; } // This function is only called when no matching result was found and therefore will only display -- cgit 1.4.1-3-g733a5 From 68687e253597a9fee97b5cc638c93a1f90ee8097 Mon Sep 17 00:00:00 2001 From: Eduardo Sánchez Muñoz Date: Wed, 13 Sep 2023 19:41:21 +0200 Subject: rustc_middle: add `Scalar::from_i8` and `Scalar::from_i16` and use them in Miri --- compiler/rustc_middle/src/mir/interpret/value.rs | 10 ++++++++++ src/tools/miri/src/shims/x86/sse2.rs | 14 +++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'src/tools') diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 5345a658803..b6f399993d2 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -266,6 +266,16 @@ impl Scalar { .unwrap_or_else(|| bug!("Signed value {:#x} does not fit in {} bits", i, size.bits())) } + #[inline] + pub fn from_i8(i: i8) -> Self { + Self::from_int(i, Size::from_bits(8)) + } + + #[inline] + pub fn from_i16(i: i16) -> Self { + Self::from_int(i, Size::from_bits(16)) + } + #[inline] pub fn from_i32(i: i32) -> Self { Self::from_int(i, Size::from_bits(32)) diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 5b42339e648..0b918eab0c0 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -5,7 +5,6 @@ use rustc_apfloat::{ use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::Ty; use rustc_span::Symbol; -use rustc_target::abi::Size; use rustc_target::spec::abi::Abi; use super::FloatCmpOp; @@ -112,7 +111,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Values are expanded from i16 to i32, so multiplication cannot overflow. let res = i32::from(left).checked_mul(i32::from(right)).unwrap() >> 16; - this.write_scalar(Scalar::from_int(res, Size::from_bits(16)), &dest)?; + this.write_scalar(Scalar::from_i16(res.try_into().unwrap()), &dest)?; } } // Used to implement the _mm_mulhi_epu16 function. @@ -431,11 +430,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let right_res = i8::try_from(right).unwrap_or(if right < 0 { i8::MIN } else { i8::MAX }); - this.write_scalar(Scalar::from_int(left_res, Size::from_bits(8)), &left_dest)?; - this.write_scalar( - Scalar::from_int(right_res, Size::from_bits(8)), - &right_dest, - )?; + this.write_scalar(Scalar::from_i8(left_res.try_into().unwrap()), &left_dest)?; + this.write_scalar(Scalar::from_i8(right_res.try_into().unwrap()), &right_dest)?; } } // Used to implement the _mm_packus_epi16 function. @@ -495,9 +491,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let right_res = i16::try_from(right).unwrap_or(if right < 0 { i16::MIN } else { i16::MAX }); - this.write_scalar(Scalar::from_int(left_res, Size::from_bits(16)), &left_dest)?; + this.write_scalar(Scalar::from_i16(left_res.try_into().unwrap()), &left_dest)?; this.write_scalar( - Scalar::from_int(right_res, Size::from_bits(16)), + Scalar::from_i16(right_res.try_into().unwrap()), &right_dest, )?; } -- cgit 1.4.1-3-g733a5 From 21418429fdb9cc823253d47d5d87294230854489 Mon Sep 17 00:00:00 2001 From: Eduardo Sánchez Muñoz Date: Wed, 13 Sep 2023 20:17:59 +0200 Subject: miri: reduce code duplication in SSE/SSE2 bin_op_* functions --- compiler/rustc_middle/src/mir/interpret/value.rs | 12 +- src/tools/miri/src/helpers.rs | 17 +++ src/tools/miri/src/shims/intrinsics/simd.rs | 19 +-- src/tools/miri/src/shims/x86/mod.rs | 158 ++++++++++++++++++++++- src/tools/miri/src/shims/x86/sse.rs | 152 +--------------------- src/tools/miri/src/shims/x86/sse2.rs | 146 +-------------------- 6 files changed, 194 insertions(+), 310 deletions(-) (limited to 'src/tools') diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index b6f399993d2..f288869289c 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -503,16 +503,20 @@ impl<'tcx, Prov: Provenance> Scalar { Ok(i64::try_from(b).unwrap()) } + #[inline] + pub fn to_float(self) -> InterpResult<'tcx, F> { + // Going through `to_uint` to check size and truncation. + Ok(F::from_bits(self.to_uint(Size::from_bits(F::BITS))?)) + } + #[inline] pub fn to_f32(self) -> InterpResult<'tcx, Single> { - // Going through `u32` to check size and truncation. - Ok(Single::from_bits(self.to_u32()?.into())) + self.to_float() } #[inline] pub fn to_f64(self) -> InterpResult<'tcx, Double> { - // Going through `u64` to check size and truncation. - Ok(Double::from_bits(self.to_u64()?.into())) + self.to_float() } } diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 0c7e8278147..7805fe25bcd 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -1152,3 +1152,20 @@ pub fn get_local_crates(tcx: TyCtxt<'_>) -> Vec { pub fn target_os_is_unix(target_os: &str) -> bool { matches!(target_os, "linux" | "macos" | "freebsd" | "android") } + +pub(crate) fn bool_to_simd_element(b: bool, size: Size) -> Scalar { + // SIMD uses all-1 as pattern for "true". In two's complement, + // -1 has all its bits set to one and `from_int` will truncate or + // sign-extend it to `size` as required. + let val = if b { -1 } else { 0 }; + Scalar::from_int(val, size) +} + +pub(crate) fn simd_element_to_bool(elem: ImmTy<'_, Provenance>) -> InterpResult<'_, bool> { + let val = elem.to_scalar().to_int(elem.layout.size)?; + Ok(match val { + 0 => false, + -1 => true, + _ => throw_ub_format!("each element of a SIMD mask must be all-0-bits or all-1-bits"), + }) +} diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index dd8c4a4f6ec..626ead378e7 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -1,10 +1,10 @@ use rustc_apfloat::{Float, Round}; use rustc_middle::ty::layout::{HasParamEnv, LayoutOf}; use rustc_middle::{mir, ty, ty::FloatTy}; -use rustc_target::abi::{Endian, HasDataLayout, Size}; +use rustc_target::abi::{Endian, HasDataLayout}; use crate::*; -use helpers::check_arg_count; +use helpers::{bool_to_simd_element, check_arg_count, simd_element_to_bool}; impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { @@ -612,21 +612,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } -fn bool_to_simd_element(b: bool, size: Size) -> Scalar { - // SIMD uses all-1 as pattern for "true" - let val = if b { -1 } else { 0 }; - Scalar::from_int(val, size) -} - -fn simd_element_to_bool(elem: ImmTy<'_, Provenance>) -> InterpResult<'_, bool> { - let val = elem.to_scalar().to_int(elem.layout.size)?; - Ok(match val { - 0 => false, - -1 => true, - _ => throw_ub_format!("each element of a SIMD mask must be all-0-bits or all-1-bits"), - }) -} - fn simd_bitmask_index(idx: u32, vec_len: u32, endianness: Endian) -> u32 { assert!(idx < vec_len); match endianness { diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 62f5eb1baf7..ccc729aae1a 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -1,4 +1,8 @@ -use crate::InterpResult; +use rustc_middle::mir; +use rustc_target::abi::Size; + +use crate::*; +use helpers::bool_to_simd_element; pub(super) mod sse; pub(super) mod sse2; @@ -43,3 +47,155 @@ impl FloatCmpOp { } } } + +#[derive(Copy, Clone)] +enum FloatBinOp { + /// Arithmetic operation + Arith(mir::BinOp), + /// Comparison + Cmp(FloatCmpOp), + /// Minimum value (with SSE semantics) + /// + /// + /// + /// + /// + Min, + /// Maximum value (with SSE semantics) + /// + /// + /// + /// + /// + Max, +} + +/// Performs `which` scalar operation on `left` and `right` and returns +/// the result. +fn bin_op_float<'tcx, F: rustc_apfloat::Float>( + this: &crate::MiriInterpCx<'_, 'tcx>, + which: FloatBinOp, + left: &ImmTy<'tcx, Provenance>, + right: &ImmTy<'tcx, Provenance>, +) -> InterpResult<'tcx, Scalar> { + match which { + FloatBinOp::Arith(which) => { + let (res, _overflow, _ty) = this.overflowing_binary_op(which, left, right)?; + Ok(res) + } + FloatBinOp::Cmp(which) => { + let left = left.to_scalar().to_float::()?; + let right = right.to_scalar().to_float::()?; + // FIXME: Make sure that these operations match the semantics + // of cmpps/cmpss/cmppd/cmpsd + let res = match which { + FloatCmpOp::Eq => left == right, + FloatCmpOp::Lt => left < right, + FloatCmpOp::Le => left <= right, + FloatCmpOp::Unord => left.is_nan() || right.is_nan(), + FloatCmpOp::Neq => left != right, + FloatCmpOp::Nlt => !(left < right), + FloatCmpOp::Nle => !(left <= right), + FloatCmpOp::Ord => !left.is_nan() && !right.is_nan(), + }; + Ok(bool_to_simd_element(res, Size::from_bits(F::BITS))) + } + FloatBinOp::Min => { + let left_scalar = left.to_scalar(); + let left = left_scalar.to_float::()?; + let right_scalar = right.to_scalar(); + let right = right_scalar.to_float::()?; + // SSE semantics to handle zero and NaN. Note that `x == F::ZERO` + // is true when `x` is either +0 or -0. + if (left == F::ZERO && right == F::ZERO) + || left.is_nan() + || right.is_nan() + || left >= right + { + Ok(right_scalar) + } else { + Ok(left_scalar) + } + } + FloatBinOp::Max => { + let left_scalar = left.to_scalar(); + let left = left_scalar.to_float::()?; + let right_scalar = right.to_scalar(); + let right = right_scalar.to_float::()?; + // SSE semantics to handle zero and NaN. Note that `x == F::ZERO` + // is true when `x` is either +0 or -0. + if (left == F::ZERO && right == F::ZERO) + || left.is_nan() + || right.is_nan() + || left <= right + { + Ok(right_scalar) + } else { + Ok(left_scalar) + } + } + } +} + +/// Performs `which` operation on the first component of `left` and `right` +/// and copies the other components from `left`. The result is stored in `dest`. +fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>( + this: &mut crate::MiriInterpCx<'_, 'tcx>, + which: FloatBinOp, + left: &OpTy<'tcx, Provenance>, + right: &OpTy<'tcx, Provenance>, + dest: &PlaceTy<'tcx, Provenance>, +) -> InterpResult<'tcx, ()> { + let (left, left_len) = this.operand_to_simd(left)?; + let (right, right_len) = this.operand_to_simd(right)?; + let (dest, dest_len) = this.place_to_simd(dest)?; + + assert_eq!(dest_len, left_len); + assert_eq!(dest_len, right_len); + + let res0 = bin_op_float::( + this, + which, + &this.read_immediate(&this.project_index(&left, 0)?)?, + &this.read_immediate(&this.project_index(&right, 0)?)?, + )?; + this.write_scalar(res0, &this.project_index(&dest, 0)?)?; + + for i in 1..dest_len { + this.copy_op( + &this.project_index(&left, i)?, + &this.project_index(&dest, i)?, + /*allow_transmute*/ false, + )?; + } + + Ok(()) +} + +/// Performs `which` operation on each component of `left` and +/// `right`, storing the result is stored in `dest`. +fn bin_op_simd_float_all<'tcx, F: rustc_apfloat::Float>( + this: &mut crate::MiriInterpCx<'_, 'tcx>, + which: FloatBinOp, + left: &OpTy<'tcx, Provenance>, + right: &OpTy<'tcx, Provenance>, + dest: &PlaceTy<'tcx, Provenance>, +) -> InterpResult<'tcx, ()> { + let (left, left_len) = this.operand_to_simd(left)?; + let (right, right_len) = this.operand_to_simd(right)?; + let (dest, dest_len) = this.place_to_simd(dest)?; + + assert_eq!(dest_len, left_len); + assert_eq!(dest_len, right_len); + + for i in 0..dest_len { + let left = this.read_immediate(&this.project_index(&left, i)?)?; + let right = this.read_immediate(&this.project_index(&right, i)?)?; + let dest = this.project_index(&dest, i)?; + + let res = bin_op_float::(this, which, &left, &right)?; + this.write_scalar(res, &dest)?; + } + + Ok(()) +} diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index ff4bd369706..dcfe190a4ed 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -5,7 +5,7 @@ use rustc_target::spec::abi::Abi; use rand::Rng as _; -use super::FloatCmpOp; +use super::{bin_op_simd_float_all, bin_op_simd_float_first, FloatBinOp, FloatCmpOp}; use crate::*; use shims::foreign_items::EmulateByNameResult; @@ -45,7 +45,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { _ => unreachable!(), }; - bin_op_ss(this, which, left, right, dest)?; + bin_op_simd_float_first::(this, which, left, right, dest)?; } // Used to implement _mm_min_ps and _mm_max_ps functions. // Note that the semantics are a bit different from Rust simd_min @@ -62,7 +62,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { _ => unreachable!(), }; - bin_op_ps(this, which, left, right, dest)?; + bin_op_simd_float_all::(this, which, left, right, dest)?; } // Used to implement _mm_{sqrt,rcp,rsqrt}_ss functions. // Performs the operations on the first component of `op` and @@ -106,7 +106,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "llvm.x86.sse.cmp.ss", )?); - bin_op_ss(this, which, left, right, dest)?; + bin_op_simd_float_first::(this, which, left, right, dest)?; } // Used to implement the _mm_cmp_ps function. // Performs a comparison operation on each component of `left` @@ -121,7 +121,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "llvm.x86.sse.cmp.ps", )?); - bin_op_ps(this, which, left, right, dest)?; + bin_op_simd_float_all::(this, which, left, right, dest)?; } // Used to implement _mm_{,u}comi{eq,lt,le,gt,ge,neq}_ss functions. // Compares the first component of `left` and `right` and returns @@ -281,148 +281,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } -#[derive(Copy, Clone)] -enum FloatBinOp { - /// Arithmetic operation - Arith(mir::BinOp), - /// Comparison - Cmp(FloatCmpOp), - /// Minimum value (with SSE semantics) - /// - /// - /// - Min, - /// Maximum value (with SSE semantics) - /// - /// - /// - Max, -} - -/// Performs `which` scalar operation on `left` and `right` and returns -/// the result. -fn bin_op_f32<'tcx>( - this: &crate::MiriInterpCx<'_, 'tcx>, - which: FloatBinOp, - left: &ImmTy<'tcx, Provenance>, - right: &ImmTy<'tcx, Provenance>, -) -> InterpResult<'tcx, Scalar> { - match which { - FloatBinOp::Arith(which) => { - let (res, _, _) = this.overflowing_binary_op(which, left, right)?; - Ok(res) - } - FloatBinOp::Cmp(which) => { - let left = left.to_scalar().to_f32()?; - let right = right.to_scalar().to_f32()?; - // FIXME: Make sure that these operations match the semantics of cmpps - let res = match which { - FloatCmpOp::Eq => left == right, - FloatCmpOp::Lt => left < right, - FloatCmpOp::Le => left <= right, - FloatCmpOp::Unord => left.is_nan() || right.is_nan(), - FloatCmpOp::Neq => left != right, - FloatCmpOp::Nlt => !(left < right), - FloatCmpOp::Nle => !(left <= right), - FloatCmpOp::Ord => !left.is_nan() && !right.is_nan(), - }; - Ok(Scalar::from_u32(if res { u32::MAX } else { 0 })) - } - FloatBinOp::Min => { - let left = left.to_scalar().to_f32()?; - let right = right.to_scalar().to_f32()?; - // SSE semantics to handle zero and NaN. Note that `x == Single::ZERO` - // is true when `x` is either +0 or -0. - if (left == Single::ZERO && right == Single::ZERO) - || left.is_nan() - || right.is_nan() - || left >= right - { - Ok(Scalar::from_f32(right)) - } else { - Ok(Scalar::from_f32(left)) - } - } - FloatBinOp::Max => { - let left = left.to_scalar().to_f32()?; - let right = right.to_scalar().to_f32()?; - // SSE semantics to handle zero and NaN. Note that `x == Single::ZERO` - // is true when `x` is either +0 or -0. - if (left == Single::ZERO && right == Single::ZERO) - || left.is_nan() - || right.is_nan() - || left <= right - { - Ok(Scalar::from_f32(right)) - } else { - Ok(Scalar::from_f32(left)) - } - } - } -} - -/// Performs `which` operation on the first component of `left` and `right` -/// and copies the other components from `left`. The result is stored in `dest`. -fn bin_op_ss<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, - which: FloatBinOp, - left: &OpTy<'tcx, Provenance>, - right: &OpTy<'tcx, Provenance>, - dest: &PlaceTy<'tcx, Provenance>, -) -> InterpResult<'tcx, ()> { - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); - - let res0 = bin_op_f32( - this, - which, - &this.read_immediate(&this.project_index(&left, 0)?)?, - &this.read_immediate(&this.project_index(&right, 0)?)?, - )?; - this.write_scalar(res0, &this.project_index(&dest, 0)?)?; - - for i in 1..dest_len { - let left = this.read_immediate(&this.project_index(&left, i)?)?; - let dest = this.project_index(&dest, i)?; - - this.write_immediate(*left, &dest)?; - } - - Ok(()) -} - -/// Performs `which` operation on each component of `left` and -/// `right`, storing the result is stored in `dest`. -fn bin_op_ps<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, - which: FloatBinOp, - left: &OpTy<'tcx, Provenance>, - right: &OpTy<'tcx, Provenance>, - dest: &PlaceTy<'tcx, Provenance>, -) -> InterpResult<'tcx, ()> { - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); - - for i in 0..dest_len { - let left = this.read_immediate(&this.project_index(&left, i)?)?; - let right = this.read_immediate(&this.project_index(&right, i)?)?; - let dest = this.project_index(&dest, i)?; - - let res = bin_op_f32(this, which, &left, &right)?; - this.write_scalar(res, &dest)?; - } - - Ok(()) -} - #[derive(Copy, Clone)] enum FloatUnaryOp { /// sqrt(x) diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 0b918eab0c0..c6496fa195d 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::spec::abi::Abi; -use super::FloatCmpOp; +use super::{bin_op_simd_float_all, bin_op_simd_float_first, FloatBinOp, FloatCmpOp}; use crate::*; use shims::foreign_items::EmulateByNameResult; @@ -513,7 +513,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { _ => unreachable!(), }; - bin_op_sd(this, which, left, right, dest)?; + bin_op_simd_float_first::(this, which, left, right, dest)?; } // Used to implement _mm_min_pd and _mm_max_pd functions. // Note that the semantics are a bit different from Rust simd_min @@ -530,7 +530,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { _ => unreachable!(), }; - bin_op_pd(this, which, left, right, dest)?; + bin_op_simd_float_all::(this, which, left, right, dest)?; } // Used to implement _mm_sqrt_sd functions. // Performs the operations on the first component of `op` and @@ -589,7 +589,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "llvm.x86.sse2.cmp.sd", )?); - bin_op_sd(this, which, left, right, dest)?; + bin_op_simd_float_first::(this, which, left, right, dest)?; } // Used to implement the _mm_cmp*_pd functions. // Performs a comparison operation on each component of `left` @@ -604,7 +604,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "llvm.x86.sse2.cmp.pd", )?); - bin_op_pd(this, which, left, right, dest)?; + bin_op_simd_float_all::(this, which, left, right, dest)?; } // Used to implement _mm_{,u}comi{eq,lt,le,gt,ge,neq}_sd functions. // Compares the first component of `left` and `right` and returns @@ -840,139 +840,3 @@ fn extract_first_u64<'tcx>( // Get the first u64 from the array this.read_scalar(&this.project_index(&op, 0)?)?.to_u64() } - -#[derive(Copy, Clone)] -enum FloatBinOp { - /// Comparison - Cmp(FloatCmpOp), - /// Minimum value (with SSE semantics) - /// - /// - /// - Min, - /// Maximum value (with SSE semantics) - /// - /// - /// - Max, -} - -/// Performs `which` scalar operation on `left` and `right` and returns -/// the result. -// FIXME make this generic over apfloat type to reduce code duplicaton with bin_op_f32 -fn bin_op_f64<'tcx>( - which: FloatBinOp, - left: &ImmTy<'tcx, Provenance>, - right: &ImmTy<'tcx, Provenance>, -) -> InterpResult<'tcx, Scalar> { - match which { - FloatBinOp::Cmp(which) => { - let left = left.to_scalar().to_f64()?; - let right = right.to_scalar().to_f64()?; - // FIXME: Make sure that these operations match the semantics of cmppd - let res = match which { - FloatCmpOp::Eq => left == right, - FloatCmpOp::Lt => left < right, - FloatCmpOp::Le => left <= right, - FloatCmpOp::Unord => left.is_nan() || right.is_nan(), - FloatCmpOp::Neq => left != right, - FloatCmpOp::Nlt => !(left < right), - FloatCmpOp::Nle => !(left <= right), - FloatCmpOp::Ord => !left.is_nan() && !right.is_nan(), - }; - Ok(Scalar::from_u64(if res { u64::MAX } else { 0 })) - } - FloatBinOp::Min => { - let left = left.to_scalar().to_f64()?; - let right = right.to_scalar().to_f64()?; - // SSE semantics to handle zero and NaN. Note that `x == Single::ZERO` - // is true when `x` is either +0 or -0. - if (left == Double::ZERO && right == Double::ZERO) - || left.is_nan() - || right.is_nan() - || left >= right - { - Ok(Scalar::from_f64(right)) - } else { - Ok(Scalar::from_f64(left)) - } - } - FloatBinOp::Max => { - let left = left.to_scalar().to_f64()?; - let right = right.to_scalar().to_f64()?; - // SSE semantics to handle zero and NaN. Note that `x == Single::ZERO` - // is true when `x` is either +0 or -0. - if (left == Double::ZERO && right == Double::ZERO) - || left.is_nan() - || right.is_nan() - || left <= right - { - Ok(Scalar::from_f64(right)) - } else { - Ok(Scalar::from_f64(left)) - } - } - } -} - -/// Performs `which` operation on the first component of `left` and `right` -/// and copies the other components from `left`. The result is stored in `dest`. -fn bin_op_sd<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, - which: FloatBinOp, - left: &OpTy<'tcx, Provenance>, - right: &OpTy<'tcx, Provenance>, - dest: &PlaceTy<'tcx, Provenance>, -) -> InterpResult<'tcx, ()> { - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); - - let res0 = bin_op_f64( - which, - &this.read_immediate(&this.project_index(&left, 0)?)?, - &this.read_immediate(&this.project_index(&right, 0)?)?, - )?; - this.write_scalar(res0, &this.project_index(&dest, 0)?)?; - - for i in 1..dest_len { - this.copy_op( - &this.project_index(&left, i)?, - &this.project_index(&dest, i)?, - /*allow_transmute*/ false, - )?; - } - - Ok(()) -} - -/// Performs `which` operation on each component of `left` and -/// `right`, storing the result is stored in `dest`. -fn bin_op_pd<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, - which: FloatBinOp, - left: &OpTy<'tcx, Provenance>, - right: &OpTy<'tcx, Provenance>, - dest: &PlaceTy<'tcx, Provenance>, -) -> InterpResult<'tcx, ()> { - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); - - for i in 0..dest_len { - let left = this.read_immediate(&this.project_index(&left, i)?)?; - let right = this.read_immediate(&this.project_index(&right, i)?)?; - let dest = this.project_index(&dest, i)?; - - let res = bin_op_f64(which, &left, &right)?; - this.write_scalar(res, &dest)?; - } - - Ok(()) -} -- cgit 1.4.1-3-g733a5 From 98310bed8e09817e518e6b82fcb3f9b2c4b89675 Mon Sep 17 00:00:00 2001 From: Eduardo Sánchez Muñoz Date: Wed, 13 Sep 2023 20:30:24 +0200 Subject: miri: reduce code duplication in SSE cvtsi2ss/cvtsi642ss --- src/tools/miri/src/shims/x86/sse.rs | 49 +++++++++---------------------------- 1 file changed, 12 insertions(+), 37 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index dcfe190a4ed..ab90e292fcb 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -204,12 +204,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_scalar(res, dest)?; } - // Used to implement the _mm_cvtsi32_ss function. - // Converts `right` from i32 to f32. Returns a SIMD vector with + // Used to implement the _mm_cvtsi32_ss and _mm_cvtsi64_ss functions. + // Converts `right` from i32/i64 to f32. Returns a SIMD vector with // the result in the first component and the remaining components // are copied from `left`. // https://www.felixcloutier.com/x86/cvtsi2ss - "cvtsi2ss" => { + "cvtsi2ss" | "cvtsi642ss" => { let [left, right] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; @@ -218,42 +218,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { assert_eq!(dest_len, left_len); - let right = this.read_scalar(right)?.to_i32()?; - - let res0 = Scalar::from_f32(Single::from_i128(right.into()).value); - this.write_scalar(res0, &this.project_index(&dest, 0)?)?; + let right = this.read_immediate(right)?; + let dest0 = this.project_index(&dest, 0)?; + let res0 = this.int_to_int_or_float(&right, dest0.layout.ty)?; + this.write_immediate(res0, &dest0)?; for i in 1..dest_len { - let left = this.read_immediate(&this.project_index(&left, i)?)?; - let dest = this.project_index(&dest, i)?; - - this.write_immediate(*left, &dest)?; - } - } - // Used to implement the _mm_cvtsi64_ss function. - // Converts `right` from i64 to f32. Returns a SIMD vector with - // the result in the first component and the remaining components - // are copied from `left`. - // https://www.felixcloutier.com/x86/cvtsi2ss - "cvtsi642ss" => { - let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - - let (left, left_len) = this.operand_to_simd(left)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - - let right = this.read_scalar(right)?.to_i64()?; - - let res0 = Scalar::from_f32(Single::from_i128(right.into()).value); - this.write_scalar(res0, &this.project_index(&dest, 0)?)?; - - for i in 1..dest_len { - let left = this.read_immediate(&this.project_index(&left, i)?)?; - let dest = this.project_index(&dest, i)?; - - this.write_immediate(*left, &dest)?; + this.copy_op( + &this.project_index(&left, i)?, + &this.project_index(&dest, i)?, + /*allow_transmute*/ false, + )?; } } // Used to implement the _mm_movemask_ps function. -- cgit 1.4.1-3-g733a5 From ff685416dbb52367df5e8d32ae95bea49a10f229 Mon Sep 17 00:00:00 2001 From: Eduardo Sánchez Muñoz Date: Wed, 13 Sep 2023 20:34:03 +0200 Subject: miri: use `copy_op` in `unary_op_ss` --- src/tools/miri/src/shims/x86/sse.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index ab90e292fcb..05717216636 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -343,10 +343,11 @@ fn unary_op_ss<'tcx>( this.write_scalar(res0, &this.project_index(&dest, 0)?)?; for i in 1..dest_len { - let op = this.read_immediate(&this.project_index(&op, i)?)?; - let dest = this.project_index(&dest, i)?; - - this.write_immediate(*op, &dest)?; + this.copy_op( + &this.project_index(&op, i)?, + &this.project_index(&dest, i)?, + /*allow_transmute*/ false, + )?; } Ok(()) -- cgit 1.4.1-3-g733a5 From 9bd648bf130a2dfb7b7f386cbc6ad33f33c8b4d0 Mon Sep 17 00:00:00 2001 From: Eduardo Sánchez Muñoz Date: Wed, 13 Sep 2023 20:50:18 +0200 Subject: miri: reduce code duplication in SSE/SSE2 cvt{,t}s{s,d}2si{,64} --- src/tools/miri/src/shims/x86/sse.rs | 38 +++++++----------------------------- src/tools/miri/src/shims/x86/sse2.rs | 38 +++++++----------------------------- 2 files changed, 14 insertions(+), 62 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index 05717216636..30ad088206a 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -154,9 +154,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }; this.write_scalar(Scalar::from_i32(i32::from(res)), dest)?; } - // Use to implement _mm_cvtss_si32 and _mm_cvttss_si32. - // Converts the first component of `op` from f32 to i32. - "cvtss2si" | "cvttss2si" => { + // Use to implement the _mm_cvtss_si32, _mm_cvttss_si32, + // _mm_cvtss_si64 and _mm_cvttss_si64 functions. + // Converts the first component of `op` from f32 to i32/i64. + "cvtss2si" | "cvttss2si" | "cvtss2si64" | "cvttss2si64" => { let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let (op, _) = this.operand_to_simd(op)?; @@ -165,41 +166,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let rnd = match unprefixed_name { // "current SSE rounding mode", assume nearest // https://www.felixcloutier.com/x86/cvtss2si - "cvtss2si" => rustc_apfloat::Round::NearestTiesToEven, + "cvtss2si" | "cvtss2si64" => rustc_apfloat::Round::NearestTiesToEven, // always truncate // https://www.felixcloutier.com/x86/cvttss2si - "cvttss2si" => rustc_apfloat::Round::TowardZero, + "cvttss2si" | "cvttss2si64" => rustc_apfloat::Round::TowardZero, _ => unreachable!(), }; let res = this.float_to_int_checked(op, dest.layout.ty, rnd).unwrap_or_else(|| { // Fallback to minimum acording to SSE semantics. - Scalar::from_i32(i32::MIN) - }); - - this.write_scalar(res, dest)?; - } - // Use to implement _mm_cvtss_si64 and _mm_cvttss_si64. - // Converts the first component of `op` from f32 to i64. - "cvtss2si64" | "cvttss2si64" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let (op, _) = this.operand_to_simd(op)?; - - let op = this.read_scalar(&this.project_index(&op, 0)?)?.to_f32()?; - - let rnd = match unprefixed_name { - // "current SSE rounding mode", assume nearest - // https://www.felixcloutier.com/x86/cvtss2si - "cvtss2si64" => rustc_apfloat::Round::NearestTiesToEven, - // always truncate - // https://www.felixcloutier.com/x86/cvttss2si - "cvttss2si64" => rustc_apfloat::Round::TowardZero, - _ => unreachable!(), - }; - - let res = this.float_to_int_checked(op, dest.layout.ty, rnd).unwrap_or_else(|| { - // Fallback to minimum acording to SSE semantics. - Scalar::from_i64(i64::MIN) + Scalar::from_int(dest.layout.size.signed_int_min(), dest.layout.size) }); this.write_scalar(res, dest)?; diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index c6496fa195d..d2370d3c1f2 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -722,9 +722,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_scalar(Scalar::from_i32(0), &dest)?; } } - // Use to implement the _mm_cvtsd_si32 and _mm_cvttsd_si32 functions. - // Converts the first component of `op` from f64 to i32. - "cvtsd2si" | "cvttsd2si" => { + // Use to implement the _mm_cvtsd_si32, _mm_cvttsd_si32, + // _mm_cvtsd_si64 and _mm_cvttsd_si64 functions. + // Converts the first component of `op` from f64 to i32/i64. + "cvtsd2si" | "cvttsd2si" | "cvtsd2si64" | "cvttsd2si64" => { let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let (op, _) = this.operand_to_simd(op)?; @@ -733,41 +734,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let rnd = match unprefixed_name { // "current SSE rounding mode", assume nearest // https://www.felixcloutier.com/x86/cvtsd2si - "cvtsd2si" => rustc_apfloat::Round::NearestTiesToEven, + "cvtsd2si" | "cvtsd2si64" => rustc_apfloat::Round::NearestTiesToEven, // always truncate // https://www.felixcloutier.com/x86/cvttsd2si - "cvttsd2si" => rustc_apfloat::Round::TowardZero, + "cvttsd2si" | "cvttsd2si64" => rustc_apfloat::Round::TowardZero, _ => unreachable!(), }; let res = this.float_to_int_checked(op, dest.layout.ty, rnd).unwrap_or_else(|| { // Fallback to minimum acording to SSE semantics. - Scalar::from_i32(i32::MIN) - }); - - this.write_scalar(res, dest)?; - } - // Use to implement the _mm_cvtsd_si64 and _mm_cvttsd_si64 functions. - // Converts the first component of `op` from f64 to i64. - "cvtsd2si64" | "cvttsd2si64" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let (op, _) = this.operand_to_simd(op)?; - - let op = this.read_scalar(&this.project_index(&op, 0)?)?.to_f64()?; - - let rnd = match unprefixed_name { - // "current SSE rounding mode", assume nearest - // https://www.felixcloutier.com/x86/cvtsd2si - "cvtsd2si64" => rustc_apfloat::Round::NearestTiesToEven, - // always truncate - // https://www.felixcloutier.com/x86/cvttsd2si - "cvttsd2si64" => rustc_apfloat::Round::TowardZero, - _ => unreachable!(), - }; - - let res = this.float_to_int_checked(op, dest.layout.ty, rnd).unwrap_or_else(|| { - // Fallback to minimum acording to SSE semantics. - Scalar::from_i64(i64::MIN) + Scalar::from_int(dest.layout.size.signed_int_min(), dest.layout.size) }); this.write_scalar(res, dest)?; -- cgit 1.4.1-3-g733a5 From e634c188dd4089320a5ca8a99683d8a1f084c3e0 Mon Sep 17 00:00:00 2001 From: Eduardo Sánchez Muñoz Date: Wed, 13 Sep 2023 21:02:11 +0200 Subject: miri: reduce code duplication in SSE2 cvtpd2ps/cvtps2pd --- src/tools/miri/src/shims/x86/sse2.rs | 49 +++++++++++------------------------- 1 file changed, 14 insertions(+), 35 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index d2370d3c1f2..a0280fd0122 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -1,6 +1,6 @@ use rustc_apfloat::{ ieee::{Double, Single}, - Float as _, FloatConvert as _, + Float as _, }; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::Ty; @@ -637,51 +637,30 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }; this.write_scalar(Scalar::from_i32(i32::from(res)), dest)?; } - // Used to implement the _mm_cvtpd_ps function. - // Converts packed f32 to packed f64. - "cvtpd2ps" => { + // Used to implement the _mm_cvtpd_ps and _mm_cvtps_pd functions. + // Converts packed f32/f64 to packed f64/f32. + "cvtpd2ps" | "cvtps2pd" => { let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let (op, op_len) = this.operand_to_simd(op)?; let (dest, dest_len) = this.place_to_simd(dest)?; - // op is f64x2, dest is f32x4 - assert_eq!(op_len, 2); - assert_eq!(dest_len, 4); - - for i in 0..op_len { - let op = this.read_scalar(&this.project_index(&op, i)?)?.to_f64()?; + // For cvtpd2ps: op is f64x2, dest is f32x4 + // For cvtps2pd: op is f32x4, dest is f64x2 + // In either case, the two first values are converted + for i in 0..op_len.min(dest_len) { + let op = this.read_immediate(&this.project_index(&op, i)?)?; let dest = this.project_index(&dest, i)?; - let res = op.convert(/*loses_info*/ &mut false).value; - this.write_scalar(Scalar::from_f32(res), &dest)?; + let res = this.float_to_float_or_int(&op, dest.layout.ty)?; + this.write_immediate(res, &dest)?; } - // Fill the remaining with zeros + // For f32 -> f64, ignore the remaining + // For f64 -> f32, fill the remaining with zeros for i in op_len..dest_len { let dest = this.project_index(&dest, i)?; - this.write_scalar(Scalar::from_u32(0), &dest)?; - } - } - // Used to implement the _mm_cvtps_pd function. - // Converts packed f64 to packed f32. - "cvtps2pd" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - - let (op, op_len) = this.operand_to_simd(op)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - // op is f32x4, dest is f64x2 - assert_eq!(op_len, 4); - assert_eq!(dest_len, 2); - - for i in 0..dest_len { - let op = this.read_scalar(&this.project_index(&op, i)?)?.to_f32()?; - let dest = this.project_index(&dest, i)?; - - let res = op.convert(/*loses_info*/ &mut false).value; - this.write_scalar(Scalar::from_f64(res), &dest)?; + this.write_scalar(Scalar::from_int(0, dest.layout.size), &dest)?; } - // the two remaining f32 are ignored } // Used to implement the _mm_cvtpd_epi32 and _mm_cvttpd_epi32 functions. // Converts packed f64 to packed i32. -- cgit 1.4.1-3-g733a5 From 4bb8a8b804d89902c2cf9be0446605306d1f22df Mon Sep 17 00:00:00 2001 From: Eduardo Sánchez Muñoz Date: Wed, 13 Sep 2023 21:03:07 +0200 Subject: miri: fix comment --- src/tools/miri/src/shims/x86/sse2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index a0280fd0122..098409d6e35 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -465,7 +465,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } // Used to implement the _mm_packs_epi32 function. - // Converts two 16-bit integer vectors to a single 8-bit integer + // Converts two 32-bit integer vectors to a single 16-bit integer // vector with signed saturation. "packssdw.128" => { let [left, right] = -- cgit 1.4.1-3-g733a5 From 8d590f2fa84c0bb7bf423dfc3ea64b229e2f7346 Mon Sep 17 00:00:00 2001 From: Eduardo Sánchez Muñoz Date: Wed, 13 Sep 2023 21:51:40 +0200 Subject: miri: reduce code duplication in SSE2 pavg.b and pavg.w --- src/tools/miri/src/helpers.rs | 20 +++++++++- src/tools/miri/src/shims/x86/sse2.rs | 74 +++++++++++++++++------------------- 2 files changed, 54 insertions(+), 40 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 7805fe25bcd..bbd905be0a9 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -14,7 +14,7 @@ use rustc_middle::mir; use rustc_middle::ty::{ self, layout::{IntegerExt as _, LayoutOf, TyAndLayout}, - Ty, TyCtxt, + IntTy, Ty, TyCtxt, UintTy, }; use rustc_span::{def_id::CrateNum, sym, Span, Symbol}; use rustc_target::abi::{Align, FieldIdx, FieldsShape, Integer, Size, Variants}; @@ -1067,6 +1067,24 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ), } } + + /// Returns an integer type that is twice wide as `ty` + fn get_twice_wide_int_ty(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + let this = self.eval_context_ref(); + match ty.kind() { + // Unsigned + ty::Uint(UintTy::U8) => this.tcx.types.u16, + ty::Uint(UintTy::U16) => this.tcx.types.u32, + ty::Uint(UintTy::U32) => this.tcx.types.u64, + ty::Uint(UintTy::U64) => this.tcx.types.u128, + // Signed + ty::Int(IntTy::I8) => this.tcx.types.i16, + ty::Int(IntTy::I16) => this.tcx.types.i32, + ty::Int(IntTy::I32) => this.tcx.types.i64, + ty::Int(IntTy::I64) => this.tcx.types.i128, + _ => span_bug!(this.cur_span(), "unexpected type: {ty:?}"), + } + } } impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 098409d6e35..28aebc8cba8 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -2,6 +2,7 @@ use rustc_apfloat::{ ieee::{Double, Single}, Float as _, }; +use rustc_middle::mir; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::Ty; use rustc_span::Symbol; @@ -36,9 +37,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Intrinsincs sufixed with "epiX" or "epuX" operate with X-bit signed or unsigned // vectors. match unprefixed_name { - // Used to implement the _mm_avg_epu8 function. - // Averages packed unsigned 8-bit integers in `left` and `right`. - "pavg.b" => { + // Used to implement the _mm_avg_epu8 and _mm_avg_epu16 functions. + // Averages packed unsigned 8/16-bit integers in `left` and `right`. + "pavg.b" | "pavg.w" => { let [left, right] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; @@ -50,46 +51,41 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { assert_eq!(dest_len, right_len); for i in 0..dest_len { - let left = this.read_scalar(&this.project_index(&left, i)?)?.to_u8()?; - let right = this.read_scalar(&this.project_index(&right, i)?)?.to_u8()?; + let left = this.read_immediate(&this.project_index(&left, i)?)?; + let right = this.read_immediate(&this.project_index(&right, i)?)?; let dest = this.project_index(&dest, i)?; - // Values are expanded from u8 to u16, so adds cannot overflow. - let res = u16::from(left) - .checked_add(u16::from(right)) - .unwrap() - .checked_add(1) - .unwrap() - / 2; - this.write_scalar(Scalar::from_u8(res.try_into().unwrap()), &dest)?; - } - } - // Used to implement the _mm_avg_epu16 function. - // Averages packed unsigned 16-bit integers in `left` and `right`. - "pavg.w" => { - let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); + // Widen the operands to avoid overflow + let twice_wide_ty = this.get_twice_wide_int_ty(left.layout.ty); + let twice_wide_layout = this.layout_of(twice_wide_ty)?; + let left = this.int_to_int_or_float(&left, twice_wide_ty)?; + let right = this.int_to_int_or_float(&right, twice_wide_ty)?; + + // Calculate left + right + 1 + let (added, _overflow, _ty) = this.overflowing_binary_op( + mir::BinOp::Add, + &ImmTy::from_immediate(left, twice_wide_layout), + &ImmTy::from_immediate(right, twice_wide_layout), + )?; + let (added, _overflow, _ty) = this.overflowing_binary_op( + mir::BinOp::Add, + &ImmTy::from_scalar(added, twice_wide_layout), + &ImmTy::from_uint(1u32, twice_wide_layout), + )?; - for i in 0..dest_len { - let left = this.read_scalar(&this.project_index(&left, i)?)?.to_u16()?; - let right = this.read_scalar(&this.project_index(&right, i)?)?.to_u16()?; - let dest = this.project_index(&dest, i)?; + // Calculate (left + right + 1) / 2 + let (divided, _overflow, _ty) = this.overflowing_binary_op( + mir::BinOp::Div, + &ImmTy::from_scalar(added, twice_wide_layout), + &ImmTy::from_uint(2u32, twice_wide_layout), + )?; - // Values are expanded from u16 to u32, so adds cannot overflow. - let res = u32::from(left) - .checked_add(u32::from(right)) - .unwrap() - .checked_add(1) - .unwrap() - / 2; - this.write_scalar(Scalar::from_u16(res.try_into().unwrap()), &dest)?; + // Narrow back to the original type + let res = this.int_to_int_or_float( + &ImmTy::from_scalar(divided, twice_wide_layout), + dest.layout.ty, + )?; + this.write_immediate(res, &dest)?; } } // Used to implement the _mm_mulhi_epi16 function. -- cgit 1.4.1-3-g733a5 From 9fbbfd2e396a2d1c66168af9db80a806bcc5a32a Mon Sep 17 00:00:00 2001 From: Eduardo Sánchez Muñoz Date: Wed, 13 Sep 2023 21:58:28 +0200 Subject: miri: reduce code duplication in SSE2 pmulh.w and pmulhu.w Not really a saving in terms of lines of code, but at least the logic is de-duplicated --- src/tools/miri/src/shims/x86/sse2.rs | 54 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 28aebc8cba8..b68690a835c 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -88,8 +88,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_immediate(res, &dest)?; } } - // Used to implement the _mm_mulhi_epi16 function. - "pmulh.w" => { + // Used to implement the _mm_mulhi_epi16 and _mm_mulhi_epu16 functions. + "pmulh.w" | "pmulhu.w" => { let [left, right] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; @@ -101,35 +101,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { assert_eq!(dest_len, right_len); for i in 0..dest_len { - let left = this.read_scalar(&this.project_index(&left, i)?)?.to_i16()?; - let right = this.read_scalar(&this.project_index(&right, i)?)?.to_i16()?; + let left = this.read_immediate(&this.project_index(&left, i)?)?; + let right = this.read_immediate(&this.project_index(&right, i)?)?; let dest = this.project_index(&dest, i)?; - // Values are expanded from i16 to i32, so multiplication cannot overflow. - let res = i32::from(left).checked_mul(i32::from(right)).unwrap() >> 16; - this.write_scalar(Scalar::from_i16(res.try_into().unwrap()), &dest)?; - } - } - // Used to implement the _mm_mulhi_epu16 function. - "pmulhu.w" => { - let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - - let (left, left_len) = this.operand_to_simd(left)?; - let (right, right_len) = this.operand_to_simd(right)?; - let (dest, dest_len) = this.place_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); + // Widen the operands to avoid overflow + let twice_wide_ty = this.get_twice_wide_int_ty(left.layout.ty); + let twice_wide_layout = this.layout_of(twice_wide_ty)?; + let left = this.int_to_int_or_float(&left, twice_wide_ty)?; + let right = this.int_to_int_or_float(&right, twice_wide_ty)?; - for i in 0..dest_len { - let left = this.read_scalar(&this.project_index(&left, i)?)?.to_u16()?; - let right = this.read_scalar(&this.project_index(&right, i)?)?.to_u16()?; - let dest = this.project_index(&dest, i)?; + // Multiply + let (multiplied, _overflow, _ty) = this.overflowing_binary_op( + mir::BinOp::Mul, + &ImmTy::from_immediate(left, twice_wide_layout), + &ImmTy::from_immediate(right, twice_wide_layout), + )?; + // Keep the high half + let (high, _overflow, _ty) = this.overflowing_binary_op( + mir::BinOp::Shr, + &ImmTy::from_scalar(multiplied, twice_wide_layout), + &ImmTy::from_uint(dest.layout.size.bits(), twice_wide_layout), + )?; - // Values are expanded from u16 to u32, so multiplication cannot overflow. - let res = u32::from(left).checked_mul(u32::from(right)).unwrap() >> 16; - this.write_scalar(Scalar::from_u16(res.try_into().unwrap()), &dest)?; + // Narrow back to the original type + let res = this.int_to_int_or_float( + &ImmTy::from_scalar(high, twice_wide_layout), + dest.layout.ty, + )?; + this.write_immediate(res, &dest)?; } } // Used to implement the _mm_mul_epu32 function. -- cgit 1.4.1-3-g733a5 From 5a0a1ff0cdb37ffb5fe970a4bcbde9df4ef1d602 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 16 Sep 2023 09:36:22 +0200 Subject: move ConstValue into mir this way we have mir::ConstValue and ty::ValTree as reasonably parallel --- compiler/rustc_codegen_cranelift/src/constant.rs | 3 +- compiler/rustc_codegen_ssa/src/common.rs | 6 +- compiler/rustc_codegen_ssa/src/mir/constant.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/operand.rs | 6 +- .../src/const_eval/eval_queries.rs | 7 +- compiler/rustc_const_eval/src/const_eval/mod.rs | 8 +- .../rustc_const_eval/src/const_eval/valtrees.rs | 13 +- .../rustc_const_eval/src/interpret/intrinsics.rs | 6 +- compiler/rustc_const_eval/src/interpret/operand.rs | 15 +- compiler/rustc_const_eval/src/interpret/place.rs | 9 +- compiler/rustc_middle/src/mir/consts.rs | 165 ++++++++++++++++++++- compiler/rustc_middle/src/mir/interpret/error.rs | 4 +- compiler/rustc_middle/src/mir/interpret/mod.rs | 2 +- compiler/rustc_middle/src/mir/interpret/value.rs | 158 +------------------- compiler/rustc_middle/src/mir/mod.rs | 2 +- compiler/rustc_middle/src/mir/pretty.rs | 4 +- compiler/rustc_middle/src/mir/query.rs | 3 +- compiler/rustc_middle/src/query/erase.rs | 16 +- compiler/rustc_middle/src/query/keys.rs | 5 +- compiler/rustc_middle/src/query/mod.rs | 8 +- .../src/build/custom/parse/instruction.rs | 2 +- .../rustc_mir_build/src/build/expr/as_constant.rs | 4 +- compiler/rustc_mir_build/src/build/mod.rs | 1 - compiler/rustc_mir_build/src/thir/pattern/mod.rs | 6 +- .../rustc_mir_transform/src/check_alignment.rs | 2 +- compiler/rustc_mir_transform/src/const_prop.rs | 4 +- .../rustc_mir_transform/src/dataflow_const_prop.rs | 2 +- compiler/rustc_mir_transform/src/large_enums.rs | 2 +- compiler/rustc_mir_transform/src/remove_zsts.rs | 1 - compiler/rustc_monomorphize/src/collector.rs | 13 +- compiler/rustc_smir/src/rustc_smir/alloc.rs | 5 +- src/librustdoc/clean/utils.rs | 9 +- src/tools/clippy/clippy_utils/src/consts.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 2 +- 34 files changed, 245 insertions(+), 254 deletions(-) (limited to 'src/tools') diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 0d9bd3cf240..02468684ba0 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -2,7 +2,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc_middle::mir::interpret::{read_target_uint, AllocId, ConstValue, GlobalAlloc, Scalar}; +use rustc_middle::mir::interpret::{read_target_uint, AllocId, GlobalAlloc, Scalar}; +use rustc_middle::mir::ConstValue; use cranelift_module::*; diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 5a68075991f..641ac3eb808 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -1,7 +1,7 @@ #![allow(non_camel_case_types)] use rustc_hir::LangItem; -use rustc_middle::mir::interpret::ConstValue; +use rustc_middle::mir; use rustc_middle::ty::{self, layout::TyAndLayout, Ty, TyCtxt}; use rustc_span::Span; @@ -194,10 +194,10 @@ pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( pub fn asm_const_to_str<'tcx>( tcx: TyCtxt<'tcx>, sp: Span, - const_value: ConstValue<'tcx>, + const_value: mir::ConstValue<'tcx>, ty_and_layout: TyAndLayout<'tcx>, ) -> String { - let ConstValue::Scalar(scalar) = const_value else { + let mir::ConstValue::Scalar(scalar) = const_value else { span_bug!(sp, "expected Scalar for promoted asm const, but got {:#?}", const_value) }; let value = scalar.assert_bits(ty_and_layout.size); diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 263b41ed880..7fec4047a95 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -2,7 +2,7 @@ use crate::errors; use crate::mir::operand::OperandRef; use crate::traits::*; use rustc_middle::mir; -use rustc_middle::mir::interpret::{ConstValue, ErrorHandled}; +use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::{self, Ty}; use rustc_target::abi::Abi; @@ -20,7 +20,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandRef::from_const(bx, val, ty) } - pub fn eval_mir_constant(&self, constant: &mir::Constant<'tcx>) -> ConstValue<'tcx> { + pub fn eval_mir_constant(&self, constant: &mir::Constant<'tcx>) -> mir::ConstValue<'tcx> { self.monomorphize(constant.literal) .eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), Some(constant.span)) .expect("erroneous constant not captured by required_consts") diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index e192d16ff38..926a0bed0da 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -6,8 +6,8 @@ use crate::glue; use crate::traits::*; use crate::MemFlags; -use rustc_middle::mir; -use rustc_middle::mir::interpret::{alloc_range, ConstValue, Pointer, Scalar}; +use rustc_middle::mir::interpret::{alloc_range, Pointer, Scalar}; +use rustc_middle::mir::{self, ConstValue}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::Ty; use rustc_target::abi::{self, Abi, Align, Size}; @@ -86,7 +86,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { pub fn from_const>( bx: &mut Bx, - val: ConstValue<'tcx>, + val: mir::ConstValue<'tcx>, ty: Ty<'tcx>, ) -> Self { let layout = bx.layout_of(ty); diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 807794a2a59..de78b4eb504 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -4,9 +4,9 @@ use crate::errors::ConstEvalError; use either::{Left, Right}; use rustc_hir::def::DefKind; -use rustc_middle::mir; use rustc_middle::mir::interpret::{ErrorHandled, InterpErrorInfo}; use rustc_middle::mir::pretty::write_allocation_bytes; +use rustc_middle::mir::{self, ConstAlloc, ConstValue}; use rustc_middle::traits::Reveal; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -18,9 +18,8 @@ use super::{CanAccessStatics, CompileTimeEvalContext, CompileTimeInterpreter}; use crate::errors; use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ - intern_const_alloc_recursive, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId, Immediate, - InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, - StackPopCleanup, + intern_const_alloc_recursive, CtfeValidationMode, GlobalId, Immediate, InternKind, InterpCx, + InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup, }; // Returns a pointer to where the result lives diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 5327fa5ce39..886d7972a15 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -1,7 +1,7 @@ // Not in interpret to make sure we do not use private implementation details use crate::errors::MaxNumNodesInConstErr; -use crate::interpret::{intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, Scalar}; +use crate::interpret::{intern_const_alloc_recursive, InternKind, InterpCx, Scalar}; use rustc_middle::mir; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -22,7 +22,7 @@ pub(crate) use valtrees::{const_to_valtree_inner, valtree_to_const_value}; pub(crate) fn const_caller_location( tcx: TyCtxt<'_>, (file, line, col): (Symbol, u32, u32), -) -> ConstValue<'_> { +) -> mir::ConstValue<'_> { trace!("const_caller_location: {}:{}:{}", file, line, col); let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all(), CanAccessStatics::No); @@ -30,7 +30,7 @@ pub(crate) fn const_caller_location( if intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &loc_place).is_err() { bug!("intern_const_alloc_recursive should not error in this case") } - ConstValue::Scalar(Scalar::from_maybe_pointer(loc_place.ptr(), &tcx)) + mir::ConstValue::Scalar(Scalar::from_maybe_pointer(loc_place.ptr(), &tcx)) } // We forbid type-level constants that contain more than `VALTREE_MAX_NODES` nodes. @@ -87,7 +87,7 @@ pub(crate) fn eval_to_valtree<'tcx>( #[instrument(skip(tcx), level = "debug")] pub(crate) fn try_destructure_mir_constant_for_diagnostics<'tcx>( tcx: TyCtxt<'tcx>, - val: ConstValue<'tcx>, + val: mir::ConstValue<'tcx>, ty: Ty<'tcx>, ) -> Option> { let param_env = ty::ParamEnv::reveal_all(); diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 1675b824c52..2fba7455cb2 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -4,9 +4,10 @@ use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES}; use crate::const_eval::CanAccessStatics; use crate::interpret::MPlaceTy; use crate::interpret::{ - intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta, - MemoryKind, PlaceTy, Projectable, Scalar, + intern_const_alloc_recursive, ImmTy, Immediate, InternKind, MemPlaceMeta, MemoryKind, PlaceTy, + Projectable, Scalar, }; +use rustc_middle::mir; use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; use rustc_span::source_map::DUMMY_SP; @@ -206,7 +207,7 @@ pub fn valtree_to_const_value<'tcx>( tcx: TyCtxt<'tcx>, param_env_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, valtree: ty::ValTree<'tcx>, -) -> ConstValue<'tcx> { +) -> mir::ConstValue<'tcx> { // Basic idea: We directly construct `Scalar` values from trivial `ValTree`s // (those for constants with type bool, int, uint, float or char). // For all other types we create an `MPlace` and fill that by walking @@ -219,10 +220,10 @@ pub fn valtree_to_const_value<'tcx>( match ty.kind() { ty::FnDef(..) => { assert!(valtree.unwrap_branch().is_empty()); - ConstValue::ZeroSized + mir::ConstValue::ZeroSized } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => match valtree { - ty::ValTree::Leaf(scalar_int) => ConstValue::Scalar(Scalar::Int(scalar_int)), + ty::ValTree::Leaf(scalar_int) => mir::ConstValue::Scalar(Scalar::Int(scalar_int)), ty::ValTree::Branch(_) => bug!( "ValTrees for Bool, Int, Uint, Float or Char should have the form ValTree::Leaf" ), @@ -237,7 +238,7 @@ pub fn valtree_to_const_value<'tcx>( let layout = tcx.layout_of(param_env_ty).unwrap(); if layout.is_zst() { // Fast path to avoid some allocations. - return ConstValue::ZeroSized; + return mir::ConstValue::ZeroSized; } if layout.abi.is_scalar() && (matches!(ty.kind(), ty::Tuple(_)) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 3b58f66353b..f08f1437918 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -5,10 +5,8 @@ use rustc_hir::def_id::DefId; use rustc_middle::mir::{ self, - interpret::{ - Allocation, ConstAllocation, ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar, - }, - BinOp, NonDivergingIntrinsic, + interpret::{Allocation, ConstAllocation, GlobalId, InterpResult, PointerArithmetic, Scalar}, + BinOp, ConstValue, NonDivergingIntrinsic, }; use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement}; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 082c0f5b84e..788b50d7c4a 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -13,9 +13,8 @@ use rustc_middle::{mir, ty}; use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size}; use super::{ - alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, InterpCx, - InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, Pointer, Projectable, - Provenance, Scalar, + alloc_range, from_known_layout, mir_assign_valid_types, AllocId, Frame, InterpCx, InterpResult, + MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, Pointer, Projectable, Provenance, Scalar, }; /// An `Immediate` represents a single immediate self-contained Rust value. @@ -702,7 +701,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub(crate) fn const_val_to_op( &self, - val_val: ConstValue<'tcx>, + val_val: mir::ConstValue<'tcx>, ty: Ty<'tcx>, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { @@ -715,15 +714,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; let layout = from_known_layout(self.tcx, self.param_env, layout, || self.layout_of(ty))?; let op = match val_val { - ConstValue::Indirect { alloc_id, offset } => { + mir::ConstValue::Indirect { alloc_id, offset } => { // We rely on mutability being set correctly in that allocation to prevent writes // where none should happen. let ptr = self.global_base_pointer(Pointer::new(alloc_id, offset))?; Operand::Indirect(MemPlace::from_ptr(ptr.into())) } - ConstValue::Scalar(x) => Operand::Immediate(adjust_scalar(x)?.into()), - ConstValue::ZeroSized => Operand::Immediate(Immediate::Uninit), - ConstValue::Slice { data, start, end } => { + mir::ConstValue::Scalar(x) => Operand::Immediate(adjust_scalar(x)?.into()), + mir::ConstValue::ZeroSized => Operand::Immediate(Immediate::Uninit), + mir::ConstValue::Slice { data, start, end } => { // We rely on mutability being set correctly in `data` to prevent writes // where none should happen. let ptr = Pointer::new( diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 0f66df5c30d..fb9aa9d3abe 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -9,16 +9,15 @@ use either::{Either, Left, Right}; use rustc_ast::Mutability; use rustc_index::IndexSlice; use rustc_middle::mir; -use rustc_middle::mir::interpret::PointerArithmetic; use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::Ty; use rustc_target::abi::{Abi, Align, FieldIdx, HasDataLayout, Size, FIRST_VARIANT}; use super::{ - alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg, - ConstAlloc, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, OpTy, Operand, - Pointer, Projectable, Provenance, Readable, Scalar, + alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg, ImmTy, + Immediate, InterpCx, InterpResult, Machine, MemoryKind, OpTy, Operand, Pointer, + PointerArithmetic, Projectable, Provenance, Readable, Scalar, }; #[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] @@ -1037,7 +1036,7 @@ where pub fn raw_const_to_mplace( &self, - raw: ConstAlloc<'tcx>, + raw: mir::ConstAlloc<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> { // This must be an allocation in `tcx` let _ = self.tcx.global_alloc(raw.alloc_id); diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index c80419d4c09..8ea951d0c6e 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -4,14 +4,169 @@ use rustc_hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir}; use rustc_span::Span; -use rustc_target::abi::Size; +use rustc_target::abi::{HasDataLayout, Size}; -use crate::mir::interpret::{ConstValue, ErrorHandled, GlobalAlloc, Scalar}; -use crate::mir::{interpret, pretty_print_const_value, Promoted}; +use crate::mir::interpret::{ + alloc_range, AllocId, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar, +}; +use crate::mir::{pretty_print_const_value, Promoted}; use crate::ty::{self, print::pretty_print_const, List, Ty, TyCtxt}; use crate::ty::{GenericArgs, GenericArgsRef}; use crate::ty::{ScalarInt, UserTypeAnnotationIndex}; +/////////////////////////////////////////////////////////////////////////// +/// Evaluated Constants + +/// Represents the result of const evaluation via the `eval_to_allocation` query. +/// Not to be confused with `ConstAllocation`, which directly refers to the underlying data! +/// Here we indirect via an `AllocId`. +#[derive(Copy, Clone, HashStable, TyEncodable, TyDecodable, Debug, Hash, Eq, PartialEq)] +pub struct ConstAlloc<'tcx> { + /// The value lives here, at offset 0, and that allocation definitely is an `AllocKind::Memory` + /// (so you can use `AllocMap::unwrap_memory`). + pub alloc_id: AllocId, + pub ty: Ty<'tcx>, +} + +/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for +/// array length computations, enum discriminants and the pattern matching logic. +#[derive(Copy, Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Hash)] +#[derive(HashStable, Lift)] +pub enum ConstValue<'tcx> { + /// Used for types with `layout::abi::Scalar` ABI. + /// + /// Not using the enum `Value` to encode that this must not be `Uninit`. + Scalar(Scalar), + + /// Only for ZSTs. + ZeroSized, + + /// Used for `&[u8]` and `&str`. + /// + /// This is worth an optimized representation since Rust has literals of these types. + /// Not having to indirect those through an `AllocId` (or two, if we used `Indirect`) has shown + /// measurable performance improvements on stress tests. + Slice { data: ConstAllocation<'tcx>, start: usize, end: usize }, + + /// A value not representable by the other variants; needs to be stored in-memory. + /// + /// Must *not* be used for scalars or ZST, but having `&str` or other slices in this variant is fine. + Indirect { + /// The backing memory of the value. May contain more memory than needed for just the value + /// if this points into some other larger ConstValue. + /// + /// We use an `AllocId` here instead of a `ConstAllocation<'tcx>` to make sure that when a + /// raw constant (which is basically just an `AllocId`) is turned into a `ConstValue` and + /// back, we can preserve the original `AllocId`. + alloc_id: AllocId, + /// Offset into `alloc` + offset: Size, + }, +} + +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +static_assert_size!(ConstValue<'_>, 32); + +impl<'tcx> ConstValue<'tcx> { + #[inline] + pub fn try_to_scalar(&self) -> Option> { + match *self { + ConstValue::Indirect { .. } | ConstValue::Slice { .. } | ConstValue::ZeroSized => None, + ConstValue::Scalar(val) => Some(val), + } + } + + pub fn try_to_scalar_int(&self) -> Option { + self.try_to_scalar()?.try_to_int().ok() + } + + pub fn try_to_bits(&self, size: Size) -> Option { + self.try_to_scalar_int()?.to_bits(size).ok() + } + + pub fn try_to_bool(&self) -> Option { + self.try_to_scalar_int()?.try_into().ok() + } + + pub fn try_to_target_usize(&self, tcx: TyCtxt<'tcx>) -> Option { + self.try_to_scalar_int()?.try_to_target_usize(tcx).ok() + } + + pub fn try_to_bits_for_ty( + &self, + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ty: Ty<'tcx>, + ) -> Option { + let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; + self.try_to_bits(size) + } + + pub fn from_bool(b: bool) -> Self { + ConstValue::Scalar(Scalar::from_bool(b)) + } + + pub fn from_u64(i: u64) -> Self { + ConstValue::Scalar(Scalar::from_u64(i)) + } + + pub fn from_u128(i: u128) -> Self { + ConstValue::Scalar(Scalar::from_u128(i)) + } + + pub fn from_target_usize(i: u64, cx: &impl HasDataLayout) -> Self { + ConstValue::Scalar(Scalar::from_target_usize(i, cx)) + } + + /// Must only be called on constants of type `&str` or `&[u8]`! + pub fn try_get_slice_bytes_for_diagnostics(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx [u8]> { + let (data, start, end) = match self { + ConstValue::Scalar(_) | ConstValue::ZeroSized => { + bug!("`try_get_slice_bytes` on non-slice constant") + } + &ConstValue::Slice { data, start, end } => (data, start, end), + &ConstValue::Indirect { alloc_id, offset } => { + // The reference itself is stored behind an indirection. + // Load the reference, and then load the actual slice contents. + let a = tcx.global_alloc(alloc_id).unwrap_memory().inner(); + let ptr_size = tcx.data_layout.pointer_size; + if a.size() < offset + 2 * ptr_size { + // (partially) dangling reference + return None; + } + // Read the wide pointer components. + let ptr = a + .read_scalar( + &tcx, + alloc_range(offset, ptr_size), + /* read_provenance */ true, + ) + .ok()?; + let ptr = ptr.to_pointer(&tcx).ok()?; + let len = a + .read_scalar( + &tcx, + alloc_range(offset + ptr_size, ptr_size), + /* read_provenance */ false, + ) + .ok()?; + let len = len.to_target_usize(&tcx).ok()?; + let len: usize = len.try_into().ok()?; + if len == 0 { + return Some(&[]); + } + // Non-empty slice, must have memory. We know this is a relative pointer. + let (inner_alloc_id, offset) = ptr.into_parts(); + let data = tcx.global_alloc(inner_alloc_id?).unwrap_memory(); + (data, offset.bytes_usize(), offset.bytes_usize() + len) + } + }; + + // This is for diagnostics only, so we are okay to use `inspect_with_uninit_and_ptr_outside_interpreter`. + Some(data.inner().inspect_with_uninit_and_ptr_outside_interpreter(start..end)) + } +} + /////////////////////////////////////////////////////////////////////////// /// Constants /// @@ -49,7 +204,7 @@ pub enum ConstantKind<'tcx> { /// This constant cannot go back into the type system, as it represents /// something the type system cannot handle (e.g. pointers). - Val(interpret::ConstValue<'tcx>, Ty<'tcx>), + Val(ConstValue<'tcx>, Ty<'tcx>), } impl<'tcx> Constant<'tcx> { @@ -116,7 +271,7 @@ impl<'tcx> ConstantKind<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, span: Option, - ) -> Result, ErrorHandled> { + ) -> Result, ErrorHandled> { match self { ConstantKind::Ty(c) => { // We want to consistently have a "clean" value for type system constants (i.e., no diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index eb4614745d5..bc464aca5f3 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -1,7 +1,7 @@ -use super::{AllocId, AllocRange, ConstAlloc, Pointer, Scalar}; +use super::{AllocId, AllocRange, Pointer, Scalar}; use crate::error; -use crate::mir::interpret::ConstValue; +use crate::mir::{ConstAlloc, ConstValue}; use crate::query::TyCtxtAt; use crate::ty::{layout, tls, Ty, TyCtxt, ValTree}; diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 8c00746a180..d21f82f04f6 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -149,7 +149,7 @@ pub use self::error::{ UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind, }; -pub use self::value::{ConstAlloc, ConstValue, Scalar}; +pub use self::value::Scalar; pub use self::allocation::{ alloc_range, AllocBytes, AllocError, AllocRange, AllocResult, Allocation, ConstAllocation, diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index c169733ad74..85394f6b7b8 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -9,163 +9,9 @@ use rustc_apfloat::{ use rustc_macros::HashStable; use rustc_target::abi::{HasDataLayout, Size}; -use crate::{ - mir::interpret::alloc_range, - ty::{ParamEnv, ScalarInt, Ty, TyCtxt}, -}; - -use super::{ - AllocId, ConstAllocation, InterpResult, Pointer, PointerArithmetic, Provenance, - ScalarSizeMismatch, -}; - -/// Represents the result of const evaluation via the `eval_to_allocation` query. -#[derive(Copy, Clone, HashStable, TyEncodable, TyDecodable, Debug, Hash, Eq, PartialEq)] -pub struct ConstAlloc<'tcx> { - /// The value lives here, at offset 0, and that allocation definitely is an `AllocKind::Memory` - /// (so you can use `AllocMap::unwrap_memory`). - pub alloc_id: AllocId, - pub ty: Ty<'tcx>, -} - -/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for -/// array length computations, enum discriminants and the pattern matching logic. -#[derive(Copy, Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Hash)] -#[derive(HashStable, Lift)] -pub enum ConstValue<'tcx> { - /// Used for types with `layout::abi::Scalar` ABI. - /// - /// Not using the enum `Value` to encode that this must not be `Uninit`. - Scalar(Scalar), - - /// Only for ZSTs. - ZeroSized, - - /// Used for `&[u8]` and `&str`. - /// - /// This is worth an optimized representation since Rust has literals of these types. - /// Not having to indirect those through an `AllocId` (or two, if we used `Indirect`) has shown - /// measurable performance improvements on stress tests. - Slice { data: ConstAllocation<'tcx>, start: usize, end: usize }, - - /// A value not representable by the other variants; needs to be stored in-memory. - /// - /// Must *not* be used for scalars or ZST, but having `&str` or other slices in this variant is fine. - Indirect { - /// The backing memory of the value. May contain more memory than needed for just the value - /// if this points into some other larger ConstValue. - /// - /// We use an `AllocId` here instead of a `ConstAllocation<'tcx>` to make sure that when a - /// raw constant (which is basically just an `AllocId`) is turned into a `ConstValue` and - /// back, we can preserve the original `AllocId`. - alloc_id: AllocId, - /// Offset into `alloc` - offset: Size, - }, -} - -#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(ConstValue<'_>, 32); - -impl<'tcx> ConstValue<'tcx> { - #[inline] - pub fn try_to_scalar(&self) -> Option> { - match *self { - ConstValue::Indirect { .. } | ConstValue::Slice { .. } | ConstValue::ZeroSized => None, - ConstValue::Scalar(val) => Some(val), - } - } - - pub fn try_to_scalar_int(&self) -> Option { - self.try_to_scalar()?.try_to_int().ok() - } - - pub fn try_to_bits(&self, size: Size) -> Option { - self.try_to_scalar_int()?.to_bits(size).ok() - } - - pub fn try_to_bool(&self) -> Option { - self.try_to_scalar_int()?.try_into().ok() - } - - pub fn try_to_target_usize(&self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_scalar_int()?.try_to_target_usize(tcx).ok() - } - - pub fn try_to_bits_for_ty( - &self, - tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, - ty: Ty<'tcx>, - ) -> Option { - let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; - self.try_to_bits(size) - } - - pub fn from_bool(b: bool) -> Self { - ConstValue::Scalar(Scalar::from_bool(b)) - } - - pub fn from_u64(i: u64) -> Self { - ConstValue::Scalar(Scalar::from_u64(i)) - } - - pub fn from_u128(i: u128) -> Self { - ConstValue::Scalar(Scalar::from_u128(i)) - } - - pub fn from_target_usize(i: u64, cx: &impl HasDataLayout) -> Self { - ConstValue::Scalar(Scalar::from_target_usize(i, cx)) - } - - /// Must only be called on constants of type `&str` or `&[u8]`! - pub fn try_get_slice_bytes_for_diagnostics(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx [u8]> { - let (data, start, end) = match self { - ConstValue::Scalar(_) | ConstValue::ZeroSized => { - bug!("`try_get_slice_bytes` on non-slice constant") - } - &ConstValue::Slice { data, start, end } => (data, start, end), - &ConstValue::Indirect { alloc_id, offset } => { - // The reference itself is stored behind an indirection. - // Load the reference, and then load the actual slice contents. - let a = tcx.global_alloc(alloc_id).unwrap_memory().inner(); - let ptr_size = tcx.data_layout.pointer_size; - if a.size() < offset + 2 * ptr_size { - // (partially) dangling reference - return None; - } - // Read the wide pointer components. - let ptr = a - .read_scalar( - &tcx, - alloc_range(offset, ptr_size), - /* read_provenance */ true, - ) - .ok()?; - let ptr = ptr.to_pointer(&tcx).ok()?; - let len = a - .read_scalar( - &tcx, - alloc_range(offset + ptr_size, ptr_size), - /* read_provenance */ false, - ) - .ok()?; - let len = len.to_target_usize(&tcx).ok()?; - let len: usize = len.try_into().ok()?; - if len == 0 { - return Some(&[]); - } - // Non-empty slice, must have memory. We know this is a relative pointer. - let (inner_alloc_id, offset) = ptr.into_parts(); - let data = tcx.global_alloc(inner_alloc_id?).unwrap_memory(); - (data, offset.bytes_usize(), offset.bytes_usize() + len) - } - }; +use crate::ty::ScalarInt; - // This is for diagnostics only, so we are okay to use `inspect_with_uninit_and_ptr_outside_interpreter`. - Some(data.inner().inspect_with_uninit_and_ptr_outside_interpreter(start..end)) - } -} +use super::{AllocId, InterpResult, Pointer, PointerArithmetic, Provenance, ScalarSizeMismatch}; /// A `Scalar` represents an immediate, primitive value existing outside of a /// `memory::Allocation`. It is in many ways like a small chunk of an `Allocation`, up to 16 bytes in diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index cf134a0e5e7..87180b56baa 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2,7 +2,7 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html -use crate::mir::interpret::{AllocRange, ErrorHandled, ConstAllocation, ConstValue, Scalar}; +use crate::mir::interpret::{AllocRange, ConstAllocation, ErrorHandled, Scalar}; use crate::mir::visit::MirVisitable; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index f41f454ba5e..632f159a7a8 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -12,8 +12,8 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; use rustc_index::Idx; use rustc_middle::mir::interpret::{ - alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, ConstAllocation, ConstValue, - GlobalAlloc, Pointer, Provenance, + alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, ConstAllocation, GlobalAlloc, + Pointer, Provenance, }; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 0c80610b308..c157b7052ab 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -1,6 +1,5 @@ //! Values computed by queries that use MIR. -use crate::mir::interpret::ConstValue; use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordSet; @@ -16,7 +15,7 @@ use smallvec::SmallVec; use std::cell::Cell; use std::fmt::{self, Debug}; -use super::SourceInfo; +use super::{ConstValue, SourceInfo}; #[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)] pub enum UnsafetyViolationKind { diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 9b666222ad0..247fcd20c6c 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -121,16 +121,12 @@ impl EraseType for Result, mir::interpret::LitToConstError [u8; size_of::, mir::interpret::LitToConstError>>()]; } -impl EraseType for Result, mir::interpret::ErrorHandled> { - type Result = [u8; size_of::< - Result, mir::interpret::ErrorHandled>, - >()]; +impl EraseType for Result, mir::interpret::ErrorHandled> { + type Result = [u8; size_of::, mir::interpret::ErrorHandled>>()]; } -impl EraseType for Result, mir::interpret::ErrorHandled> { - type Result = [u8; size_of::< - Result, mir::interpret::ErrorHandled>, - >()]; +impl EraseType for Result, mir::interpret::ErrorHandled> { + type Result = [u8; size_of::, mir::interpret::ErrorHandled>>()]; } impl EraseType for Result>, mir::interpret::ErrorHandled> { @@ -317,8 +313,8 @@ tcx_lifetime! { rustc_middle::middle::exported_symbols::ExportedSymbol, rustc_middle::mir::ConstantKind, rustc_middle::mir::DestructuredConstant, - rustc_middle::mir::interpret::ConstAlloc, - rustc_middle::mir::interpret::ConstValue, + rustc_middle::mir::ConstAlloc, + rustc_middle::mir::ConstValue, rustc_middle::mir::interpret::GlobalId, rustc_middle::mir::interpret::LitToConstInput, rustc_middle::traits::query::MethodAutoderefStepsResult, diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 01bdc4c9904..af4c57e702f 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -2,7 +2,6 @@ use crate::infer::canonical::Canonical; use crate::mir; -use crate::mir::interpret::ConstValue; use crate::traits; use crate::ty::fast_reject::SimplifiedType; use crate::ty::layout::{TyAndLayout, ValidityRequirement}; @@ -369,7 +368,7 @@ impl<'tcx> Key for (ty::Const<'tcx>, FieldIdx) { } } -impl<'tcx> Key for (ConstValue<'tcx>, Ty<'tcx>) { +impl<'tcx> Key for (mir::ConstValue<'tcx>, Ty<'tcx>) { type CacheSelector = DefaultCacheSelector; fn default_span(&self, _: TyCtxt<'_>) -> Span { @@ -377,7 +376,7 @@ impl<'tcx> Key for (ConstValue<'tcx>, Ty<'tcx>) { } } -impl<'tcx> Key for mir::interpret::ConstAlloc<'tcx> { +impl<'tcx> Key for mir::ConstAlloc<'tcx> { type CacheSelector = DefaultCacheSelector; fn default_span(&self, _: TyCtxt<'_>) -> Span { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 9e358ea4eba..b5529568ff2 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -21,7 +21,7 @@ use crate::middle::stability::{self, DeprecationEntry}; use crate::mir; use crate::mir::interpret::GlobalId; use crate::mir::interpret::{ - ConstValue, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, + EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, }; use crate::mir::interpret::{LitToConstError, LitToConstInput}; use crate::mir::mono::CodegenUnit; @@ -1091,7 +1091,7 @@ rustc_queries! { } /// Converts a type level constant value into `ConstValue` - query valtree_to_const_val(key: (Ty<'tcx>, ty::ValTree<'tcx>)) -> ConstValue<'tcx> { + query valtree_to_const_val(key: (Ty<'tcx>, ty::ValTree<'tcx>)) -> mir::ConstValue<'tcx> { desc { "converting type-level constant value to mir constant value"} } @@ -1104,14 +1104,14 @@ rustc_queries! { /// Tries to destructure an `mir::ConstantKind` ADT or array into its variant index /// and its field values. This should only be used for pretty printing. query try_destructure_mir_constant_for_diagnostics( - key: (ConstValue<'tcx>, Ty<'tcx>) + key: (mir::ConstValue<'tcx>, Ty<'tcx>) ) -> Option> { desc { "destructuring MIR constant"} no_hash eval_always } - query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> { + query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> mir::ConstValue<'tcx> { desc { "getting a &core::panic::Location referring to a span" } } diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index da5f2b1bcc9..0eff2df1366 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -1,4 +1,4 @@ -use rustc_middle::mir::interpret::{ConstValue, Scalar}; +use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::ty::cast::mir_cast_kind; use rustc_middle::{mir::*, thir::*, ty}; diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index aaa37446e24..22712fd3df0 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -3,9 +3,7 @@ use crate::build::{parse_float_into_constval, Builder}; use rustc_ast as ast; use rustc_middle::mir; -use rustc_middle::mir::interpret::{ - Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar, -}; +use rustc_middle::mir::interpret::{Allocation, LitToConstError, LitToConstInput, Scalar}; use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::{ diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 4e10916ad61..7748ffab79c 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -15,7 +15,6 @@ use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; use rustc_middle::middle::region; -use rustc_middle::mir::interpret::ConstValue; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::*; use rustc_middle::thir::{ diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 71e6e6f3a7a..3d9e634c849 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -18,7 +18,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::RangeEnd; use rustc_index::Idx; use rustc_middle::mir::interpret::{ - ConstValue, ErrorHandled, GlobalId, LitToConstError, LitToConstInput, Scalar, + ErrorHandled, GlobalId, LitToConstError, LitToConstInput, Scalar, }; use rustc_middle::mir::{self, ConstantKind, UserTypeProjection}; use rustc_middle::mir::{BorrowKind, Mutability}; @@ -855,8 +855,8 @@ pub(crate) fn compare_const_vals<'tcx>( ty::Float(_) | ty::Int(_) => {} // require special handling, see below _ => match (a, b) { ( - mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(a)), _a_ty), - mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(b)), _b_ty), + mir::ConstantKind::Val(mir::ConstValue::Scalar(Scalar::Int(a)), _a_ty), + mir::ConstantKind::Val(mir::ConstValue::Scalar(Scalar::Int(b)), _b_ty), ) => return Some(a.cmp(&b)), (mir::ConstantKind::Ty(a), mir::ConstantKind::Ty(b)) => { return Some(a.kind().cmp(&b.kind())); diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index 4892ace53e3..fe66a9a0994 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -4,7 +4,7 @@ use rustc_hir::lang_items::LangItem; use rustc_index::IndexVec; use rustc_middle::mir::*; use rustc_middle::mir::{ - interpret::{ConstValue, Scalar}, + interpret::Scalar, visit::{PlaceContext, Visitor}, }; use rustc_middle::ty::{Ty, TyCtxt, TypeAndMut}; diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 00e3e3a8f9f..c6aac2ca213 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -22,8 +22,8 @@ use rustc_target::spec::abi::Abi as CallAbi; use crate::dataflow_const_prop::Patch; use crate::MirPass; use rustc_const_eval::interpret::{ - self, compile_time_machine, AllocId, ConstAllocation, ConstValue, FnArg, Frame, ImmTy, - Immediate, InterpCx, InterpResult, MemoryKind, OpTy, PlaceTy, Pointer, Scalar, StackPopCleanup, + self, compile_time_machine, AllocId, ConstAllocation, FnArg, Frame, ImmTy, Immediate, InterpCx, + InterpResult, MemoryKind, OpTy, PlaceTy, Pointer, Scalar, StackPopCleanup, }; /// The maximum number of bytes that we'll allocate space for a local or the return value. diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index c7c5f17dfec..cf827c98894 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -6,7 +6,7 @@ use rustc_const_eval::const_eval::CheckAlignment; use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, Projectable}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; -use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ConstValue, InterpResult, Scalar}; +use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult, Scalar}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::layout::TyAndLayout; diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 8afbe418502..fc49c9ba348 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -153,7 +153,7 @@ impl EnumSizeOpt { span, user_ty: None, literal: ConstantKind::Val( - interpret::ConstValue::Indirect { alloc_id, offset: Size::ZERO }, + ConstValue::Indirect { alloc_id, offset: Size::ZERO }, tmp_ty, ), }; diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index c13bafa9fbb..dcc4cd85cda 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -1,7 +1,6 @@ //! Removes operations on ZST places, and convert ZST operands to constants. use crate::MirPass; -use rustc_middle::mir::interpret::ConstValue; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 92abd0c3b6e..67e821dcf5a 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -170,8 +170,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::lang_items::LangItem; -use rustc_middle::mir::interpret::{AllocId, ConstValue}; -use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar}; +use rustc_middle::mir::interpret::{AllocId, ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; use rustc_middle::mir::visit::Visitor as MirVisitor; use rustc_middle::mir::{self, Local, Location}; @@ -1442,13 +1441,15 @@ fn collect_used_items<'tcx>( #[instrument(skip(tcx, output), level = "debug")] fn collect_const_value<'tcx>( tcx: TyCtxt<'tcx>, - value: ConstValue<'tcx>, + value: mir::ConstValue<'tcx>, output: &mut MonoItems<'tcx>, ) { match value { - ConstValue::Scalar(Scalar::Ptr(ptr, _size)) => collect_alloc(tcx, ptr.provenance, output), - ConstValue::Indirect { alloc_id, .. } => collect_alloc(tcx, alloc_id, output), - ConstValue::Slice { data, start: _, end: _ } => { + mir::ConstValue::Scalar(Scalar::Ptr(ptr, _size)) => { + collect_alloc(tcx, ptr.provenance, output) + } + mir::ConstValue::Indirect { alloc_id, .. } => collect_alloc(tcx, alloc_id, output), + mir::ConstValue::Slice { data, start: _, end: _ } => { for &id in data.inner().provenance().ptrs().values() { collect_alloc(tcx, id, output); } diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index 35e65c19be0..58b695f755f 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -1,4 +1,7 @@ -use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer}; +use rustc_middle::mir::{ + interpret::{alloc_range, AllocRange, Pointer}, + ConstValue, +}; use crate::{ rustc_smir::{Stable, Tables}, diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 7696ea0f449..8cddd5f9a87 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -16,7 +16,6 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_metadata::rendered_const; use rustc_middle::mir; -use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use std::fmt::Write as _; @@ -282,8 +281,8 @@ pub(crate) fn print_evaluated_const( let ty = tcx.type_of(def_id).instantiate_identity(); match (val, ty.kind()) { (_, &ty::Ref(..)) => None, - (ConstValue::Scalar(_), &ty::Adt(_, _)) => None, - (ConstValue::Scalar(_), _) => { + (mir::ConstValue::Scalar(_), &ty::Adt(_, _)) => None, + (mir::ConstValue::Scalar(_), _) => { let const_ = mir::ConstantKind::from_value(val, ty); Some(print_const_with_custom_print_scalar(tcx, const_, underscores_and_type)) } @@ -326,14 +325,14 @@ fn print_const_with_custom_print_scalar<'tcx>( // Use a slightly different format for integer types which always shows the actual value. // For all other types, fallback to the original `pretty_print_const`. match (ct, ct.ty().kind()) { - (mir::ConstantKind::Val(ConstValue::Scalar(int), _), ty::Uint(ui)) => { + (mir::ConstantKind::Val(mir::ConstValue::Scalar(int), _), ty::Uint(ui)) => { if underscores_and_type { format!("{}{}", format_integer_with_underscore_sep(&int.to_string()), ui.name_str()) } else { int.to_string() } } - (mir::ConstantKind::Val(ConstValue::Scalar(int), _), ty::Int(i)) => { + (mir::ConstantKind::Val(mir::ConstValue::Scalar(int), _), ty::Int(i)) => { let ty = ct.ty(); let size = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size; let data = int.assert_bits(size); diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index fcb90c63a6f..c88fce22f7f 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -656,7 +656,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { } pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::ConstantKind<'tcx>) -> Option> { - use rustc_middle::mir::interpret::ConstValue; + use rustc_middle::mir::ConstValue; match result { mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(int)), _) => match result.ty().kind() { ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)), diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index f0b4ede35fb..9e25d97f5a6 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -13,7 +13,7 @@ use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; -use rustc_middle::mir::interpret::{ConstValue, Scalar}; +use rustc_middle::mir::{ConstValue, interpret::Scalar}; use rustc_middle::traits::EvaluationResult; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{ -- cgit 1.4.1-3-g733a5 From 7928c7e25d0977eed31a2ac9d22c1b440b1fdfc4 Mon Sep 17 00:00:00 2001 From: Martin Kröning Date: Tue, 19 Sep 2023 14:15:53 +0200 Subject: chore(Cargo.lock): bump colored and tracing-tree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reduces the amount of dependencies pulling in atty. ``` Updating colored v2.0.0 -> v2.0.4 Updating tracing-tree v0.2.3 -> v0.2.4 ``` Signed-off-by: Martin Kröning --- Cargo.lock | 14 +++++++------- src/tools/tidy/src/deps.rs | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/tools') diff --git a/Cargo.lock b/Cargo.lock index 95ac3136628..e45f4e80602 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -627,13 +627,13 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.0.0" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" dependencies = [ - "atty", + "is-terminal", "lazy_static", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -5591,11 +5591,11 @@ dependencies = [ [[package]] name = "tracing-tree" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9742d8df709837409dbb22aa25dd7769c260406f20ff48a2320b80a4a6aed0" +checksum = "92d6b63348fad3ae0439b8bebf8d38fb5bda0b115d7a8a7e6f165f12790c58c3" dependencies = [ - "atty", + "is-terminal", "nu-ansi-term", "tracing-core", "tracing-log", diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 410852b6a31..843ffe2c4c3 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -120,7 +120,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "annotate-snippets", "ar_archive_writer", "arrayvec", - "atty", "autocfg", "bitflags", "block-buffer", @@ -181,6 +180,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "intl-memoizer", "intl_pluralrules", "io-lifetimes", + "is-terminal", "itertools", "itoa", "jobserver", -- cgit 1.4.1-3-g733a5 From 4241f942b67407fd9fda0c393254277fd4f35fd3 Mon Sep 17 00:00:00 2001 From: Martin Kröning Date: Tue, 19 Sep 2023 14:19:52 +0200 Subject: chore(miri): bump env_logger to 0.10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reduces the amount of dependencies pulling in atty. ``` Removing env_logger v0.9.3 ``` Signed-off-by: Martin Kröning --- Cargo.lock | 15 +-------------- src/tools/miri/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 15 deletions(-) (limited to 'src/tools') diff --git a/Cargo.lock b/Cargo.lock index e45f4e80602..d9aaedb8544 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1169,19 +1169,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "env_logger" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" -dependencies = [ - "atty", - "humantime 2.1.0", - "log", - "regex", - "termcolor", -] - [[package]] name = "env_logger" version = "0.10.0" @@ -2454,7 +2441,7 @@ version = "0.1.0" dependencies = [ "colored", "ctrlc", - "env_logger 0.9.3", + "env_logger 0.10.0", "getrandom", "lazy_static", "libc", diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index 67a2aeefa02..2ae6f922e3a 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -19,7 +19,7 @@ doctest = false # and no doc tests [dependencies] getrandom = { version = "0.2", features = ["std"] } -env_logger = "0.9" +env_logger = "0.10" log = "0.4" rand = "0.8" smallvec = "1.7" -- cgit 1.4.1-3-g733a5 From ea22adbabdd0f5fbc033101eaeed6d3e304ede08 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 15 Sep 2023 15:59:47 +0200 Subject: adjust constValue::Slice to work for arbitrary slice types --- compiler/rustc_codegen_cranelift/src/constant.rs | 12 +++----- compiler/rustc_codegen_ssa/src/mir/operand.rs | 9 ++---- .../src/const_eval/eval_queries.rs | 25 ++++++++++------ compiler/rustc_const_eval/src/interpret/cast.rs | 5 ++-- .../rustc_const_eval/src/interpret/intrinsics.rs | 2 +- compiler/rustc_const_eval/src/interpret/operand.rs | 33 ++++++++++++---------- compiler/rustc_middle/src/mir/consts.rs | 27 ++++++++++++------ compiler/rustc_middle/src/ty/structural_impls.rs | 1 + .../rustc_mir_build/src/build/expr/as_constant.rs | 6 ++-- compiler/rustc_monomorphize/src/collector.rs | 2 +- compiler/rustc_smir/src/rustc_smir/alloc.rs | 14 ++++----- src/tools/miri/src/shims/backtrace.rs | 2 +- 12 files changed, 75 insertions(+), 63 deletions(-) (limited to 'src/tools') diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 02468684ba0..151674b2d6d 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -184,15 +184,11 @@ pub(crate) fn codegen_const_value<'tcx>( .offset_i64(fx, i64::try_from(offset.bytes()).unwrap()), layout, ), - ConstValue::Slice { data, start, end } => { + ConstValue::Slice { data, meta } => { let alloc_id = fx.tcx.reserve_and_set_memory_alloc(data); - let ptr = pointer_for_allocation(fx, alloc_id) - .offset_i64(fx, i64::try_from(start).unwrap()) - .get_addr(fx); - let len = fx - .bcx - .ins() - .iconst(fx.pointer_type, i64::try_from(end.checked_sub(start).unwrap()).unwrap()); + let ptr = pointer_for_allocation(fx, alloc_id).get_addr(fx); + // FIXME: the `try_from` here can actually fail, e.g. for very long ZST slices. + let len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(meta).unwrap()); CValue::by_val_pair(ptr, len, layout) } } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 926a0bed0da..9205acc527e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -100,15 +100,12 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { OperandValue::Immediate(llval) } ConstValue::ZeroSized => return OperandRef::zero_sized(layout), - ConstValue::Slice { data, start, end } => { + ConstValue::Slice { data, meta } => { let Abi::ScalarPair(a_scalar, _) = layout.abi else { bug!("from_const: invalid ScalarPair layout: {:#?}", layout); }; let a = Scalar::from_pointer( - Pointer::new( - bx.tcx().reserve_and_set_memory_alloc(data), - Size::from_bytes(start), - ), + Pointer::new(bx.tcx().reserve_and_set_memory_alloc(data), Size::ZERO), &bx.tcx(), ); let a_llval = bx.scalar_to_backend( @@ -116,7 +113,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { a_scalar, bx.scalar_pair_element_backend_type(layout, 0, true), ); - let b_llval = bx.const_usize((end - start) as u64); + let b_llval = bx.const_usize(meta); OperandValue::Pair(a_llval, b_llval) } ConstValue::Indirect { alloc_id, offset } => { diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index de78b4eb504..3d758cd01d3 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -151,19 +151,26 @@ pub(super) fn op_to_const<'tcx>( Immediate::Scalar(x) => ConstValue::Scalar(x), Immediate::ScalarPair(a, b) => { debug!("ScalarPair(a: {:?}, b: {:?})", a, b); - // FIXME: assert that this has an appropriate type. - // Currently we actually get here for non-[u8] slices during valtree construction! - let msg = "`op_to_const` on an immediate scalar pair must only be used on slice references to actually allocated memory"; + // This codepath solely exists for `valtree_to_const_value` to not need to generate + // a `ConstValue::Indirect` for wide references, so it is tightly restricted to just + // that case. + let pointee_ty = imm.layout.ty.builtin_deref(false).unwrap().ty; // `false` = no raw ptrs + debug_assert!( + matches!( + ecx.tcx.struct_tail_without_normalization(pointee_ty).kind(), + ty::Str | ty::Slice(..), + ), + "`ConstValue::Slice` is for slice-tailed types only, but got {}", + imm.layout.ty, + ); + let msg = "`op_to_const` on an immediate scalar pair must only be used on slice references to the beginning of an actual allocation"; // We know `offset` is relative to the allocation, so we can use `into_parts`. - // We use `ConstValue::Slice` so that we don't have to generate an allocation for - // `ConstValue::Indirect` here. let (alloc_id, offset) = a.to_pointer(ecx).expect(msg).into_parts(); let alloc_id = alloc_id.expect(msg); let data = ecx.tcx.global_alloc(alloc_id).unwrap_memory(); - let start = offset.bytes_usize(); - let len = b.to_target_usize(ecx).expect(msg); - let len: usize = len.try_into().unwrap(); - ConstValue::Slice { data, start, end: start + len } + assert!(offset == abi::Size::ZERO, "{}", msg); + let meta = b.to_target_usize(ecx).expect(msg); + ConstValue::Slice { data, meta } } Immediate::Uninit => bug!("`Uninit` is not a valid value for {}", op.layout.ty), }, diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 4c826239eca..bd897ffaafc 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -351,7 +351,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match (&src_pointee_ty.kind(), &dest_pointee_ty.kind()) { (&ty::Array(_, length), &ty::Slice(_)) => { - let ptr = self.read_scalar(src)?; + let ptr = self.read_pointer(src)?; // u64 cast is from usize to u64, which is always good let val = Immediate::new_slice( ptr, @@ -367,6 +367,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return self.write_immediate(*val, dest); } let (old_data, old_vptr) = val.to_scalar_pair(); + let old_data = old_data.to_pointer(self)?; let old_vptr = old_vptr.to_pointer(self)?; let (ty, old_trait) = self.get_ptr_vtable(old_vptr)?; if old_trait != data_a.principal() { @@ -378,7 +379,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (_, &ty::Dynamic(data, _, ty::Dyn)) => { // Initial cast from sized to dyn trait let vtable = self.get_vtable_ptr(src_pointee_ty, data.principal())?; - let ptr = self.read_scalar(src)?; + let ptr = self.read_pointer(src)?; let val = Immediate::new_dyn_trait(ptr, vtable, &*self.tcx); self.write_immediate(val, dest) } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index f08f1437918..775a834f2ee 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -62,7 +62,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( sym::type_name => { ensure_monomorphic_enough(tcx, tp_ty)?; let alloc = alloc_type_name(tcx, tp_ty); - ConstValue::Slice { data: alloc, start: 0, end: alloc.inner().len() } + ConstValue::Slice { data: alloc, meta: alloc.inner().size().bytes() } } sym::needs_drop => { ensure_monomorphic_enough(tcx, tp_ty)?; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 788b50d7c4a..fdda98a50e8 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -43,24 +43,30 @@ impl From> for Immediate { } impl Immediate { - pub fn from_pointer(p: Pointer, cx: &impl HasDataLayout) -> Self { - Immediate::Scalar(Scalar::from_pointer(p, cx)) + pub fn from_pointer(ptr: Pointer, cx: &impl HasDataLayout) -> Self { + Immediate::Scalar(Scalar::from_pointer(ptr, cx)) } - pub fn from_maybe_pointer(p: Pointer>, cx: &impl HasDataLayout) -> Self { - Immediate::Scalar(Scalar::from_maybe_pointer(p, cx)) + pub fn from_maybe_pointer(ptr: Pointer>, cx: &impl HasDataLayout) -> Self { + Immediate::Scalar(Scalar::from_maybe_pointer(ptr, cx)) } - pub fn new_slice(val: Scalar, len: u64, cx: &impl HasDataLayout) -> Self { - Immediate::ScalarPair(val, Scalar::from_target_usize(len, cx)) + pub fn new_slice(ptr: Pointer>, len: u64, cx: &impl HasDataLayout) -> Self { + Immediate::ScalarPair( + Scalar::from_maybe_pointer(ptr, cx), + Scalar::from_target_usize(len, cx), + ) } pub fn new_dyn_trait( - val: Scalar, + val: Pointer>, vtable: Pointer>, cx: &impl HasDataLayout, ) -> Self { - Immediate::ScalarPair(val, Scalar::from_maybe_pointer(vtable, cx)) + Immediate::ScalarPair( + Scalar::from_maybe_pointer(val, cx), + Scalar::from_maybe_pointer(vtable, cx), + ) } #[inline] @@ -722,16 +728,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } mir::ConstValue::Scalar(x) => Operand::Immediate(adjust_scalar(x)?.into()), mir::ConstValue::ZeroSized => Operand::Immediate(Immediate::Uninit), - mir::ConstValue::Slice { data, start, end } => { + mir::ConstValue::Slice { data, meta } => { // We rely on mutability being set correctly in `data` to prevent writes // where none should happen. - let ptr = Pointer::new( - self.tcx.reserve_and_set_memory_alloc(data), - Size::from_bytes(start), // offset: `start` - ); + let ptr = Pointer::new(self.tcx.reserve_and_set_memory_alloc(data), Size::ZERO); Operand::Immediate(Immediate::new_slice( - Scalar::from_pointer(self.global_base_pointer(ptr)?, &*self.tcx), - u64::try_from(end.checked_sub(start).unwrap()).unwrap(), // len: `end - start` + self.global_base_pointer(ptr)?.into(), + meta, self, )) } diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 9e86eb214c1..0115b1dcb3e 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -41,12 +41,20 @@ pub enum ConstValue<'tcx> { /// Only for ZSTs. ZeroSized, - /// Used for `&[u8]` and `&str`. + /// Used for references to unsized types with slice tail. /// - /// This is worth an optimized representation since Rust has literals of these types. - /// Not having to indirect those through an `AllocId` (or two, if we used `Indirect`) has shown - /// measurable performance improvements on stress tests. - Slice { data: ConstAllocation<'tcx>, start: usize, end: usize }, + /// This is worth an optimized representation since Rust has literals of type `&str` and + /// `&[u8]`. Not having to indirect those through an `AllocId` (or two, if we used `Indirect`) + /// has shown measurable performance improvements on stress tests. We then reuse this + /// optimization for slice-tail types more generally during valtree-to-constval conversion. + Slice { + /// The allocation storing the slice contents. + /// This always points to the beginning of the allocation. + data: ConstAllocation<'tcx>, + /// The metadata field of the reference. + /// This is a "target usize", so we use `u64` as in the interpreter. + meta: u64, + }, /// A value not representable by the other variants; needs to be stored in-memory. /// @@ -65,7 +73,7 @@ pub enum ConstValue<'tcx> { } #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(ConstValue<'_>, 32); +static_assert_size!(ConstValue<'_>, 24); impl<'tcx> ConstValue<'tcx> { #[inline] @@ -124,7 +132,7 @@ impl<'tcx> ConstValue<'tcx> { ConstValue::Scalar(_) | ConstValue::ZeroSized => { bug!("`try_get_slice_bytes` on non-slice constant") } - &ConstValue::Slice { data, start, end } => (data, start, end), + &ConstValue::Slice { data, meta } => (data, 0, meta), &ConstValue::Indirect { alloc_id, offset } => { // The reference itself is stored behind an indirection. // Load the reference, and then load the actual slice contents. @@ -151,18 +159,19 @@ impl<'tcx> ConstValue<'tcx> { ) .ok()?; let len = len.to_target_usize(&tcx).ok()?; - let len: usize = len.try_into().ok()?; if len == 0 { return Some(&[]); } // Non-empty slice, must have memory. We know this is a relative pointer. let (inner_alloc_id, offset) = ptr.into_parts(); let data = tcx.global_alloc(inner_alloc_id?).unwrap_memory(); - (data, offset.bytes_usize(), offset.bytes_usize() + len) + (data, offset.bytes(), offset.bytes() + len) } }; // This is for diagnostics only, so we are okay to use `inspect_with_uninit_and_ptr_outside_interpreter`. + let start = start.try_into().unwrap(); + let end = end.try_into().unwrap(); Some(data.inner().inspect_with_uninit_and_ptr_outside_interpreter(start..end)) } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index f4158597d10..268339ed402 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -457,6 +457,7 @@ TrivialLiftImpls! { (), bool, usize, + u64, } // For some things about which the type library does not know, or does not diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 22712fd3df0..d8232199e01 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -131,14 +131,14 @@ fn lit_to_mir_constant<'tcx>( let s = s.as_str(); let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes()); let allocation = tcx.mk_const_alloc(allocation); - ConstValue::Slice { data: allocation, start: 0, end: s.len() } + ConstValue::Slice { data: allocation, meta: allocation.inner().size().bytes() } } (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Slice(_)) => { let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); let allocation = tcx.mk_const_alloc(allocation); - ConstValue::Slice { data: allocation, start: 0, end: data.len() } + ConstValue::Slice { data: allocation, meta: allocation.inner().size().bytes() } } (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => { let id = tcx.allocate_bytes(data); @@ -148,7 +148,7 @@ fn lit_to_mir_constant<'tcx>( { let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); let allocation = tcx.mk_const_alloc(allocation); - ConstValue::Slice { data: allocation, start: 0, end: data.len() } + ConstValue::Slice { data: allocation, meta: allocation.inner().size().bytes() } } (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1))) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 67e821dcf5a..c8b72107756 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1449,7 +1449,7 @@ fn collect_const_value<'tcx>( collect_alloc(tcx, ptr.provenance, output) } mir::ConstValue::Indirect { alloc_id, .. } => collect_alloc(tcx, alloc_id, output), - mir::ConstValue::Slice { data, start: _, end: _ } => { + mir::ConstValue::Slice { data, meta: _ } => { for &id in data.inner().provenance().ptrs().values() { collect_alloc(tcx, id, output); } diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index 58b695f755f..d8766cf8ce2 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -47,14 +47,12 @@ pub fn new_allocation<'tcx>( tables.tcx.layout_of(rustc_middle::ty::ParamEnv::empty().and(ty)).unwrap().align; new_empty_allocation(align.abi) } - ConstValue::Slice { data, start, end } => { + ConstValue::Slice { data, meta } => { let alloc_id = tables.tcx.reserve_and_set_memory_alloc(data); - let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start)); + let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::ZERO); let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx); - let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize( - (end - start) as u64, - &tables.tcx, - ); + let scalar_meta = + rustc_middle::mir::interpret::Scalar::from_target_usize(meta, &tables.tcx); let layout = tables.tcx.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)).unwrap(); let mut allocation = @@ -69,8 +67,8 @@ pub fn new_allocation<'tcx>( allocation .write_scalar( &tables.tcx, - alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()), - scalar_len, + alloc_range(tables.tcx.data_layout.pointer_size, scalar_meta.size()), + scalar_meta, ) .unwrap(); allocation.stable(tables) diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index bfec4833ac9..836cab3ac9d 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -89,7 +89,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } this.write_immediate( - Immediate::new_slice(Scalar::from_maybe_pointer(alloc.ptr(), this), len, this), + Immediate::new_slice(alloc.ptr(), len, this), dest, )?; } -- cgit 1.4.1-3-g733a5 From 670631dd2606e7cb7cc488a2f7a7331e9dfd39af Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 20 Sep 2023 08:31:33 +0200 Subject: Ensure `build/tmp` exists in `rustdoc_themes::get_themes` --- src/tools/rustdoc-themes/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/rustdoc-themes/main.rs b/src/tools/rustdoc-themes/main.rs index cc13df1f5ba..1eba83a8057 100644 --- a/src/tools/rustdoc-themes/main.rs +++ b/src/tools/rustdoc-themes/main.rs @@ -1,5 +1,5 @@ use std::env::args; -use std::fs::File; +use std::fs::{create_dir_all, File}; use std::io::{BufRead, BufReader, BufWriter, Write}; use std::path::Path; use std::process::{exit, Command}; @@ -14,6 +14,7 @@ fn get_themes>(style_path: P) -> Vec { std::time::SystemTime::UNIX_EPOCH.elapsed().expect("time is after UNIX epoch").as_millis(); let mut in_theme = None; + create_dir_all("build/tmp").expect("failed to create temporary test directory"); for line in BufReader::new(File::open(style_path).expect("read rustdoc.css failed")).lines() { let line = line.expect("read line from rustdoc.css failed"); let line = line.trim(); -- cgit 1.4.1-3-g733a5 From bb6a46592f173bd1ee045f8d57ed66d9dbe5812d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 20 Sep 2023 19:00:34 +0000 Subject: Fix ui-fulldeps --stage=1 with -Zignore-directory-in-diagnostics-source-blocks --- src/tools/compiletest/src/runtest.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'src/tools') diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7b42d8e9b58..657d074b380 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2335,14 +2335,17 @@ impl<'test> TestCx<'test> { rustc.arg("-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX"); rustc.arg("-Ztranslate-remapped-path-to-local-path=no"); - // Hide Cargo dependency sources from ui tests to make sure the error message doesn't - // change depending on whether $CARGO_HOME is remapped or not. If this is not present, - // when $CARGO_HOME is remapped the source won't be shown, and when it's not remapped the - // source will be shown, causing a blessing hell. - rustc.arg("-Z").arg(format!( - "ignore-directory-in-diagnostics-source-blocks={}", - home::cargo_home().expect("failed to find cargo home").to_str().unwrap() - )); + // #[cfg(not(bootstrap))]: After beta bump, this should **always** run. + if !(self.config.stage_id.starts_with("stage1-") && self.config.suite == "ui-fulldeps") { + // Hide Cargo dependency sources from ui tests to make sure the error message doesn't + // change depending on whether $CARGO_HOME is remapped or not. If this is not present, + // when $CARGO_HOME is remapped the source won't be shown, and when it's not remapped the + // source will be shown, causing a blessing hell. + rustc.arg("-Z").arg(format!( + "ignore-directory-in-diagnostics-source-blocks={}", + home::cargo_home().expect("failed to find cargo home").to_str().unwrap() + )); + } // Optionally prevent default --sysroot if specified in test compile-flags. if !self.props.compile_flags.iter().any(|flag| flag.starts_with("--sysroot")) -- cgit 1.4.1-3-g733a5 From 4b865b7d1aa4ffe2e760adfdc9744d6a656ba96a Mon Sep 17 00:00:00 2001 From: The Miri Conjob Bot Date: Thu, 21 Sep 2023 05:28:08 +0000 Subject: Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index a2030c1c343..f6db58695fb 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -19dd9535408db0f1ff3d16613619076aef524d19 +4fda889bf8735755573b27e6116ce025f3ded5f9 -- cgit 1.4.1-3-g733a5 From bc7bb3c8e7f62a490055cfd2aa43b6dc77c0f3f7 Mon Sep 17 00:00:00 2001 From: Tomasz Miąsko Date: Sat, 9 Sep 2023 00:00:00 +0000 Subject: compiletest: use builder pattern to construct Config in tests --- src/tools/compiletest/src/header/tests.rs | 234 ++++++++++++++++++------------ 1 file changed, 141 insertions(+), 93 deletions(-) (limited to 'src/tools') diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 362fba11697..2fd80b52cee 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -53,47 +53,117 @@ fn test_parse_normalization_string() { assert_eq!(s, r#"normalize-stderr-16bit: something (16 bits) -> something ($WORD bits)."#); } -fn config() -> Config { - let args = &[ - "compiletest", - "--mode=ui", - "--suite=ui", - "--compile-lib-path=", - "--run-lib-path=", - "--python=", - "--jsondocck-path=", - "--src-base=", - "--build-base=", - "--sysroot-base=", - "--stage-id=stage2-x86_64-unknown-linux-gnu", - "--cc=c", - "--cxx=c++", - "--cflags=", - "--cxxflags=", - "--llvm-components=", - "--android-cross-path=", - "--target=x86_64-unknown-linux-gnu", - "--channel=nightly", - ]; - let mut args: Vec = args.iter().map(ToString::to_string).collect(); - args.push("--rustc-path".to_string()); - // This is a subtle/fragile thing. On rust-lang CI, there is no global - // `rustc`, and Cargo doesn't offer a convenient way to get the path to - // `rustc`. Fortunately bootstrap sets `RUSTC` for us, which is pointing - // to the stage0 compiler. - // - // Otherwise, if you are running compiletests's tests manually, you - // probably don't have `RUSTC` set, in which case this falls back to the - // global rustc. If your global rustc is too far out of sync with stage0, - // then this may cause confusing errors. Or if for some reason you don't - // have rustc in PATH, that would also fail. - args.push(std::env::var("RUSTC").unwrap_or_else(|_| { - eprintln!( - "warning: RUSTC not set, using global rustc (are you not running via bootstrap?)" - ); - "rustc".to_string() - })); - crate::parse_config(args) +#[derive(Default)] +struct ConfigBuilder { + channel: Option, + host: Option, + target: Option, + stage_id: Option, + llvm_version: Option, + git_hash: bool, + system_llvm: bool, +} + +impl ConfigBuilder { + fn channel(&mut self, s: &str) -> &mut Self { + self.channel = Some(s.to_owned()); + self + } + + fn host(&mut self, s: &str) -> &mut Self { + self.host = Some(s.to_owned()); + self + } + + fn target(&mut self, s: &str) -> &mut Self { + self.target = Some(s.to_owned()); + self + } + + fn stage_id(&mut self, s: &str) -> &mut Self { + self.stage_id = Some(s.to_owned()); + self + } + + fn llvm_version(&mut self, s: &str) -> &mut Self { + self.llvm_version = Some(s.to_owned()); + self + } + + fn git_hash(&mut self, b: bool) -> &mut Self { + self.git_hash = b; + self + } + + fn system_llvm(&mut self, s: bool) -> &mut Self { + self.system_llvm = s; + self + } + + fn build(&mut self) -> Config { + let args = &[ + "compiletest", + "--mode=ui", + "--suite=ui", + "--compile-lib-path=", + "--run-lib-path=", + "--python=", + "--jsondocck-path=", + "--src-base=", + "--build-base=", + "--sysroot-base=", + "--cc=c", + "--cxx=c++", + "--cflags=", + "--cxxflags=", + "--llvm-components=", + "--android-cross-path=", + "--stage-id", + self.stage_id.as_deref().unwrap_or("stage2-x86_64-unknown-linux-gnu"), + "--channel", + self.channel.as_deref().unwrap_or("nightly"), + "--host", + self.host.as_deref().unwrap_or("x86_64-unknown-linux-gnu"), + "--target", + self.target.as_deref().unwrap_or("x86_64-unknown-linux-gnu"), + ]; + let mut args: Vec = args.iter().map(ToString::to_string).collect(); + + if let Some(ref llvm_version) = self.llvm_version { + args.push("--llvm-version".to_owned()); + args.push(llvm_version.clone()); + } + + if self.git_hash { + args.push("--git-hash".to_owned()); + } + if self.system_llvm { + args.push("--system-llvm".to_owned()); + } + + args.push("--rustc-path".to_string()); + // This is a subtle/fragile thing. On rust-lang CI, there is no global + // `rustc`, and Cargo doesn't offer a convenient way to get the path to + // `rustc`. Fortunately bootstrap sets `RUSTC` for us, which is pointing + // to the stage0 compiler. + // + // Otherwise, if you are running compiletests's tests manually, you + // probably don't have `RUSTC` set, in which case this falls back to the + // global rustc. If your global rustc is too far out of sync with stage0, + // then this may cause confusing errors. Or if for some reason you don't + // have rustc in PATH, that would also fail. + args.push(std::env::var("RUSTC").unwrap_or_else(|_| { + eprintln!( + "warning: RUSTC not set, using global rustc (are you not running via bootstrap?)" + ); + "rustc".to_string() + })); + crate::parse_config(args) + } +} + +fn cfg() -> ConfigBuilder { + ConfigBuilder::default() } fn parse_rs(config: &Config, contents: &str) -> EarlyProps { @@ -115,7 +185,7 @@ fn parse_makefile(config: &Config, contents: &str) -> EarlyProps { #[test] fn should_fail() { - let config = config(); + let config: Config = cfg().build(); let tn = test::DynTestName(String::new()); let p = Path::new("a.rs"); @@ -127,7 +197,7 @@ fn should_fail() { #[test] fn revisions() { - let config = config(); + let config: Config = cfg().build(); assert_eq!(parse_rs(&config, "// revisions: a b c").revisions, vec!["a", "b", "c"],); assert_eq!( @@ -138,7 +208,7 @@ fn revisions() { #[test] fn aux_build() { - let config = config(); + let config: Config = cfg().build(); assert_eq!( parse_rs( @@ -155,36 +225,31 @@ fn aux_build() { #[test] fn no_system_llvm() { - let mut config = config(); - - config.system_llvm = false; + let config: Config = cfg().system_llvm(false).build(); assert!(!check_ignore(&config, "// no-system-llvm")); - config.system_llvm = true; + let config: Config = cfg().system_llvm(true).build(); assert!(check_ignore(&config, "// no-system-llvm")); } #[test] fn llvm_version() { - let mut config = config(); - - config.llvm_version = Some(80102); + let config: Config = cfg().llvm_version("8.1.2").build(); assert!(check_ignore(&config, "// min-llvm-version: 9.0")); - config.llvm_version = Some(90001); + let config: Config = cfg().llvm_version("9.0.1").build(); assert!(check_ignore(&config, "// min-llvm-version: 9.2")); - config.llvm_version = Some(90301); + let config: Config = cfg().llvm_version("9.3.1").build(); assert!(!check_ignore(&config, "// min-llvm-version: 9.2")); - config.llvm_version = Some(100000); + let config: Config = cfg().llvm_version("10.0.0").build(); assert!(!check_ignore(&config, "// min-llvm-version: 9.0")); } #[test] fn ignore_target() { - let mut config = config(); - config.target = "x86_64-unknown-linux-gnu".to_owned(); + let config: Config = cfg().target("x86_64-unknown-linux-gnu").build(); assert!(check_ignore(&config, "// ignore-x86_64-unknown-linux-gnu")); assert!(check_ignore(&config, "// ignore-x86_64")); @@ -200,8 +265,7 @@ fn ignore_target() { #[test] fn only_target() { - let mut config = config(); - config.target = "x86_64-pc-windows-gnu".to_owned(); + let config: Config = cfg().target("x86_64-pc-windows-gnu").build(); assert!(check_ignore(&config, "// only-x86")); assert!(check_ignore(&config, "// only-linux")); @@ -217,8 +281,7 @@ fn only_target() { #[test] fn stage() { - let mut config = config(); - config.stage_id = "stage1-x86_64-unknown-linux-gnu".to_owned(); + let config: Config = cfg().stage_id("stage1-x86_64-unknown-linux-gnu").build(); assert!(check_ignore(&config, "// ignore-stage1")); assert!(!check_ignore(&config, "// ignore-stage2")); @@ -226,18 +289,16 @@ fn stage() { #[test] fn cross_compile() { - let mut config = config(); - config.host = "x86_64-apple-darwin".to_owned(); - config.target = "wasm32-unknown-unknown".to_owned(); + let config: Config = cfg().host("x86_64-apple-darwin").target("wasm32-unknown-unknown").build(); assert!(check_ignore(&config, "// ignore-cross-compile")); - config.target = config.host.clone(); + let config: Config = cfg().host("x86_64-apple-darwin").target("x86_64-apple-darwin").build(); assert!(!check_ignore(&config, "// ignore-cross-compile")); } #[test] fn debugger() { - let mut config = config(); + let mut config = cfg().build(); config.debugger = None; assert!(!check_ignore(&config, "// ignore-cdb")); @@ -253,27 +314,24 @@ fn debugger() { #[test] fn git_hash() { - let mut config = config(); - config.git_hash = false; + let config: Config = cfg().git_hash(false).build(); assert!(check_ignore(&config, "// needs-git-hash")); - config.git_hash = true; + let config: Config = cfg().git_hash(true).build(); assert!(!check_ignore(&config, "// needs-git-hash")); } #[test] fn sanitizers() { - let mut config = config(); - // Target that supports all sanitizers: - config.target = "x86_64-unknown-linux-gnu".to_owned(); + let config: Config = cfg().target("x86_64-unknown-linux-gnu").build(); assert!(!check_ignore(&config, "// needs-sanitizer-address")); assert!(!check_ignore(&config, "// needs-sanitizer-leak")); assert!(!check_ignore(&config, "// needs-sanitizer-memory")); assert!(!check_ignore(&config, "// needs-sanitizer-thread")); // Target that doesn't support sanitizers: - config.target = "wasm32-unknown-emscripten".to_owned(); + let config: Config = cfg().target("wasm32-unknown-emscripten").build(); assert!(check_ignore(&config, "// needs-sanitizer-address")); assert!(check_ignore(&config, "// needs-sanitizer-leak")); assert!(check_ignore(&config, "// needs-sanitizer-memory")); @@ -291,8 +349,7 @@ fn asm_support() { ("i686-unknown-netbsd", true), ]; for (target, has_asm) in asms { - let mut config = config(); - config.target = target.to_string(); + let config = cfg().target(target).build(); assert_eq!(config.has_asm_support(), has_asm); assert_eq!(check_ignore(&config, "// needs-asm-support"), !has_asm) } @@ -300,8 +357,7 @@ fn asm_support() { #[test] fn channel() { - let mut config = config(); - config.channel = "beta".into(); + let config: Config = cfg().channel("beta").build(); assert!(check_ignore(&config, "// ignore-beta")); assert!(check_ignore(&config, "// only-nightly")); @@ -330,7 +386,7 @@ fn test_extract_version_range() { #[test] #[should_panic(expected = "Duplicate revision: `rpass1` in line ` rpass1 rpass1`")] fn test_duplicate_revisions() { - let config = config(); + let config: Config = cfg().build(); parse_rs(&config, "// revisions: rpass1 rpass1"); } @@ -345,8 +401,7 @@ fn ignore_arch() { ("thumbv7m-none-eabi", "thumb"), ]; for (target, arch) in archs { - let mut config = config(); - config.target = target.to_string(); + let config: Config = cfg().target(target).build(); assert!(config.matches_arch(arch), "{target} {arch}"); assert!(check_ignore(&config, &format!("// ignore-{arch}"))); } @@ -361,8 +416,7 @@ fn matches_os() { ("x86_64-unknown-none", "none"), ]; for (target, os) in oss { - let mut config = config(); - config.target = target.to_string(); + let config = cfg().target(target).build(); assert!(config.matches_os(os), "{target} {os}"); assert!(check_ignore(&config, &format!("// ignore-{os}"))); } @@ -376,8 +430,7 @@ fn matches_env() { ("arm-unknown-linux-musleabi", "musl"), ]; for (target, env) in envs { - let mut config = config(); - config.target = target.to_string(); + let config: Config = cfg().target(target).build(); assert!(config.matches_env(env), "{target} {env}"); assert!(check_ignore(&config, &format!("// ignore-{env}"))); } @@ -391,8 +444,7 @@ fn matches_abi() { ("arm-unknown-linux-gnueabi", "eabi"), ]; for (target, abi) in abis { - let mut config = config(); - config.target = target.to_string(); + let config: Config = cfg().target(target).build(); assert!(config.matches_abi(abi), "{target} {abi}"); assert!(check_ignore(&config, &format!("// ignore-{abi}"))); } @@ -408,8 +460,7 @@ fn is_big_endian() { ("powerpc64-unknown-linux-gnu", true), ]; for (target, is_big) in endians { - let mut config = config(); - config.target = target.to_string(); + let config = cfg().target(target).build(); assert_eq!(config.is_big_endian(), is_big, "{target} {is_big}"); assert_eq!(check_ignore(&config, "// ignore-endian-big"), is_big); } @@ -424,8 +475,7 @@ fn pointer_width() { ("msp430-none-elf", 16), ]; for (target, width) in widths { - let mut config = config(); - config.target = target.to_string(); + let config: Config = cfg().target(target).build(); assert_eq!(config.get_pointer_width(), width, "{target} {width}"); assert_eq!(check_ignore(&config, "// ignore-16bit"), width == 16); assert_eq!(check_ignore(&config, "// ignore-32bit"), width == 32); @@ -456,8 +506,7 @@ fn wasm_special() { ("wasm64-unknown-unknown", "wasm64", true), ]; for (target, pattern, ignore) in ignores { - let mut config = config(); - config.target = target.to_string(); + let config: Config = cfg().target(target).build(); assert_eq!( check_ignore(&config, &format!("// ignore-{pattern}")), ignore, @@ -476,8 +525,7 @@ fn families() { ("wasm32-unknown-emscripten", "unix"), ]; for (target, family) in families { - let mut config = config(); - config.target = target.to_string(); + let config: Config = cfg().target(target).build(); assert!(config.matches_family(family)); let other = if family == "windows" { "unix" } else { "windows" }; assert!(!config.matches_family(other)); -- cgit 1.4.1-3-g733a5 From 64e27cb4d9eb41928ca959a616e06d2e9c4c3fdb Mon Sep 17 00:00:00 2001 From: Tomasz Miąsko Date: Sat, 9 Sep 2023 00:00:00 +0000 Subject: compiletest: load supported sanitizers from target spec --- src/tools/compiletest/src/common.rs | 18 +++++++ src/tools/compiletest/src/header/needs.rs | 25 ++++----- src/tools/compiletest/src/util.rs | 89 ------------------------------- 3 files changed, 31 insertions(+), 101 deletions(-) (limited to 'src/tools') diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index b91d5a958bb..ee17953f96f 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -141,6 +141,22 @@ impl PanicStrategy { } } +#[derive(Clone, Debug, PartialEq, serde::Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum Sanitizer { + Address, + Cfi, + Kcfi, + KernelAddress, + Leak, + Memory, + Memtag, + Safestack, + ShadowCallStack, + Thread, + Hwaddress, +} + /// Configuration for compiletest #[derive(Debug, Default, Clone)] pub struct Config { @@ -560,6 +576,8 @@ pub struct TargetCfg { pub(crate) panic: PanicStrategy, #[serde(default)] pub(crate) dynamic_linking: bool, + #[serde(rename = "supported-sanitizers", default)] + pub(crate) sanitizers: Vec, } impl TargetCfg { diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index 62364ede47b..cb04b6f756f 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -1,4 +1,4 @@ -use crate::common::{Config, Debugger}; +use crate::common::{Config, Debugger, Sanitizer}; use crate::header::IgnoreDecision; use crate::util; @@ -220,19 +220,20 @@ impl CachedNeedsConditions { path.iter().any(|dir| dir.join("x86_64-w64-mingw32-dlltool").is_file()); let target = &&*config.target; + let sanitizers = &config.target_cfg().sanitizers; Self { sanitizer_support: std::env::var_os("RUSTC_SANITIZER_SUPPORT").is_some(), - sanitizer_address: util::ASAN_SUPPORTED_TARGETS.contains(target), - sanitizer_cfi: util::CFI_SUPPORTED_TARGETS.contains(target), - sanitizer_kcfi: util::KCFI_SUPPORTED_TARGETS.contains(target), - sanitizer_kasan: util::KASAN_SUPPORTED_TARGETS.contains(target), - sanitizer_leak: util::LSAN_SUPPORTED_TARGETS.contains(target), - sanitizer_memory: util::MSAN_SUPPORTED_TARGETS.contains(target), - sanitizer_thread: util::TSAN_SUPPORTED_TARGETS.contains(target), - sanitizer_hwaddress: util::HWASAN_SUPPORTED_TARGETS.contains(target), - sanitizer_memtag: util::MEMTAG_SUPPORTED_TARGETS.contains(target), - sanitizer_shadow_call_stack: util::SHADOWCALLSTACK_SUPPORTED_TARGETS.contains(target), - sanitizer_safestack: util::SAFESTACK_SUPPORTED_TARGETS.contains(target), + sanitizer_address: sanitizers.contains(&Sanitizer::Address), + sanitizer_cfi: sanitizers.contains(&Sanitizer::Cfi), + sanitizer_kcfi: sanitizers.contains(&Sanitizer::Kcfi), + sanitizer_kasan: sanitizers.contains(&Sanitizer::KernelAddress), + sanitizer_leak: sanitizers.contains(&Sanitizer::Leak), + sanitizer_memory: sanitizers.contains(&Sanitizer::Memory), + sanitizer_thread: sanitizers.contains(&Sanitizer::Thread), + sanitizer_hwaddress: sanitizers.contains(&Sanitizer::Hwaddress), + sanitizer_memtag: sanitizers.contains(&Sanitizer::Memtag), + sanitizer_shadow_call_stack: sanitizers.contains(&Sanitizer::ShadowCallStack), + sanitizer_safestack: sanitizers.contains(&Sanitizer::Safestack), profiler_support: std::env::var_os("RUSTC_PROFILER_SUPPORT").is_some(), xray: util::XRAY_SUPPORTED_TARGETS.contains(target), diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 02648fe5c29..7a5cab4f68b 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -9,93 +9,6 @@ use tracing::*; #[cfg(test)] mod tests; -pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[ - "aarch64-apple-darwin", - "aarch64-apple-ios", - "aarch64-apple-ios-sim", - "aarch64-apple-ios-macabi", - "aarch64-unknown-fuchsia", - "aarch64-linux-android", - "aarch64-unknown-linux-gnu", - "arm-linux-androideabi", - "armv7-linux-androideabi", - "i686-linux-android", - "i686-unknown-linux-gnu", - "x86_64-apple-darwin", - "x86_64-apple-ios", - "x86_64-apple-ios-macabi", - "x86_64-unknown-fuchsia", - "x86_64-linux-android", - "x86_64-unknown-freebsd", - "x86_64-unknown-linux-gnu", - "s390x-unknown-linux-gnu", -]; - -// FIXME(rcvalle): More targets are likely supported. -pub const CFI_SUPPORTED_TARGETS: &[&str] = &[ - "aarch64-apple-darwin", - "aarch64-unknown-fuchsia", - "aarch64-linux-android", - "aarch64-unknown-freebsd", - "aarch64-unknown-linux-gnu", - "x86_64-apple-darwin", - "x86_64-unknown-fuchsia", - "x86_64-pc-solaris", - "x86_64-unknown-freebsd", - "x86_64-unknown-illumos", - "x86_64-unknown-linux-gnu", - "x86_64-unknown-linux-musl", - "x86_64-unknown-netbsd", -]; - -pub const KCFI_SUPPORTED_TARGETS: &[&str] = &["aarch64-linux-none", "x86_64-linux-none"]; - -pub const KASAN_SUPPORTED_TARGETS: &[&str] = &[ - "aarch64-unknown-none", - "riscv64gc-unknown-none-elf", - "riscv64imac-unknown-none-elf", - "x86_64-unknown-none", -]; - -pub const LSAN_SUPPORTED_TARGETS: &[&str] = &[ - // FIXME: currently broken, see #88132 - // "aarch64-apple-darwin", - "aarch64-unknown-linux-gnu", - "x86_64-apple-darwin", - "x86_64-apple-ios-macabi", - "x86_64-unknown-linux-gnu", - "s390x-unknown-linux-gnu", -]; - -pub const MSAN_SUPPORTED_TARGETS: &[&str] = &[ - "aarch64-unknown-linux-gnu", - "x86_64-unknown-freebsd", - "x86_64-unknown-linux-gnu", - "s390x-unknown-linux-gnu", -]; - -pub const TSAN_SUPPORTED_TARGETS: &[&str] = &[ - "aarch64-apple-darwin", - "aarch64-apple-ios", - "aarch64-apple-ios-sim", - "aarch64-apple-ios-macabi", - "aarch64-unknown-linux-gnu", - "x86_64-apple-darwin", - "x86_64-apple-ios", - "x86_64-apple-ios-macabi", - "x86_64-unknown-freebsd", - "x86_64-unknown-linux-gnu", - "s390x-unknown-linux-gnu", -]; - -pub const HWASAN_SUPPORTED_TARGETS: &[&str] = - &["aarch64-linux-android", "aarch64-unknown-linux-gnu"]; - -pub const MEMTAG_SUPPORTED_TARGETS: &[&str] = - &["aarch64-linux-android", "aarch64-unknown-linux-gnu"]; - -pub const SHADOWCALLSTACK_SUPPORTED_TARGETS: &[&str] = &["aarch64-linux-android"]; - pub const XRAY_SUPPORTED_TARGETS: &[&str] = &[ "aarch64-linux-android", "aarch64-unknown-linux-gnu", @@ -109,8 +22,6 @@ pub const XRAY_SUPPORTED_TARGETS: &[&str] = &[ "x86_64-unknown-openbsd", ]; -pub const SAFESTACK_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"]; - pub fn make_new_path(path: &str) -> String { assert!(cfg!(windows)); // Windows just uses PATH as the library search path, so we have to -- cgit 1.4.1-3-g733a5 From 34c248d31f8351e33e597abcea2a3bffff653a4d Mon Sep 17 00:00:00 2001 From: Tomasz Miąsko Date: Sun, 10 Sep 2023 00:00:00 +0000 Subject: compiletest: load supports-xray from target spec --- src/tools/compiletest/src/common.rs | 2 ++ src/tools/compiletest/src/header/needs.rs | 3 +-- src/tools/compiletest/src/util.rs | 13 ------------- 3 files changed, 3 insertions(+), 15 deletions(-) (limited to 'src/tools') diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index ee17953f96f..ba273489eb8 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -578,6 +578,8 @@ pub struct TargetCfg { pub(crate) dynamic_linking: bool, #[serde(rename = "supported-sanitizers", default)] pub(crate) sanitizers: Vec, + #[serde(rename = "supports-xray", default)] + pub(crate) xray: bool, } impl TargetCfg { diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index cb04b6f756f..1113721fff6 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -1,6 +1,5 @@ use crate::common::{Config, Debugger, Sanitizer}; use crate::header::IgnoreDecision; -use crate::util; pub(super) fn handle_needs( cache: &CachedNeedsConditions, @@ -235,7 +234,7 @@ impl CachedNeedsConditions { sanitizer_shadow_call_stack: sanitizers.contains(&Sanitizer::ShadowCallStack), sanitizer_safestack: sanitizers.contains(&Sanitizer::Safestack), profiler_support: std::env::var_os("RUSTC_PROFILER_SUPPORT").is_some(), - xray: util::XRAY_SUPPORTED_TARGETS.contains(target), + xray: config.target_cfg().xray, // For tests using the `needs-rust-lld` directive (e.g. for `-Zgcc-ld=lld`), we need to find // whether `rust-lld` is present in the compiler under test. diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 7a5cab4f68b..8f9425eb071 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -9,19 +9,6 @@ use tracing::*; #[cfg(test)] mod tests; -pub const XRAY_SUPPORTED_TARGETS: &[&str] = &[ - "aarch64-linux-android", - "aarch64-unknown-linux-gnu", - "aarch64-unknown-linux-musl", - "x86_64-linux-android", - "x86_64-unknown-freebsd", - "x86_64-unknown-linux-gnu", - "x86_64-unknown-linux-musl", - "x86_64-unknown-netbsd", - "x86_64-unknown-none-linuxkernel", - "x86_64-unknown-openbsd", -]; - pub fn make_new_path(path: &str) -> String { assert!(cfg!(windows)); // Windows just uses PATH as the library search path, so we have to -- cgit 1.4.1-3-g733a5 From e6cd29d06e48186562eefe6007854ca9776e6e8f Mon Sep 17 00:00:00 2001 From: The Miri Conjob Bot Date: Thu, 21 Sep 2023 05:40:21 +0000 Subject: fmt --- src/tools/miri/src/shims/backtrace.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index 836cab3ac9d..ee2edd462d1 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -88,10 +88,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_pointer(ptr, &place)?; } - this.write_immediate( - Immediate::new_slice(alloc.ptr(), len, this), - dest, - )?; + this.write_immediate(Immediate::new_slice(alloc.ptr(), len, this), dest)?; } // storage for pointers is allocated by the caller 1 => { -- cgit 1.4.1-3-g733a5 From 96a85d67fd0e986ba8f9ee2207f3c916f46b4bb1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 21 Sep 2023 07:46:41 +0200 Subject: update lockfile --- src/tools/miri/Cargo.lock | 58 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 11 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index ca5b6d22515..8cd2df8b5c5 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -70,6 +70,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + [[package]] name = "bstr" version = "1.4.0" @@ -201,12 +207,12 @@ checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] name = "env_logger" -version = "0.9.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ - "atty", "humantime", + "is-terminal", "log", "regex", "termcolor", @@ -316,6 +322,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi 0.3.1", + "rustix 0.38.14", + "windows-sys 0.48.0", +] + [[package]] name = "itoa" version = "1.0.6" @@ -330,9 +347,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.142" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "libffi" @@ -369,6 +386,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" +[[package]] +name = "linux-raw-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" + [[package]] name = "lock_api" version = "0.4.9" @@ -454,7 +477,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "static_assertions", @@ -581,7 +604,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -590,7 +613,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -655,11 +678,24 @@ version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.7", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" +dependencies = [ + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys 0.4.7", "windows-sys 0.48.0", ] @@ -756,7 +792,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix", + "rustix 0.37.19", "windows-sys 0.45.0", ] -- cgit 1.4.1-3-g733a5 From e018f49d4597cc5575703e3ff1d53a8cba11757a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 21 Sep 2023 08:02:58 +0200 Subject: remove atty dependency by updating colored --- src/tools/miri/Cargo.lock | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index 8cd2df8b5c5..f253d71e50d 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -32,17 +32,6 @@ version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -161,13 +150,13 @@ dependencies = [ [[package]] name = "colored" -version = "2.0.0" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" dependencies = [ - "atty", + "is-terminal", "lazy_static", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -275,15 +264,6 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.1" @@ -317,7 +297,7 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "libc", "windows-sys 0.48.0", ] @@ -328,7 +308,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "rustix 0.38.14", "windows-sys 0.48.0", ] -- cgit 1.4.1-3-g733a5 From ed8fbcb05910f4439ec572bd163cc99a3603e378 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 21 Sep 2023 08:03:45 +0200 Subject: fix clippy lints --- src/tools/miri/src/shims/x86/sse2.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/tools') diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index b68690a835c..d3bfb53afd2 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -426,8 +426,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let right_res = i8::try_from(right).unwrap_or(if right < 0 { i8::MIN } else { i8::MAX }); - this.write_scalar(Scalar::from_i8(left_res.try_into().unwrap()), &left_dest)?; - this.write_scalar(Scalar::from_i8(right_res.try_into().unwrap()), &right_dest)?; + this.write_scalar(Scalar::from_i8(left_res), &left_dest)?; + this.write_scalar(Scalar::from_i8(right_res), &right_dest)?; } } // Used to implement the _mm_packus_epi16 function. @@ -487,11 +487,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let right_res = i16::try_from(right).unwrap_or(if right < 0 { i16::MIN } else { i16::MAX }); - this.write_scalar(Scalar::from_i16(left_res.try_into().unwrap()), &left_dest)?; - this.write_scalar( - Scalar::from_i16(right_res.try_into().unwrap()), - &right_dest, - )?; + this.write_scalar(Scalar::from_i16(left_res), &left_dest)?; + this.write_scalar(Scalar::from_i16(right_res), &right_dest)?; } } // Used to implement _mm_min_sd and _mm_max_sd functions. -- cgit 1.4.1-3-g733a5