From bd71c26af0d5bcbff111adb6c0f8f196930f5164 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 3 Jun 2023 00:41:50 -0700 Subject: [PATCH 1/3] Promote unchecked_add/sub/mul/shl/shr to mir::BinOp --- .../src/codegen_i128.rs | 9 +- compiler/rustc_codegen_cranelift/src/num.rs | 16 +- compiler/rustc_codegen_ssa/src/common.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 33 ++++- .../src/interpret/operator.rs | 66 ++++++--- .../rustc_const_eval/src/interpret/step.rs | 8 +- .../src/transform/promote_consts.rs | 7 +- .../src/transform/validate.rs | 20 ++- compiler/rustc_middle/src/mir/syntax.rs | 13 ++ compiler/rustc_middle/src/mir/tcx.rs | 18 ++- .../src/lower_intrinsics.rs | 12 +- compiler/rustc_smir/src/rustc_smir/mod.rs | 5 + .../rustc_smir/src/stable_mir/mir/body.rs | 5 + compiler/rustc_ty_utils/src/consts.rs | 5 +- ...unchecked_shl_unsigned_smaller.Inline.diff | 44 +++--- ..._shl_unsigned_smaller.PreCodegen.after.mir | 14 +- ...s.unchecked_shr_signed_smaller.Inline.diff | 44 +++--- ...ed_shr_signed_smaller.PreCodegen.after.mir | 14 +- ...r_intrinsics.align_of.LowerIntrinsics.diff | 2 +- ...wer_intrinsics.assume.LowerIntrinsics.diff | 2 +- ...trinsics.discriminant.LowerIntrinsics.diff | 14 +- ...f_copy_nonoverlapping.LowerIntrinsics.diff | 2 +- ...wer_intrinsics.forget.LowerIntrinsics.diff | 2 +- ..._intrinsics.non_const.LowerIntrinsics.diff | 2 +- ...insics.option_payload.LowerIntrinsics.diff | 4 +- ...intrinsics.ptr_offset.LowerIntrinsics.diff | 2 +- ...ad_via_copy_primitive.LowerIntrinsics.diff | 2 +- ..._via_copy_uninhabited.LowerIntrinsics.diff | 2 +- tests/mir-opt/lower_intrinsics.rs | 5 + ...er_intrinsics.size_of.LowerIntrinsics.diff | 2 +- ...s.transmute_inhabited.LowerIntrinsics.diff | 2 +- ...ics.transmute_ref_dst.LowerIntrinsics.diff | 2 +- ...te_to_box_uninhabited.LowerIntrinsics.diff | 2 +- ...te_to_mut_uninhabited.LowerIntrinsics.diff | 2 +- ...te_to_ref_uninhabited.LowerIntrinsics.diff | 2 +- ...transmute_uninhabited.LowerIntrinsics.diff | 2 +- ..._intrinsics.unchecked.LowerIntrinsics.diff | 139 ++++++++++++++++-- ...ntrinsics.unreachable.LowerIntrinsics.diff | 2 +- ...rinsics.with_overflow.LowerIntrinsics.diff | 6 +- ...write_via_move_string.LowerIntrinsics.diff | 2 +- ...ecked_ops.checked_shl.PreCodegen.after.mir | 50 +++---- ...t_unchecked_mut_range.PreCodegen.after.mir | 72 ++++----- 42 files changed, 433 insertions(+), 228 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs index f751d8c179db5..13568b198db1b 100644 --- a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs +++ b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs @@ -22,8 +22,8 @@ pub(crate) fn maybe_codegen<'tcx>( match bin_op { BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => None, - BinOp::Add | BinOp::Sub => None, - BinOp::Mul => { + BinOp::Add | BinOp::AddUnchecked | BinOp::Sub | BinOp::SubUnchecked => None, + BinOp::Mul | BinOp::MulUnchecked => { let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)]; let ret_val = fx.lib_call( "__multi3", @@ -69,7 +69,7 @@ pub(crate) fn maybe_codegen<'tcx>( } } BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => None, - BinOp::Shl | BinOp::Shr => None, + BinOp::Shl | BinOp::ShlUnchecked | BinOp::Shr | BinOp::ShrUnchecked => None, } } @@ -131,9 +131,10 @@ pub(crate) fn maybe_codegen_checked<'tcx>( fx.lib_call(name, param_types, vec![], &args); Some(out_place.to_cvalue(fx)) } + BinOp::AddUnchecked | BinOp::SubUnchecked | BinOp::MulUnchecked => unreachable!(), BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"), BinOp::Div | BinOp::Rem => unreachable!(), BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => unreachable!(), - BinOp::Shl | BinOp::Shr => unreachable!(), + BinOp::Shl | BinOp::ShlUnchecked | BinOp::Shr | BinOp::ShrUnchecked => unreachable!(), } } diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs index ba53e01c7a212..ac1a6cce096f4 100644 --- a/compiler/rustc_codegen_cranelift/src/num.rs +++ b/compiler/rustc_codegen_cranelift/src/num.rs @@ -128,10 +128,11 @@ pub(crate) fn codegen_int_binop<'tcx>( let rhs = in_rhs.load_scalar(fx); let b = fx.bcx.ins(); + // FIXME trap on overflow for the Unchecked versions let val = match bin_op { - BinOp::Add => b.iadd(lhs, rhs), - BinOp::Sub => b.isub(lhs, rhs), - BinOp::Mul => b.imul(lhs, rhs), + BinOp::Add | BinOp::AddUnchecked => b.iadd(lhs, rhs), + BinOp::Sub | BinOp::SubUnchecked => b.isub(lhs, rhs), + BinOp::Mul | BinOp::MulUnchecked => b.imul(lhs, rhs), BinOp::Div => { if signed { b.sdiv(lhs, rhs) @@ -149,16 +150,19 @@ pub(crate) fn codegen_int_binop<'tcx>( BinOp::BitXor => b.bxor(lhs, rhs), BinOp::BitAnd => b.band(lhs, rhs), BinOp::BitOr => b.bor(lhs, rhs), - BinOp::Shl => b.ishl(lhs, rhs), - BinOp::Shr => { + BinOp::Shl | BinOp::ShlUnchecked => b.ishl(lhs, rhs), + BinOp::Shr | BinOp::ShrUnchecked => { if signed { b.sshr(lhs, rhs) } else { b.ushr(lhs, rhs) } } + BinOp::Offset => unreachable!("Offset is not an integer operation"), // Compare binops handles by `codegen_binop`. - _ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty), + BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge => { + unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty); + } }; CValue::by_val(val, in_lhs.layout()) diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index e1abb73a504a3..5a68075991f16 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -132,7 +132,7 @@ pub fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // all shifts). For 32- and 64-bit types, this matches the semantics // of Java. (See related discussion on #1877 and #10183.) -pub fn build_unchecked_lshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( +pub fn build_masked_lshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, lhs: Bx::Value, rhs: Bx::Value, @@ -143,7 +143,7 @@ pub fn build_unchecked_lshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx.shl(lhs, rhs) } -pub fn build_unchecked_rshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( +pub fn build_masked_rshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, lhs_t: Ty<'tcx>, lhs: Bx::Value, diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 5241a5aee008e..2d3d0ec68b81c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -798,6 +798,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.add(lhs, rhs) } } + mir::BinOp::AddUnchecked => { + if is_signed { + bx.unchecked_sadd(lhs, rhs) + } else { + bx.unchecked_uadd(lhs, rhs) + } + } mir::BinOp::Sub => { if is_float { bx.fsub(lhs, rhs) @@ -805,6 +812,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.sub(lhs, rhs) } } + mir::BinOp::SubUnchecked => { + if is_signed { + bx.unchecked_ssub(lhs, rhs) + } else { + bx.unchecked_usub(lhs, rhs) + } + } mir::BinOp::Mul => { if is_float { bx.fmul(lhs, rhs) @@ -812,6 +826,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.mul(lhs, rhs) } } + mir::BinOp::MulUnchecked => { + if is_signed { + bx.unchecked_smul(lhs, rhs) + } else { + bx.unchecked_umul(lhs, rhs) + } + } mir::BinOp::Div => { if is_float { bx.fdiv(lhs, rhs) @@ -848,8 +869,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.inbounds_gep(llty, lhs, &[rhs]) } } - mir::BinOp::Shl => common::build_unchecked_lshift(bx, lhs, rhs), - mir::BinOp::Shr => common::build_unchecked_rshift(bx, input_ty, lhs, rhs), + mir::BinOp::Shl => common::build_masked_lshift(bx, lhs, rhs), + mir::BinOp::ShlUnchecked => { + let rhs = base::cast_shift_expr_rhs(bx, lhs, rhs); + bx.shl(lhs, rhs) + } + mir::BinOp::Shr => common::build_masked_rshift(bx, input_ty, lhs, rhs), + mir::BinOp::ShrUnchecked => { + let rhs = base::cast_shift_expr_rhs(bx, lhs, rhs); + if is_signed { bx.ashr(lhs, rhs) } else { bx.lshr(lhs, rhs) } + } mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 7186148daf0ba..7bca7efdf5a83 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -3,10 +3,13 @@ use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, Ty}; +use rustc_span::symbol::sym; use rustc_target::abi::Abi; use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy}; +use crate::fluent_generated as fluent; + impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Applies the binary operation `op` to the two operands and writes a tuple of the result /// and a boolean signifying the potential overflow to the destination. @@ -139,8 +142,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> { use rustc_middle::mir::BinOp::*; + let throw_ub_on_overflow = match bin_op { + AddUnchecked => Some(sym::unchecked_add), + SubUnchecked => Some(sym::unchecked_sub), + MulUnchecked => Some(sym::unchecked_mul), + ShlUnchecked => Some(sym::unchecked_shl), + ShrUnchecked => Some(sym::unchecked_shr), + _ => None, + }; + // Shift ops can have an RHS with a different numeric type. - if bin_op == Shl || bin_op == Shr { + if matches!(bin_op, Shl | ShlUnchecked | Shr | ShrUnchecked) { let size = u128::from(left_layout.size.bits()); // Even if `r` is signed, we treat it as if it was unsigned (i.e., we use its // zero-extended form). This matches the codegen backend: @@ -155,6 +167,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // integers are maximally 128bits wide, so negative shifts *always* overflow and we have // consistent results for the same value represented at different bit widths. assert!(size <= 128); + let original_r = r; let overflow = r >= size; // The shift offset is implicitly masked to the type size, to make sure this operation // is always defined. This is the one MIR operator that does *not* directly map to a @@ -166,19 +179,28 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let result = if left_layout.abi.is_signed() { let l = self.sign_extend(l, left_layout) as i128; let result = match bin_op { - Shl => l.checked_shl(r).unwrap(), - Shr => l.checked_shr(r).unwrap(), + Shl | ShlUnchecked => l.checked_shl(r).unwrap(), + Shr | ShrUnchecked => l.checked_shr(r).unwrap(), _ => bug!(), }; result as u128 } else { match bin_op { - Shl => l.checked_shl(r).unwrap(), - Shr => l.checked_shr(r).unwrap(), + Shl | ShlUnchecked => l.checked_shl(r).unwrap(), + Shr | ShrUnchecked => l.checked_shr(r).unwrap(), _ => bug!(), } }; let truncated = self.truncate(result, left_layout); + + if overflow && let Some(intrinsic_name) = throw_ub_on_overflow { + throw_ub_custom!( + fluent::const_eval_overflow_shift, + val = original_r, + name = intrinsic_name + ); + } + return Ok((Scalar::from_uint(truncated, left_layout.size), overflow, left_layout.ty)); } @@ -216,9 +238,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Rem if r == 0 => throw_ub!(RemainderByZero), Div => Some(i128::overflowing_div), Rem => Some(i128::overflowing_rem), - Add => Some(i128::overflowing_add), - Sub => Some(i128::overflowing_sub), - Mul => Some(i128::overflowing_mul), + Add | AddUnchecked => Some(i128::overflowing_add), + Sub | SubUnchecked => Some(i128::overflowing_sub), + Mul | MulUnchecked => Some(i128::overflowing_mul), _ => None, }; if let Some(op) = op { @@ -242,11 +264,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // If that truncation loses any information, we have an overflow. let result = result as u128; let truncated = self.truncate(result, left_layout); - return Ok(( - Scalar::from_uint(truncated, size), - oflo || self.sign_extend(truncated, left_layout) != result, - left_layout.ty, - )); + let overflow = oflo || self.sign_extend(truncated, left_layout) != result; + if overflow && let Some(intrinsic_name) = throw_ub_on_overflow { + throw_ub_custom!(fluent::const_eval_overflow, name = intrinsic_name); + } + return Ok((Scalar::from_uint(truncated, size), overflow, left_layout.ty)); } } @@ -263,12 +285,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { BitAnd => (Scalar::from_uint(l & r, size), left_layout.ty), BitXor => (Scalar::from_uint(l ^ r, size), left_layout.ty), - Add | Sub | Mul | Rem | Div => { + Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Rem | Div => { assert!(!left_layout.abi.is_signed()); let op: fn(u128, u128) -> (u128, bool) = match bin_op { - Add => u128::overflowing_add, - Sub => u128::overflowing_sub, - Mul => u128::overflowing_mul, + Add | AddUnchecked => u128::overflowing_add, + Sub | SubUnchecked => u128::overflowing_sub, + Mul | MulUnchecked => u128::overflowing_mul, Div if r == 0 => throw_ub!(DivisionByZero), Rem if r == 0 => throw_ub!(RemainderByZero), Div => u128::overflowing_div, @@ -279,11 +301,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Truncate to target type. // If that truncation loses any information, we have an overflow. let truncated = self.truncate(result, left_layout); - return Ok(( - Scalar::from_uint(truncated, size), - oflo || truncated != result, - left_layout.ty, - )); + let overflow = oflo || truncated != result; + if overflow && let Some(intrinsic_name) = throw_ub_on_overflow { + throw_ub_custom!(fluent::const_eval_overflow, name = intrinsic_name); + } + return Ok((Scalar::from_uint(truncated, size), overflow, left_layout.ty)); } _ => span_bug!( diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 1e60a1e72ea07..050ed291b4fc7 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -16,7 +16,8 @@ use super::{ImmTy, InterpCx, Machine}; fn binop_left_homogeneous(op: mir::BinOp) -> bool { use rustc_middle::mir::BinOp::*; match op { - Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Offset | Shl | Shr => true, + Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Div | Rem | BitXor + | BitAnd | BitOr | Offset | Shl | ShlUnchecked | Shr | ShrUnchecked => true, Eq | Ne | Lt | Le | Gt | Ge => false, } } @@ -26,8 +27,9 @@ fn binop_left_homogeneous(op: mir::BinOp) -> bool { fn binop_right_homogeneous(op: mir::BinOp) -> bool { use rustc_middle::mir::BinOp::*; match op { - Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Eq | Ne | Lt | Le | Gt | Ge => true, - Offset | Shl | Shr => false, + Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Div | Rem | BitXor + | BitAnd | BitOr | Eq | Ne | Lt | Le | Gt | Ge => true, + Offset | Shl | ShlUnchecked | Shr | ShrUnchecked => false, } } diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 0e2d9ee8fb2fb..219a71fa5b5e3 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -572,13 +572,18 @@ impl<'tcx> Validator<'_, 'tcx> { | BinOp::Gt | BinOp::Offset | BinOp::Add + | BinOp::AddUnchecked | BinOp::Sub + | BinOp::SubUnchecked | BinOp::Mul + | BinOp::MulUnchecked | BinOp::BitXor | BinOp::BitAnd | BinOp::BitOr | BinOp::Shl - | BinOp::Shr => {} + | BinOp::ShlUnchecked + | BinOp::Shr + | BinOp::ShrUnchecked => {} } self.validate_operand(lhs)?; diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 3c350e25ba6ec..d421c7a2755ea 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -556,7 +556,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } } - Shl | Shr => { + Shl | ShlUnchecked | Shr | ShrUnchecked => { for x in [a, b] { check_kinds!( x, @@ -601,6 +601,24 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } } + AddUnchecked | SubUnchecked | MulUnchecked => { + for x in [a, b] { + check_kinds!( + x, + "Cannot perform unchecked arithmetic on type {:?}", + ty::Uint(..) | ty::Int(..) + ) + } + if a != b { + self.fail( + location, + format!( + "Cannot perform unchecked arithmetic on unequal types {:?} and {:?}", + a, b + ), + ); + } + } } } Rvalue::CheckedBinaryOp(op, vals) => { diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 1a65f74f4fe22..ddc9fdc9a4239 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1267,10 +1267,16 @@ pub enum UnOp { pub enum BinOp { /// The `+` operator (addition) Add, + /// Like `Add`, but with UB on overflow. (Integers only.) + AddUnchecked, /// The `-` operator (subtraction) Sub, + /// Like `Sub`, but with UB on overflow. (Integers only.) + SubUnchecked, /// The `*` operator (multiplication) Mul, + /// Like `Mul`, but with UB on overflow. (Integers only.) + MulUnchecked, /// The `/` operator (division) /// /// For integer types, division by zero is UB, as is `MIN / -1` for signed. @@ -1296,10 +1302,17 @@ pub enum BinOp { /// /// The offset is truncated to the size of the first operand before shifting. Shl, + /// Like `Shl`, but is UB if the RHS >= LHS::BITS + ShlUnchecked, /// The `>>` operator (shift right) /// /// The offset is truncated to the size of the first operand before shifting. + /// + /// This is an arithmetic shift if the LHS is signed + /// and a logical shift if the LHS is unsigned. Shr, + /// Like `Shl`, but is UB if the RHS >= LHS::BITS + ShrUnchecked, /// The `==` operator (equality) Eq, /// The `<` operator (less than) diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 5ca8241344832..4a16abdd4e38f 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -235,8 +235,11 @@ impl<'tcx> BinOp { // FIXME: handle SIMD correctly match self { &BinOp::Add + | &BinOp::AddUnchecked | &BinOp::Sub + | &BinOp::SubUnchecked | &BinOp::Mul + | &BinOp::MulUnchecked | &BinOp::Div | &BinOp::Rem | &BinOp::BitXor @@ -246,7 +249,11 @@ impl<'tcx> BinOp { assert_eq!(lhs_ty, rhs_ty); lhs_ty } - &BinOp::Shl | &BinOp::Shr | &BinOp::Offset => { + &BinOp::Shl + | &BinOp::ShlUnchecked + | &BinOp::Shr + | &BinOp::ShrUnchecked + | &BinOp::Offset => { lhs_ty // lhs_ty can be != rhs_ty } &BinOp::Eq | &BinOp::Lt | &BinOp::Le | &BinOp::Ne | &BinOp::Ge | &BinOp::Gt => { @@ -293,7 +300,14 @@ impl BinOp { BinOp::Gt => hir::BinOpKind::Gt, BinOp::Le => hir::BinOpKind::Le, BinOp::Ge => hir::BinOpKind::Ge, - BinOp::Offset => unreachable!(), + BinOp::AddUnchecked + | BinOp::SubUnchecked + | BinOp::MulUnchecked + | BinOp::ShlUnchecked + | BinOp::ShrUnchecked + | BinOp::Offset => { + unreachable!() + } } } } diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 3a7d58f712568..ce98e9b0c8432 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -85,8 +85,13 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul + | sym::unchecked_add + | sym::unchecked_sub + | sym::unchecked_mul | sym::unchecked_div - | sym::unchecked_rem => { + | sym::unchecked_rem + | sym::unchecked_shl + | sym::unchecked_shr => { let target = target.unwrap(); let lhs; let rhs; @@ -99,8 +104,13 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { sym::wrapping_add => BinOp::Add, sym::wrapping_sub => BinOp::Sub, sym::wrapping_mul => BinOp::Mul, + sym::unchecked_add => BinOp::AddUnchecked, + sym::unchecked_sub => BinOp::SubUnchecked, + sym::unchecked_mul => BinOp::MulUnchecked, sym::unchecked_div => BinOp::Div, sym::unchecked_rem => BinOp::Rem, + sym::unchecked_shl => BinOp::ShlUnchecked, + sym::unchecked_shr => BinOp::ShrUnchecked, _ => bug!("unexpected intrinsic"), }; block.statements.push(Statement { diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 5572108f49567..96ca3484913b4 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -243,15 +243,20 @@ fn rustc_bin_op_to_bin_op(bin_op: &rustc_middle::mir::BinOp) -> stable_mir::mir: use rustc_middle::mir::BinOp; match bin_op { BinOp::Add => stable_mir::mir::BinOp::Add, + BinOp::AddUnchecked => stable_mir::mir::BinOp::AddUnchecked, BinOp::Sub => stable_mir::mir::BinOp::Sub, + BinOp::SubUnchecked => stable_mir::mir::BinOp::SubUnchecked, BinOp::Mul => stable_mir::mir::BinOp::Mul, + BinOp::MulUnchecked => stable_mir::mir::BinOp::MulUnchecked, BinOp::Div => stable_mir::mir::BinOp::Div, BinOp::Rem => stable_mir::mir::BinOp::Rem, BinOp::BitXor => stable_mir::mir::BinOp::BitXor, BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd, BinOp::BitOr => stable_mir::mir::BinOp::BitOr, BinOp::Shl => stable_mir::mir::BinOp::Shl, + BinOp::ShlUnchecked => stable_mir::mir::BinOp::ShlUnchecked, BinOp::Shr => stable_mir::mir::BinOp::Shr, + BinOp::ShrUnchecked => stable_mir::mir::BinOp::ShrUnchecked, BinOp::Eq => stable_mir::mir::BinOp::Eq, BinOp::Lt => stable_mir::mir::BinOp::Lt, BinOp::Le => stable_mir::mir::BinOp::Le, diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index 6328c35aa5982..52c5e5ec1e871 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -71,15 +71,20 @@ pub enum AssertMessage { #[derive(Clone, Debug)] pub enum BinOp { Add, + AddUnchecked, Sub, + SubUnchecked, Mul, + MulUnchecked, Div, Rem, BitXor, BitAnd, BitOr, Shl, + ShlUnchecked, Shr, + ShrUnchecked, Eq, Lt, Le, diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index ce77df0df5dcf..387adda8f579f 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -78,8 +78,9 @@ pub(crate) fn destructure_const<'tcx>( fn check_binop(op: mir::BinOp) -> bool { use mir::BinOp::*; match op { - Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr | Eq | Lt | Le | Ne - | Ge | Gt => true, + Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Div | Rem | BitXor + | BitAnd | BitOr | Shl | ShlUnchecked | Shr | ShrUnchecked | Eq | Lt | Le | Ne | Ge + | Gt => true, Offset => false, } } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff index e82e3f1881153..5d8fe44bc5964 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff @@ -75,70 +75,64 @@ + _9 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _8 = Gt(_4, move _9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ switchInt(move _8) -> [0: bb2, otherwise: bb1]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { -+ StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 - StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 - return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 -+ } -+ -+ bb2: { + _7 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: TryFromIntError, val: Value() } -+ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb3; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + -+ bb3: { ++ bb2: { + StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _10 = _4 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _7 = Result::::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb3; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + -+ bb4: { ++ bb3: { + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _11 = discriminant(_7); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL -+ switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _11) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + -+ bb5: { ++ bb4: { + _6 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL -+ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb7; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + -+ bb6: { ++ bb5: { + unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + -+ bb7: { ++ bb6: { + _12 = move ((_7 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _6 = Option::::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL -+ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb7; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + -+ bb8: { ++ bb7: { + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _14) -> [1: bb8, otherwise: bb5]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + } + -+ bb9: { ++ bb8: { + _5 = move ((_6 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _0 = unchecked_shl::(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ // mir::Constant -+ // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::}, val: Value() } ++ _0 = ShlUnchecked(_3, move _5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 + StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 + return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 } } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir index 8fa4fdaa49aed..fd90cbd654f15 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir @@ -87,7 +87,7 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { StorageDead(_4); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL _7 = discriminant(_6); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb8]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb4: { @@ -106,25 +106,19 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL _10 = discriminant(_9); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - switchInt(move _10) -> [1: bb7, otherwise: bb9]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _10) -> [1: bb7, otherwise: bb8]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL } bb7: { _11 = move ((_9 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _0 = unchecked_shl::(_1, move _11) -> [return: bb8, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::}, val: Value() } - } - - bb8: { + _0 = ShlUnchecked(_1, move _11); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL StorageDead(_11); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 } - bb9: { + bb8: { unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff index f20c7da4747c8..65c6db8a3c48b 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff @@ -75,70 +75,64 @@ + _9 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _8 = Gt(_4, move _9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ switchInt(move _8) -> [0: bb2, otherwise: bb1]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { -+ StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 - StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 - return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 -+ } -+ -+ bb2: { + _7 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: TryFromIntError, val: Value() } -+ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb3; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + -+ bb3: { ++ bb2: { + StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _10 = _4 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _7 = Result::::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb3; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + -+ bb4: { ++ bb3: { + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _11 = discriminant(_7); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL -+ switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _11) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + -+ bb5: { ++ bb4: { + _6 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL -+ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb7; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + -+ bb6: { ++ bb5: { + unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + -+ bb7: { ++ bb6: { + _12 = move ((_7 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _6 = Option::::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL -+ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb7; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + -+ bb8: { ++ bb7: { + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _14) -> [1: bb8, otherwise: bb5]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + } + -+ bb9: { ++ bb8: { + _5 = move ((_6 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _0 = unchecked_shr::(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ // mir::Constant -+ // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::}, val: Value() } ++ _0 = ShrUnchecked(_3, move _5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 + StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 + return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 } } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir index 7f737abb9360d..69543937aa606 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir @@ -87,7 +87,7 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { StorageDead(_4); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL _7 = discriminant(_6); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb8]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb4: { @@ -106,25 +106,19 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL _10 = discriminant(_9); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - switchInt(move _10) -> [1: bb7, otherwise: bb9]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _10) -> [1: bb7, otherwise: bb8]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL } bb7: { _11 = move ((_9 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _0 = unchecked_shr::(_1, move _11) -> [return: bb8, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::}, val: Value() } - } - - bb8: { + _0 = ShrUnchecked(_1, move _11); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL StorageDead(_11); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 } - bb9: { + bb8: { unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } } diff --git a/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff index 3530f4a807f2c..98cfef4442a70 100644 --- a/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff @@ -7,7 +7,7 @@ bb0: { - _0 = std::intrinsics::min_align_of::() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:27:5: 27:40 +- // + span: $DIR/lower_intrinsics.rs:32:5: 32:40 - // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::min_align_of::}, val: Value() } + _0 = AlignOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42 diff --git a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff index 158ce62e209c2..987f927f808a5 100644 --- a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff @@ -11,7 +11,7 @@ StorageLive(_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 - _1 = std::intrinsics::assume(const true) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:112:9: 112:32 +- // + span: $DIR/lower_intrinsics.rs:117:9: 117:32 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(bool) {std::intrinsics::assume}, val: Value() } + assume(const true); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 + goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 diff --git a/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff index 6fc9616d85540..caf47f4c8b49e 100644 --- a/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff @@ -31,7 +31,7 @@ _3 = &(*_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44 - _2 = discriminant_value::(move _3) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:88:5: 88:41 +- // + span: $DIR/lower_intrinsics.rs:93:5: 93:41 - // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a T) -> ::Discriminant {discriminant_value::}, val: Value() } + _2 = discriminant((*_3)); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45 @@ -46,13 +46,13 @@ StorageLive(_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 _19 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 // mir::Constant - // + span: $DIR/lower_intrinsics.rs:89:42: 89:44 + // + span: $DIR/lower_intrinsics.rs:94:42: 94:44 // + literal: Const { ty: &i32, val: Unevaluated(discriminant, [T], Some(promoted[2])) } _7 = &(*_19); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 _6 = &(*_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 - _5 = discriminant_value::(move _6) -> [return: bb2, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:89:5: 89:41 +- // + span: $DIR/lower_intrinsics.rs:94:5: 94:41 - // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a i32) -> ::Discriminant {discriminant_value::}, val: Value() } + _5 = discriminant((*_6)); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 + goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 @@ -67,13 +67,13 @@ StorageLive(_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 _18 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 // mir::Constant - // + span: $DIR/lower_intrinsics.rs:90:42: 90:45 + // + span: $DIR/lower_intrinsics.rs:95:42: 95:45 // + literal: Const { ty: &(), val: Unevaluated(discriminant, [T], Some(promoted[1])) } _11 = &(*_18); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 _10 = &(*_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 - _9 = discriminant_value::<()>(move _10) -> [return: bb3, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:90:5: 90:41 +- // + span: $DIR/lower_intrinsics.rs:95:5: 95:41 - // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a ()) -> <() as DiscriminantKind>::Discriminant {discriminant_value::<()>}, val: Value() } + _9 = discriminant((*_10)); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 + goto -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 @@ -88,13 +88,13 @@ StorageLive(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 _17 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 // mir::Constant - // + span: $DIR/lower_intrinsics.rs:91:42: 91:47 + // + span: $DIR/lower_intrinsics.rs:96:42: 96:47 // + literal: Const { ty: &E, val: Unevaluated(discriminant, [T], Some(promoted[0])) } _15 = &(*_17); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 _14 = &(*_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 - _13 = discriminant_value::(move _14) -> [return: bb4, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:91:5: 91:41 +- // + span: $DIR/lower_intrinsics.rs:96:5: 96:41 - // + literal: Const { ty: for<'a> extern "rust-intrinsic" fn(&'a E) -> ::Discriminant {discriminant_value::}, val: Value() } + _13 = discriminant((*_14)); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 + goto -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 diff --git a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff index 5b870ccf5ee28..818425a306ef4 100644 --- a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff @@ -49,7 +49,7 @@ StorageDead(_9); // scope 3 at $DIR/lower_intrinsics.rs:+4:90: +4:91 - _3 = copy_nonoverlapping::(move _4, move _8, const 0_usize) -> [return: bb1, unwind unreachable]; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:105:9: 105:28 +- // + span: $DIR/lower_intrinsics.rs:110:9: 110:28 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32, *mut i32, usize) {copy_nonoverlapping::}, val: Value() } + copy_nonoverlapping(dst = move _8, src = move _4, count = const 0_usize); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 + goto -> bb1; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 diff --git a/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff index 582a79f48d8c8..61a0ffa7aa87c 100644 --- a/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff @@ -11,7 +11,7 @@ _2 = move _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31 - _0 = std::intrinsics::forget::(move _2) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:32:5: 32:29 +- // + span: $DIR/lower_intrinsics.rs:37:5: 37:29 - // + literal: Const { ty: extern "rust-intrinsic" fn(T) {std::intrinsics::forget::}, val: Value() } + _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32 diff --git a/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff index 81ad97077b428..ee06564df3dbf 100644 --- a/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff @@ -13,7 +13,7 @@ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:18 _1 = std::intrinsics::size_of::; // scope 0 at $DIR/lower_intrinsics.rs:+2:21: +2:51 // mir::Constant - // + span: $DIR/lower_intrinsics.rs:43:21: 43:51 + // + span: $DIR/lower_intrinsics.rs:48:21: 48:51 // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::}, val: Value() } StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14 _2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14 diff --git a/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.diff index edc66e2c75ce4..e9fb25674572c 100644 --- a/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.diff @@ -24,7 +24,7 @@ _4 = &raw const (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:55: +2:56 - _3 = option_payload_ptr::(move _4) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:18: +2:57 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:143:18: 143:54 +- // + span: $DIR/lower_intrinsics.rs:148:18: 148:54 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Option) -> *const usize {option_payload_ptr::}, val: Value() } + _3 = &raw const (((*_4) as Some).0: usize); // scope 1 at $DIR/lower_intrinsics.rs:+2:18: +2:57 + goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:18: +2:57 @@ -37,7 +37,7 @@ _6 = &raw const (*_2); // scope 2 at $DIR/lower_intrinsics.rs:+3:55: +3:56 - _5 = option_payload_ptr::(move _6) -> [return: bb2, unwind unreachable]; // scope 2 at $DIR/lower_intrinsics.rs:+3:18: +3:57 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:144:18: 144:54 +- // + span: $DIR/lower_intrinsics.rs:149:18: 149:54 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Option) -> *const String {option_payload_ptr::}, val: Value() } + _5 = &raw const (((*_6) as Some).0: std::string::String); // scope 2 at $DIR/lower_intrinsics.rs:+3:18: +3:57 + goto -> bb2; // scope 2 at $DIR/lower_intrinsics.rs:+3:18: +3:57 diff --git a/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.diff index 1760efe77d98f..03e8655ed3c32 100644 --- a/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.ptr_offset.LowerIntrinsics.diff @@ -15,7 +15,7 @@ _4 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:33: +1:34 - _0 = offset::<*const i32, isize>(move _3, move _4) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:35 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:150:5: 150:29 +- // + span: $DIR/lower_intrinsics.rs:155:5: 155:29 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32, isize) -> *const i32 {offset::<*const i32, isize>}, val: Value() } + _0 = Offset(move _3, move _4); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:35 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:35 diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.diff index 8583766348a6e..94c47bbc9d9b1 100644 --- a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.diff @@ -13,7 +13,7 @@ _2 = &raw const (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+1:46: +1:47 - _0 = read_via_copy::(move _2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:125:14: 125:45 +- // + span: $DIR/lower_intrinsics.rs:130:14: 130:45 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32) -> i32 {read_via_copy::}, val: Value() } + _0 = (*_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 + goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff index f64bc9dcf620c..92fc9b23eba1d 100644 --- a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.diff @@ -13,7 +13,7 @@ _2 = &raw const (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+1:46: +1:47 - _0 = read_via_copy::(move _2) -> unwind unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:130:14: 130:45 +- // + span: $DIR/lower_intrinsics.rs:135:14: 135:45 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const Never) -> Never {read_via_copy::}, val: Value() } + unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:48 } diff --git a/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs index 30b5c78e647c8..150b13f8d90d0 100644 --- a/tests/mir-opt/lower_intrinsics.rs +++ b/tests/mir-opt/lower_intrinsics.rs @@ -13,8 +13,13 @@ pub fn wrapping(a: i32, b: i32) { // EMIT_MIR lower_intrinsics.unchecked.LowerIntrinsics.diff pub unsafe fn unchecked(a: i32, b: i32) { + let _a = core::intrinsics::unchecked_add(a, b); + let _b = core::intrinsics::unchecked_sub(a, b); + let _c = core::intrinsics::unchecked_mul(a, b); let _x = core::intrinsics::unchecked_div(a, b); let _y = core::intrinsics::unchecked_rem(a, b); + let _i = core::intrinsics::unchecked_shl(a, b); + let _j = core::intrinsics::unchecked_shr(a, b); } // EMIT_MIR lower_intrinsics.size_of.LowerIntrinsics.diff diff --git a/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff index a880df6a5c236..2d72fd748884d 100644 --- a/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff @@ -7,7 +7,7 @@ bb0: { - _0 = std::intrinsics::size_of::() -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:22:5: 22:35 +- // + span: $DIR/lower_intrinsics.rs:27:5: 27:35 - // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::}, val: Value() } + _0 = SizeOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37 diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.diff index cde7c64c57a56..1e50857516ff2 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.diff @@ -13,7 +13,7 @@ _2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+1:34: +1:35 - _0 = transmute::(move _2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:36 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:49:14: 49:33 +- // + span: $DIR/lower_intrinsics.rs:54:14: 54:33 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(std::cmp::Ordering) -> i8 {transmute::}, val: Value() } + _0 = move _2 as i8 (Transmute); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:36 + goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:36 diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.diff index 6fc0f3d3e3fee..096fd1b1ae5d3 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.diff @@ -13,7 +13,7 @@ _2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+1:34: +1:35 - _0 = transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:36 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:59:14: 59:33 +- // + span: $DIR/lower_intrinsics.rs:64:14: 64:33 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&T) -> *const T {transmute::<&T, *const T>}, val: Value() } + _0 = move _2 as *const T (Transmute); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:36 + goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:36 diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.diff index e6887a382a2d6..2fe254b2f2e17 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.diff @@ -12,7 +12,7 @@ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10 - _1 = transmute::>(const 1_usize) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:76:25: 76:44 +- // + span: $DIR/lower_intrinsics.rs:81:25: 81:44 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize) -> Box {transmute::>}, val: Value() } + _1 = const 1_usize as std::boxed::Box (Transmute); // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52 diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.diff index b2a44b7c56114..c7eb4a8c94ec8 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.diff @@ -12,7 +12,7 @@ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10 - _1 = transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:70:25: 70:44 +- // + span: $DIR/lower_intrinsics.rs:75:25: 75:44 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize) -> &mut Never {transmute::}, val: Value() } + _1 = const 1_usize as &mut Never (Transmute); // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52 diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.diff index c49d3aeff70b6..cf98776b66958 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.diff @@ -12,7 +12,7 @@ StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10 - _1 = transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:21: +1:48 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:64:21: 64:40 +- // + span: $DIR/lower_intrinsics.rs:69:21: 69:40 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize) -> &Never {transmute::}, val: Value() } + _1 = const 1_usize as &Never (Transmute); // scope 0 at $DIR/lower_intrinsics.rs:+1:21: +1:48 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:21: +1:48 diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.diff index 06759d74a3205..f9e8076979a2f 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.diff @@ -13,7 +13,7 @@ _2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+1:47: +1:48 - _0 = transmute::<(), Never>(move _2) -> unwind unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:49 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:54:14: 54:46 +- // + span: $DIR/lower_intrinsics.rs:59:14: 59:46 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(()) -> Never {transmute::<(), Never>}, val: Value() } + _0 = move _2 as Never (Transmute); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:49 + unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:49 diff --git a/tests/mir-opt/lower_intrinsics.unchecked.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.unchecked.LowerIntrinsics.diff index 9bb43d850ebf3..ebb5b664a51e4 100644 --- a/tests/mir-opt/lower_intrinsics.unchecked.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.unchecked.LowerIntrinsics.diff @@ -10,11 +10,41 @@ let mut _5: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:49: +1:50 let mut _7: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:46: +2:47 let mut _8: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+2:49: +2:50 + let mut _10: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+3:46: +3:47 + let mut _11: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+3:49: +3:50 + let mut _13: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+4:46: +4:47 + let mut _14: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+4:49: +4:50 + let mut _16: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+5:46: +5:47 + let mut _17: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+5:49: +5:50 + let mut _19: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+6:46: +6:47 + let mut _20: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+6:49: +6:50 + let mut _22: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+7:46: +7:47 + let mut _23: i32; // in scope 0 at $DIR/lower_intrinsics.rs:+7:49: +7:50 scope 1 { - debug _x => _3; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:11 + debug _a => _3; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:11 let _6: i32; // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11 scope 2 { - debug _y => _6; // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + debug _b => _6; // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:11 + let _9: i32; // in scope 2 at $DIR/lower_intrinsics.rs:+3:9: +3:11 + scope 3 { + debug _c => _9; // in scope 3 at $DIR/lower_intrinsics.rs:+3:9: +3:11 + let _12: i32; // in scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:11 + scope 4 { + debug _x => _12; // in scope 4 at $DIR/lower_intrinsics.rs:+4:9: +4:11 + let _15: i32; // in scope 4 at $DIR/lower_intrinsics.rs:+5:9: +5:11 + scope 5 { + debug _y => _15; // in scope 5 at $DIR/lower_intrinsics.rs:+5:9: +5:11 + let _18: i32; // in scope 5 at $DIR/lower_intrinsics.rs:+6:9: +6:11 + scope 6 { + debug _i => _18; // in scope 6 at $DIR/lower_intrinsics.rs:+6:9: +6:11 + let _21: i32; // in scope 6 at $DIR/lower_intrinsics.rs:+7:9: +7:11 + scope 7 { + debug _j => _21; // in scope 7 at $DIR/lower_intrinsics.rs:+7:9: +7:11 + } + } + } + } + } } } @@ -24,11 +54,11 @@ _4 = _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:46: +1:47 StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+1:49: +1:50 _5 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:49: +1:50 -- _3 = unchecked_div::(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:51 +- _3 = unchecked_add::(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:51 - // mir::Constant - // + span: $DIR/lower_intrinsics.rs:16:14: 16:45 -- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i32, i32) -> i32 {unchecked_div::}, val: Value() } -+ _3 = Div(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:51 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i32, i32) -> i32 {unchecked_add::}, val: Value() } ++ _3 = AddUnchecked(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:51 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:51 } @@ -40,21 +70,106 @@ _7 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+2:46: +2:47 StorageLive(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:49: +2:50 _8 = _2; // scope 1 at $DIR/lower_intrinsics.rs:+2:49: +2:50 -- _6 = unchecked_rem::(move _7, move _8) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:51 +- _6 = unchecked_sub::(move _7, move _8) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:51 - // mir::Constant - // + span: $DIR/lower_intrinsics.rs:17:14: 17:45 -- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i32, i32) -> i32 {unchecked_rem::}, val: Value() } -+ _6 = Rem(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:51 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i32, i32) -> i32 {unchecked_sub::}, val: Value() } ++ _6 = SubUnchecked(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:51 + goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:51 } bb2: { StorageDead(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:50: +2:51 StorageDead(_7); // scope 1 at $DIR/lower_intrinsics.rs:+2:50: +2:51 - _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+0:41: +3:2 - StorageDead(_6); // scope 1 at $DIR/lower_intrinsics.rs:+3:1: +3:2 - StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:+3:1: +3:2 - return; // scope 0 at $DIR/lower_intrinsics.rs:+3:2: +3:2 + StorageLive(_9); // scope 2 at $DIR/lower_intrinsics.rs:+3:9: +3:11 + StorageLive(_10); // scope 2 at $DIR/lower_intrinsics.rs:+3:46: +3:47 + _10 = _1; // scope 2 at $DIR/lower_intrinsics.rs:+3:46: +3:47 + StorageLive(_11); // scope 2 at $DIR/lower_intrinsics.rs:+3:49: +3:50 + _11 = _2; // scope 2 at $DIR/lower_intrinsics.rs:+3:49: +3:50 +- _9 = unchecked_mul::(move _10, move _11) -> [return: bb3, unwind unreachable]; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:51 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:18:14: 18:45 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i32, i32) -> i32 {unchecked_mul::}, val: Value() } ++ _9 = MulUnchecked(move _10, move _11); // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:51 ++ goto -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:51 + } + + bb3: { + StorageDead(_11); // scope 2 at $DIR/lower_intrinsics.rs:+3:50: +3:51 + StorageDead(_10); // scope 2 at $DIR/lower_intrinsics.rs:+3:50: +3:51 + StorageLive(_12); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:11 + StorageLive(_13); // scope 3 at $DIR/lower_intrinsics.rs:+4:46: +4:47 + _13 = _1; // scope 3 at $DIR/lower_intrinsics.rs:+4:46: +4:47 + StorageLive(_14); // scope 3 at $DIR/lower_intrinsics.rs:+4:49: +4:50 + _14 = _2; // scope 3 at $DIR/lower_intrinsics.rs:+4:49: +4:50 +- _12 = unchecked_div::(move _13, move _14) -> [return: bb4, unwind unreachable]; // scope 3 at $DIR/lower_intrinsics.rs:+4:14: +4:51 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:19:14: 19:45 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i32, i32) -> i32 {unchecked_div::}, val: Value() } ++ _12 = Div(move _13, move _14); // scope 3 at $DIR/lower_intrinsics.rs:+4:14: +4:51 ++ goto -> bb4; // scope 3 at $DIR/lower_intrinsics.rs:+4:14: +4:51 + } + + bb4: { + StorageDead(_14); // scope 3 at $DIR/lower_intrinsics.rs:+4:50: +4:51 + StorageDead(_13); // scope 3 at $DIR/lower_intrinsics.rs:+4:50: +4:51 + StorageLive(_15); // scope 4 at $DIR/lower_intrinsics.rs:+5:9: +5:11 + StorageLive(_16); // scope 4 at $DIR/lower_intrinsics.rs:+5:46: +5:47 + _16 = _1; // scope 4 at $DIR/lower_intrinsics.rs:+5:46: +5:47 + StorageLive(_17); // scope 4 at $DIR/lower_intrinsics.rs:+5:49: +5:50 + _17 = _2; // scope 4 at $DIR/lower_intrinsics.rs:+5:49: +5:50 +- _15 = unchecked_rem::(move _16, move _17) -> [return: bb5, unwind unreachable]; // scope 4 at $DIR/lower_intrinsics.rs:+5:14: +5:51 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:20:14: 20:45 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i32, i32) -> i32 {unchecked_rem::}, val: Value() } ++ _15 = Rem(move _16, move _17); // scope 4 at $DIR/lower_intrinsics.rs:+5:14: +5:51 ++ goto -> bb5; // scope 4 at $DIR/lower_intrinsics.rs:+5:14: +5:51 + } + + bb5: { + StorageDead(_17); // scope 4 at $DIR/lower_intrinsics.rs:+5:50: +5:51 + StorageDead(_16); // scope 4 at $DIR/lower_intrinsics.rs:+5:50: +5:51 + StorageLive(_18); // scope 5 at $DIR/lower_intrinsics.rs:+6:9: +6:11 + StorageLive(_19); // scope 5 at $DIR/lower_intrinsics.rs:+6:46: +6:47 + _19 = _1; // scope 5 at $DIR/lower_intrinsics.rs:+6:46: +6:47 + StorageLive(_20); // scope 5 at $DIR/lower_intrinsics.rs:+6:49: +6:50 + _20 = _2; // scope 5 at $DIR/lower_intrinsics.rs:+6:49: +6:50 +- _18 = unchecked_shl::(move _19, move _20) -> [return: bb6, unwind unreachable]; // scope 5 at $DIR/lower_intrinsics.rs:+6:14: +6:51 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:21:14: 21:45 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i32, i32) -> i32 {unchecked_shl::}, val: Value() } ++ _18 = ShlUnchecked(move _19, move _20); // scope 5 at $DIR/lower_intrinsics.rs:+6:14: +6:51 ++ goto -> bb6; // scope 5 at $DIR/lower_intrinsics.rs:+6:14: +6:51 + } + + bb6: { + StorageDead(_20); // scope 5 at $DIR/lower_intrinsics.rs:+6:50: +6:51 + StorageDead(_19); // scope 5 at $DIR/lower_intrinsics.rs:+6:50: +6:51 + StorageLive(_21); // scope 6 at $DIR/lower_intrinsics.rs:+7:9: +7:11 + StorageLive(_22); // scope 6 at $DIR/lower_intrinsics.rs:+7:46: +7:47 + _22 = _1; // scope 6 at $DIR/lower_intrinsics.rs:+7:46: +7:47 + StorageLive(_23); // scope 6 at $DIR/lower_intrinsics.rs:+7:49: +7:50 + _23 = _2; // scope 6 at $DIR/lower_intrinsics.rs:+7:49: +7:50 +- _21 = unchecked_shr::(move _22, move _23) -> [return: bb7, unwind unreachable]; // scope 6 at $DIR/lower_intrinsics.rs:+7:14: +7:51 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:22:14: 22:45 +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i32, i32) -> i32 {unchecked_shr::}, val: Value() } ++ _21 = ShrUnchecked(move _22, move _23); // scope 6 at $DIR/lower_intrinsics.rs:+7:14: +7:51 ++ goto -> bb7; // scope 6 at $DIR/lower_intrinsics.rs:+7:14: +7:51 + } + + bb7: { + StorageDead(_23); // scope 6 at $DIR/lower_intrinsics.rs:+7:50: +7:51 + StorageDead(_22); // scope 6 at $DIR/lower_intrinsics.rs:+7:50: +7:51 + _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+0:41: +8:2 + StorageDead(_21); // scope 6 at $DIR/lower_intrinsics.rs:+8:1: +8:2 + StorageDead(_18); // scope 5 at $DIR/lower_intrinsics.rs:+8:1: +8:2 + StorageDead(_15); // scope 4 at $DIR/lower_intrinsics.rs:+8:1: +8:2 + StorageDead(_12); // scope 3 at $DIR/lower_intrinsics.rs:+8:1: +8:2 + StorageDead(_9); // scope 2 at $DIR/lower_intrinsics.rs:+8:1: +8:2 + StorageDead(_6); // scope 1 at $DIR/lower_intrinsics.rs:+8:1: +8:2 + StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:+8:1: +8:2 + return; // scope 0 at $DIR/lower_intrinsics.rs:+8:2: +8:2 } } diff --git a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff index 83c9c508bc0b0..74e889d28fa0b 100644 --- a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff @@ -13,7 +13,7 @@ StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45 - _2 = std::intrinsics::unreachable() -> unwind unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:37:14: 37:43 +- // + span: $DIR/lower_intrinsics.rs:42:14: 42:43 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value() } + unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45 } diff --git a/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.diff index 4ae4466a60038..f802d567efa56 100644 --- a/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.diff @@ -32,7 +32,7 @@ _5 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:53: +1:54 - _3 = add_with_overflow::(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:55 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:118:14: 118:49 +- // + span: $DIR/lower_intrinsics.rs:123:14: 123:49 - // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> (i32, bool) {add_with_overflow::}, val: Value() } + _3 = CheckedAdd(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:55 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:55 @@ -48,7 +48,7 @@ _8 = _2; // scope 1 at $DIR/lower_intrinsics.rs:+2:53: +2:54 - _6 = sub_with_overflow::(move _7, move _8) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:55 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:119:14: 119:49 +- // + span: $DIR/lower_intrinsics.rs:124:14: 124:49 - // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> (i32, bool) {sub_with_overflow::}, val: Value() } + _6 = CheckedSub(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:55 + goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:55 @@ -64,7 +64,7 @@ _11 = _2; // scope 2 at $DIR/lower_intrinsics.rs:+3:53: +3:54 - _9 = mul_with_overflow::(move _10, move _11) -> [return: bb3, unwind unreachable]; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:55 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:120:14: 120:49 +- // + span: $DIR/lower_intrinsics.rs:125:14: 125:49 - // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> (i32, bool) {mul_with_overflow::}, val: Value() } + _9 = CheckedMul(move _10, move _11); // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:55 + goto -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:55 diff --git a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.diff index 2eabd7f626b69..39dd3037bf663 100644 --- a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.diff @@ -17,7 +17,7 @@ _4 = move _2; // scope 1 at $DIR/lower_intrinsics.rs:+1:50: +1:51 - _0 = write_via_move::(move _3, move _4) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:52 - // mir::Constant -- // + span: $DIR/lower_intrinsics.rs:135:14: 135:46 +- // + span: $DIR/lower_intrinsics.rs:140:14: 140:46 - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*mut String, String) {write_via_move::}, val: Value() } + (*_3) = move _4; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:52 + goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:52 diff --git a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir index dff3cbbe76d22..7161fe9bfdc5b 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir @@ -7,10 +7,9 @@ fn checked_shl(_1: u32, _2: u32) -> Option { scope 1 (inlined core::num::::checked_shl) { // at $DIR/checked_ops.rs:16:7: 16:23 debug self => _1; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - let mut _11: u32; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - let mut _12: bool; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _11: bool; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL scope 2 { - debug a => _11; // in scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + debug a => _9; // in scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL debug b => _10; // in scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL } scope 3 (inlined core::num::::overflowing_shl) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL @@ -55,7 +54,7 @@ fn checked_shl(_1: u32, _2: u32) -> Option { } scope 16 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL debug self => _7; // in scope 16 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _13: &std::option::Option; // in scope 16 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _12: &std::option::Option; // in scope 16 at $SRC_DIR/core/src/option.rs:LL:COL scope 17 { debug val => _8; // in scope 17 at $SRC_DIR/core/src/option.rs:LL:COL } @@ -68,7 +67,7 @@ fn checked_shl(_1: u32, _2: u32) -> Option { } } scope 19 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL - debug self => _13; // in scope 19 at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _12; // in scope 19 at $SRC_DIR/core/src/option.rs:LL:COL } } } @@ -81,9 +80,8 @@ fn checked_shl(_1: u32, _2: u32) -> Option { } bb0: { + StorageLive(_9); // scope 0 at $DIR/checked_ops.rs:+1:7: +1:23 StorageLive(_10); // scope 0 at $DIR/checked_ops.rs:+1:7: +1:23 - StorageLive(_11); // scope 0 at $DIR/checked_ops.rs:+1:7: +1:23 - StorageLive(_9); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL StorageLive(_4); // scope 5 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL StorageLive(_3); // scope 5 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL _3 = const 31_u32; // scope 5 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL @@ -98,47 +96,39 @@ fn checked_shl(_1: u32, _2: u32) -> Option { _7 = Option::::Some(move _6); // scope 15 at $SRC_DIR/core/src/result.rs:LL:COL StorageDead(_6); // scope 9 at $SRC_DIR/core/src/num/mod.rs:LL:COL StorageDead(_5); // scope 9 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_13); // scope 9 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_12); // scope 9 at $SRC_DIR/core/src/num/mod.rs:LL:COL _8 = move ((_7 as Some).0: u32); // scope 16 at $SRC_DIR/core/src/option.rs:LL:COL - StorageDead(_13); // scope 9 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_12); // scope 9 at $SRC_DIR/core/src/num/mod.rs:LL:COL StorageDead(_7); // scope 9 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _9 = unchecked_shl::(_1, move _8) -> [return: bb1, unwind unreachable]; // scope 7 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u32, u32) -> u32 {unchecked_shl::}, val: Value() } - } - - bb1: { + _9 = ShlUnchecked(_1, move _8); // scope 7 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL StorageDead(_8); // scope 7 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL StorageDead(_4); // scope 5 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL _10 = Ge(_2, const _); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - _11 = move _9; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageDead(_9); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageLive(_12); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _12 = unlikely(_10) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_11); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _11 = unlikely(_10) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/num/mod.rs:LL:COL // + literal: Const { ty: extern "rust-intrinsic" fn(bool) -> bool {unlikely}, val: Value() } } - bb2: { - switchInt(move _12) -> [0: bb3, otherwise: bb4]; // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + bb1: { + switchInt(move _11) -> [0: bb2, otherwise: bb3]; // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL } - bb3: { - _0 = Option::::Some(_11); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - goto -> bb5; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + bb2: { + _0 = Option::::Some(_9); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + goto -> bb4; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL } - bb4: { + bb3: { _0 = Option::::None; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - goto -> bb5; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + goto -> bb4; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL } - bb5: { - StorageDead(_12); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageDead(_11); // scope 0 at $DIR/checked_ops.rs:+1:7: +1:23 + bb4: { + StorageDead(_11); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL StorageDead(_10); // scope 0 at $DIR/checked_ops.rs:+1:7: +1:23 + StorageDead(_9); // scope 0 at $DIR/checked_ops.rs:+1:7: +1:23 return; // scope 0 at $DIR/checked_ops.rs:+2:2: +2:2 } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir index 727ccc1de5350..d8d6958850eda 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir @@ -10,18 +10,17 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL debug index => std::ops::Range{ .0 => _3, .1 => _4, }; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL let mut _5: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - let mut _14: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _13: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL scope 2 { scope 3 (inlined as SliceIndex<[u32]>>::get_unchecked_mut) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL debug self => std::ops::Range{ .0 => _3, .1 => _4, }; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL debug slice => _5; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL let mut _7: *mut u32; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL let mut _8: *mut u32; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let mut _9: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let _15: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL let _16: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let _17: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL scope 4 { - debug this => std::ops::Range{ .0 => _16, .1 => _17, }; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug this => std::ops::Range{ .0 => _15, .1 => _16, }; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL scope 5 { let _6: usize; // in scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL scope 6 { @@ -37,30 +36,30 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> } scope 14 (inlined slice_from_raw_parts_mut::) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL debug data => _8; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - debug len => _9; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - let mut _10: *mut (); // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + debug len => _6; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + let mut _9: *mut (); // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL scope 15 (inlined ptr::mut_ptr::::cast::<()>) { // at $SRC_DIR/core/src/ptr/mod.rs:LL:COL debug self => _8; // in scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL } scope 16 (inlined std::ptr::from_raw_parts_mut::<[u32]>) { // at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - debug data_address => _10; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - debug metadata => _9; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - let mut _11: *const (); // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - let mut _12: std::ptr::metadata::PtrComponents<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - let mut _13: std::ptr::metadata::PtrRepr<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + debug data_address => _9; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + debug metadata => _6; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + let mut _10: *const (); // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + let mut _11: std::ptr::metadata::PtrComponents<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + let mut _12: std::ptr::metadata::PtrRepr<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL scope 17 { } } } } scope 7 (inlined as SliceIndex<[T]>>::get_unchecked_mut::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug this => std::ops::Range{ .0 => _16, .1 => _17, }; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug this => std::ops::Range{ .0 => _15, .1 => _16, }; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL debug slice => _5; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 8 (inlined ptr::mut_ptr::::len) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL debug self => _5; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - let mut _15: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _14: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL scope 9 (inlined std::ptr::metadata::<[u32]>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - debug ptr => _15; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + debug ptr => _14; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL scope 10 { } } @@ -75,49 +74,40 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> bb0: { _3 = move (_2.0: usize); // scope 0 at $DIR/slice_index.rs:+1:29: +1:34 _4 = move (_2.1: usize); // scope 0 at $DIR/slice_index.rs:+1:29: +1:34 - StorageLive(_14); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_13); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageLive(_5); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL _5 = &raw mut (*_1); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_6); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_14); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageLive(_15); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageLive(_16); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageLive(_17); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageLive(_6); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _6 = unchecked_sub::(_4, _3) -> [return: bb1, unwind unreachable]; // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/slice/index.rs:LL:COL - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize, usize) -> usize {unchecked_sub::}, val: Value() } - } - - bb1: { + _6 = SubUnchecked(_4, _3); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL StorageLive(_8); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL StorageLive(_7); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL _7 = _5 as *mut u32 (PtrToPtr); // scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL _8 = Offset(_7, _3); // scope 13 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL StorageDead(_7); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_9); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _9 = _6; // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_10); // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - _10 = _8 as *mut () (PtrToPtr); // scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - StorageLive(_13); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageLive(_9); // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + _9 = _8 as *mut () (PtrToPtr); // scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL StorageLive(_12); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL StorageLive(_11); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - _11 = _10 as *const () (Pointer(MutToConstPointer)); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - _12 = ptr::metadata::PtrComponents::<[u32]> { data_address: move _11, metadata: _9 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageLive(_10); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _10 = _9 as *const () (Pointer(MutToConstPointer)); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _11 = ptr::metadata::PtrComponents::<[u32]> { data_address: move _10, metadata: _6 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_10); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _12 = ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL StorageDead(_11); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - _13 = ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _12 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - StorageDead(_12); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - _14 = (_13.1: *mut [u32]); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - StorageDead(_13); // scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - StorageDead(_10); // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - StorageDead(_9); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _13 = (_12.1: *mut [u32]); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_12); // scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_9); // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL StorageDead(_8); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageDead(_6); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageDead(_17); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageDead(_16); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageDead(_15); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_14); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_6); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageDead(_5); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - _0 = &mut (*_14); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageDead(_14); // scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _0 = &mut (*_13); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_13); // scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL return; // scope 0 at $DIR/slice_index.rs:+2:2: +2:2 } } From b96de9e77a0898ba0841cfbe2e42272baf4b9939 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 3 Jun 2023 02:38:22 -0700 Subject: [PATCH 2/3] Remove unchecked_add/sub/mul/shl/shr from CTFE/cg_ssa/cg_clif --- .../src/intrinsics/mod.rs | 20 ++------ .../rustc_codegen_ssa/src/mir/intrinsic.rs | 49 +++---------------- .../src/interpret/intrinsics.rs | 31 ------------ 3 files changed, 9 insertions(+), 91 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 1e83c30bd677a..5862f18299e90 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -472,25 +472,11 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, CValue::by_val(align, usize_layout)); } - sym::unchecked_add - | sym::unchecked_sub - | sym::unchecked_mul - | sym::exact_div - | sym::unchecked_shl - | sym::unchecked_shr => { + sym::exact_div => { intrinsic_args!(fx, args => (x, y); intrinsic); - // FIXME trap on overflow - let bin_op = match intrinsic { - sym::unchecked_add => BinOp::Add, - sym::unchecked_sub => BinOp::Sub, - sym::unchecked_mul => BinOp::Mul, - sym::exact_div => BinOp::Div, - sym::unchecked_shl => BinOp::Shl, - sym::unchecked_shr => BinOp::Shr, - _ => unreachable!(), - }; - let res = crate::num::codegen_int_binop(fx, bin_op, x, y); + // FIXME trap on inexact + let res = crate::num::codegen_int_binop(fx, BinOp::Div, x, y); ret.write_cvalue(fx, res); } sym::saturating_add | sym::saturating_sub => { diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 9ac2424e76be0..8a65dd593b8c1 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -211,52 +211,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { args[1].val.unaligned_volatile_store(bx, dst); return; } - | sym::unchecked_shl - | sym::unchecked_shr - | sym::unchecked_add - | sym::unchecked_sub - | sym::unchecked_mul - | sym::exact_div => { + sym::exact_div => { let ty = arg_tys[0]; match int_type_width_signed(ty, bx.tcx()) { - Some((_width, signed)) => match name { - sym::exact_div => { - if signed { - bx.exactsdiv(args[0].immediate(), args[1].immediate()) - } else { - bx.exactudiv(args[0].immediate(), args[1].immediate()) - } - } - sym::unchecked_shl => bx.shl(args[0].immediate(), args[1].immediate()), - sym::unchecked_shr => { - if signed { - bx.ashr(args[0].immediate(), args[1].immediate()) - } else { - bx.lshr(args[0].immediate(), args[1].immediate()) - } - } - sym::unchecked_add => { - if signed { - bx.unchecked_sadd(args[0].immediate(), args[1].immediate()) - } else { - bx.unchecked_uadd(args[0].immediate(), args[1].immediate()) - } - } - sym::unchecked_sub => { - if signed { - bx.unchecked_ssub(args[0].immediate(), args[1].immediate()) - } else { - bx.unchecked_usub(args[0].immediate(), args[1].immediate()) - } - } - sym::unchecked_mul => { - if signed { - bx.unchecked_smul(args[0].immediate(), args[1].immediate()) - } else { - bx.unchecked_umul(args[0].immediate(), args[1].immediate()) - } + Some((_width, signed)) => { + if signed { + bx.exactsdiv(args[0].immediate(), args[1].immediate()) + } else { + bx.exactudiv(args[0].immediate(), args[1].immediate()) } - _ => bug!(), }, None => { bx.tcx().sess.emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty }); diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index fffb9a7f26487..6c130fb74f367 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -234,37 +234,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let r = self.read_immediate(&args[1])?; self.exact_div(&l, &r, dest)?; } - sym::unchecked_shl - | sym::unchecked_shr - | sym::unchecked_add - | sym::unchecked_sub - | sym::unchecked_mul => { - let l = self.read_immediate(&args[0])?; - let r = self.read_immediate(&args[1])?; - let bin_op = match intrinsic_name { - sym::unchecked_shl => BinOp::Shl, - sym::unchecked_shr => BinOp::Shr, - sym::unchecked_add => BinOp::Add, - sym::unchecked_sub => BinOp::Sub, - sym::unchecked_mul => BinOp::Mul, - _ => bug!(), - }; - let (val, overflowed, _ty) = self.overflowing_binary_op(bin_op, &l, &r)?; - if overflowed { - let layout = self.layout_of(substs.type_at(0))?; - let r_val = r.to_scalar().to_bits(layout.size)?; - if let sym::unchecked_shl | sym::unchecked_shr = intrinsic_name { - throw_ub_custom!( - fluent::const_eval_overflow_shift, - val = r_val, - name = intrinsic_name - ); - } else { - throw_ub_custom!(fluent::const_eval_overflow, name = intrinsic_name); - } - } - self.write_scalar(val, dest)?; - } sym::rotate_left | sym::rotate_right => { // rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW)) // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW)) From 33be521c0580eb4c6d1fb8cd022c931c98aa4f15 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 4 Jun 2023 11:09:20 -0700 Subject: [PATCH 3/3] Dedup some type checks in the MIR validator --- .../rustc_const_eval/src/interpret/step.rs | 30 +------- .../src/transform/validate.rs | 77 +++++++------------ compiler/rustc_const_eval/src/util/mod.rs | 26 +++++++ 3 files changed, 57 insertions(+), 76 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 050ed291b4fc7..619da8abb7d22 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -9,29 +9,7 @@ use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::ty::layout::LayoutOf; use super::{ImmTy, InterpCx, Machine}; - -/// Classify whether an operator is "left-homogeneous", i.e., the LHS has the -/// same type as the result. -#[inline] -fn binop_left_homogeneous(op: mir::BinOp) -> bool { - use rustc_middle::mir::BinOp::*; - match op { - Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Div | Rem | BitXor - | BitAnd | BitOr | Offset | Shl | ShlUnchecked | Shr | ShrUnchecked => true, - Eq | Ne | Lt | Le | Gt | Ge => false, - } -} -/// Classify whether an operator is "right-homogeneous", i.e., the RHS has the -/// same type as the LHS. -#[inline] -fn binop_right_homogeneous(op: mir::BinOp) -> bool { - use rustc_middle::mir::BinOp::*; - match op { - Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Div | Rem | BitXor - | BitAnd | BitOr | Eq | Ne | Lt | Le | Gt | Ge => true, - Offset | Shl | ShlUnchecked | Shr | ShrUnchecked => false, - } -} +use crate::util; impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Returns `true` as long as there are more things to do. @@ -181,9 +159,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } BinaryOp(bin_op, box (ref left, ref right)) => { - let layout = binop_left_homogeneous(bin_op).then_some(dest.layout); + let layout = util::binop_left_homogeneous(bin_op).then_some(dest.layout); let left = self.read_immediate(&self.eval_operand(left, layout)?)?; - let layout = binop_right_homogeneous(bin_op).then_some(left.layout); + let layout = util::binop_right_homogeneous(bin_op).then_some(left.layout); let right = self.read_immediate(&self.eval_operand(right, layout)?)?; self.binop_ignore_overflow(bin_op, &left, &right, &dest)?; } @@ -191,7 +169,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { CheckedBinaryOp(bin_op, box (ref left, ref right)) => { // Due to the extra boolean in the result, we can never reuse the `dest.layout`. let left = self.read_immediate(&self.eval_operand(left, None)?)?; - let layout = binop_right_homogeneous(bin_op).then_some(left.layout); + let layout = util::binop_right_homogeneous(bin_op).then_some(left.layout); let right = self.read_immediate(&self.eval_operand(right, layout)?)?; self.binop_with_overflow(bin_op, &left, &right, &dest)?; } diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index d421c7a2755ea..f197541da5bea 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -498,8 +498,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { macro_rules! check_kinds { - ($t:expr, $text:literal, $($patterns:tt)*) => { - if !matches!(($t).kind(), $($patterns)*) { + ($t:expr, $text:literal, $typat:pat) => { + if !matches!(($t).kind(), $typat) { self.fail(location, format!($text, $t)); } }; @@ -527,6 +527,25 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { use BinOp::*; let a = vals.0.ty(&self.body.local_decls, self.tcx); let b = vals.1.ty(&self.body.local_decls, self.tcx); + if crate::util::binop_right_homogeneous(*op) { + if let Eq | Lt | Le | Ne | Ge | Gt = op { + // The function pointer types can have lifetimes + if !self.mir_assign_valid_types(a, b) { + self.fail( + location, + format!("Cannot {op:?} compare incompatible types {a:?} and {b:?}"), + ); + } + } else if a != b { + self.fail( + location, + format!( + "Cannot perform binary op {op:?} on unequal types {a:?} and {b:?}" + ), + ); + } + } + match op { Offset => { check_kinds!(a, "Cannot offset non-pointer type {:?}", ty::RawPtr(..)); @@ -538,7 +557,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { for x in [a, b] { check_kinds!( x, - "Cannot compare type {:?}", + "Cannot {op:?} compare type {:?}", ty::Bool | ty::Char | ty::Int(..) @@ -548,19 +567,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { | ty::FnPtr(..) ) } - // The function pointer types can have lifetimes - if !self.mir_assign_valid_types(a, b) { - self.fail( - location, - format!("Cannot compare unequal types {:?} and {:?}", a, b), - ); - } } - Shl | ShlUnchecked | Shr | ShrUnchecked => { + AddUnchecked | SubUnchecked | MulUnchecked | Shl | ShlUnchecked | Shr + | ShrUnchecked => { for x in [a, b] { check_kinds!( x, - "Cannot shift non-integer type {:?}", + "Cannot {op:?} non-integer type {:?}", ty::Uint(..) | ty::Int(..) ) } @@ -569,55 +582,19 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { for x in [a, b] { check_kinds!( x, - "Cannot perform bitwise op on type {:?}", + "Cannot perform bitwise op {op:?} on type {:?}", ty::Uint(..) | ty::Int(..) | ty::Bool ) } - if a != b { - self.fail( - location, - format!( - "Cannot perform bitwise op on unequal types {:?} and {:?}", - a, b - ), - ); - } } Add | Sub | Mul | Div | Rem => { for x in [a, b] { check_kinds!( x, - "Cannot perform arithmetic on type {:?}", + "Cannot perform arithmetic {op:?} on type {:?}", ty::Uint(..) | ty::Int(..) | ty::Float(..) ) } - if a != b { - self.fail( - location, - format!( - "Cannot perform arithmetic on unequal types {:?} and {:?}", - a, b - ), - ); - } - } - AddUnchecked | SubUnchecked | MulUnchecked => { - for x in [a, b] { - check_kinds!( - x, - "Cannot perform unchecked arithmetic on type {:?}", - ty::Uint(..) | ty::Int(..) - ) - } - if a != b { - self.fail( - location, - format!( - "Cannot perform unchecked arithmetic on unequal types {:?} and {:?}", - a, b - ), - ); - } } } } diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs index 7641f560714d4..289e342259547 100644 --- a/compiler/rustc_const_eval/src/util/mod.rs +++ b/compiler/rustc_const_eval/src/util/mod.rs @@ -1,3 +1,5 @@ +use rustc_middle::mir; + mod alignment; mod check_validity_requirement; mod compare_types; @@ -7,3 +9,27 @@ pub use self::alignment::is_disaligned; pub use self::check_validity_requirement::check_validity_requirement; pub use self::compare_types::{is_equal_up_to_subtyping, is_subtype}; pub use self::type_name::type_name; + +/// Classify whether an operator is "left-homogeneous", i.e., the LHS has the +/// same type as the result. +#[inline] +pub(crate) fn binop_left_homogeneous(op: mir::BinOp) -> bool { + use rustc_middle::mir::BinOp::*; + match op { + Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Div | Rem | BitXor + | BitAnd | BitOr | Offset | Shl | ShlUnchecked | Shr | ShrUnchecked => true, + Eq | Ne | Lt | Le | Gt | Ge => false, + } +} + +/// Classify whether an operator is "right-homogeneous", i.e., the RHS has the +/// same type as the LHS. +#[inline] +pub(crate) fn binop_right_homogeneous(op: mir::BinOp) -> bool { + use rustc_middle::mir::BinOp::*; + match op { + Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Div | Rem | BitXor + | BitAnd | BitOr | Eq | Ne | Lt | Le | Gt | Ge => true, + Offset | Shl | ShlUnchecked | Shr | ShrUnchecked => false, + } +}