diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 816288eb50b29..9f7a4d49989ab 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -391,7 +391,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { | mir::StatementKind::Retag { .. } | mir::StatementKind::AscribeUserType(..) | mir::StatementKind::Coverage(..) - | mir::StatementKind::CopyNonOverlapping(..) + | mir::StatementKind::Intrinsic(..) | mir::StatementKind::Nop => {} } } diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index ec521b1cf0afd..3157f861d93be 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -1,6 +1,6 @@ use rustc_data_structures::graph::dominators::Dominators; use rustc_middle::mir::visit::Visitor; -use rustc_middle::mir::{BasicBlock, Body, Location, Place, Rvalue}; +use rustc_middle::mir::{self, BasicBlock, Body, Location, NonDivergingIntrinsic, Place, Rvalue}; use rustc_middle::mir::{BorrowKind, Mutability, Operand}; use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind}; use rustc_middle::mir::{Statement, StatementKind}; @@ -63,23 +63,24 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { StatementKind::FakeRead(box (_, _)) => { // Only relevant for initialized/liveness/safety checks. } - StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { + StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => { + self.consume_operand(location, op); + } + StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping { ref src, ref dst, ref count, - }) => { + })) => { self.consume_operand(location, src); self.consume_operand(location, dst); self.consume_operand(location, count); } - StatementKind::Nop + // Only relevant for mir typeck + StatementKind::AscribeUserType(..) + // Doesn't have any language semantics | StatementKind::Coverage(..) - | StatementKind::AscribeUserType(..) - | StatementKind::Retag { .. } - | StatementKind::StorageLive(..) => { - // `Nop`, `AscribeUserType`, `Retag`, and `StorageLive` are irrelevant - // to borrow check. - } + // Does not actually affect borrowck + | StatementKind::StorageLive(..) => {} StatementKind::StorageDead(local) => { self.access_place( location, @@ -88,7 +89,10 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { LocalMutationIsAllowed::Yes, ); } - StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => { + StatementKind::Nop + | StatementKind::Retag { .. } + | StatementKind::Deinit(..) + | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 20c22575bd1fa..ec652f852179a 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -26,8 +26,8 @@ use rustc_index::bit_set::ChunkedBitSet; use rustc_index::vec::IndexVec; use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt}; use rustc_middle::mir::{ - traversal, Body, ClearCrossCrate, Local, Location, Mutability, Operand, Place, PlaceElem, - PlaceRef, VarDebugInfoContents, + traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand, + Place, PlaceElem, PlaceRef, VarDebugInfoContents, }; use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; @@ -591,22 +591,19 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx flow_state, ); } - StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { - .. - }) => { - span_bug!( + StatementKind::Intrinsic(box ref kind) => match kind { + NonDivergingIntrinsic::Assume(op) => self.consume_operand(location, (op, span), flow_state), + NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!( span, "Unexpected CopyNonOverlapping, should only appear after lower_intrinsics", ) } - StatementKind::Nop + // Only relevant for mir typeck + StatementKind::AscribeUserType(..) + // Doesn't have any language semantics | StatementKind::Coverage(..) - | StatementKind::AscribeUserType(..) - | StatementKind::Retag { .. } - | StatementKind::StorageLive(..) => { - // `Nop`, `AscribeUserType`, `Retag`, and `StorageLive` are irrelevant - // to borrow check. - } + // Does not actually affect borrowck + | StatementKind::StorageLive(..) => {} StatementKind::StorageDead(local) => { self.access_place( location, @@ -616,7 +613,10 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx flow_state, ); } - StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => { + StatementKind::Nop + | StatementKind::Retag { .. } + | StatementKind::Deinit(..) + | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index a620c987052ba..fc0e95f30c98f 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1302,12 +1302,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } } - StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { - .. - }) => span_bug!( - stmt.source_info.span, - "Unexpected StatementKind::CopyNonOverlapping, should only appear after lowering_intrinsics", - ), + StatementKind::Intrinsic(box ref kind) => match kind { + NonDivergingIntrinsic::Assume(op) => self.check_operand(op, location), + NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!( + stmt.source_info.span, + "Unexpected NonDivergingIntrinsic::CopyNonOverlapping, should only appear after lowering_intrinsics", + ), + }, StatementKind::FakeRead(..) | StatementKind::StorageLive(..) | StatementKind::StorageDead(..) diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index c412e451a033e..2aa11ac2eeaa6 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -794,20 +794,31 @@ fn codegen_stmt<'tcx>( | StatementKind::AscribeUserType(..) => {} StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"), - StatementKind::CopyNonOverlapping(inner) => { - let dst = codegen_operand(fx, &inner.dst); - let pointee = dst - .layout() - .pointee_info_at(fx, rustc_target::abi::Size::ZERO) - .expect("Expected pointer"); - let dst = dst.load_scalar(fx); - let src = codegen_operand(fx, &inner.src).load_scalar(fx); - let count = codegen_operand(fx, &inner.count).load_scalar(fx); - let elem_size: u64 = pointee.size.bytes(); - let bytes = - if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) } else { count }; - fx.bcx.call_memcpy(fx.target_config, dst, src, bytes); - } + StatementKind::Intrinsic(ref intrinsic) => match &**intrinsic { + // We ignore `assume` intrinsics, they are only useful for optimizations + NonDivergingIntrinsic::Assume(_) => {} + NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping { + src, + dst, + count, + }) => { + let dst = codegen_operand(fx, dst); + let pointee = dst + .layout() + .pointee_info_at(fx, rustc_target::abi::Size::ZERO) + .expect("Expected pointer"); + let dst = dst.load_scalar(fx); + let src = codegen_operand(fx, src).load_scalar(fx); + let count = codegen_operand(fx, count).load_scalar(fx); + let elem_size: u64 = pointee.size.bytes(); + let bytes = if elem_size != 1 { + fx.bcx.ins().imul_imm(count, elem_size as i64) + } else { + count + }; + fx.bcx.call_memcpy(fx.target_config, dst, src, bytes); + } + }, } } diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 9224f499339cb..0305341da784e 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -536,9 +536,11 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( { return None; } - StatementKind::CopyNonOverlapping(_) => { - return None; - } // conservative handling + StatementKind::Intrinsic(ref intrinsic) => match **intrinsic { + NonDivergingIntrinsic::CopyNonOverlapping(..) => return None, + NonDivergingIntrinsic::Assume(..) => {} + }, + // conservative handling StatementKind::Assign(_) | StatementKind::FakeRead(_) | StatementKind::SetDiscriminant { .. } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 39e9e784a478b..0cd9332a58bef 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -357,9 +357,6 @@ fn codegen_regular_intrinsic_call<'tcx>( let usize_layout = fx.layout_of(fx.tcx.types.usize); match intrinsic { - sym::assume => { - intrinsic_args!(fx, args => (_a); intrinsic); - } sym::likely | sym::unlikely => { intrinsic_args!(fx, args => (a); intrinsic); diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 16aad07194da8..6393dd9d634fc 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -77,10 +77,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout); let llval = match name { - sym::assume => { - bx.assume(args[0].immediate()); - return; - } sym::abort => { bx.abort(); return; diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index f452f29883f93..1db0fb3a6f1b0 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -1,4 +1,5 @@ use rustc_middle::mir; +use rustc_middle::mir::NonDivergingIntrinsic; use super::FunctionCx; use super::LocalRef; @@ -73,11 +74,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_coverage(&mut bx, coverage.clone(), statement.source_info.scope); bx } - mir::StatementKind::CopyNonOverlapping(box mir::CopyNonOverlapping { - ref src, - ref dst, - ref count, - }) => { + mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(ref op)) => { + let op_val = self.codegen_operand(&mut bx, op); + bx.assume(op_val.immediate()); + bx + } + mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping( + mir::CopyNonOverlapping { ref count, ref src, ref dst }, + )) => { let dst_val = self.codegen_operand(&mut bx, dst); let src_val = self.codegen_operand(&mut bx, src); let count = self.codegen_operand(&mut bx, count).immediate(); diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index adda9639990d0..2f415a8c9c709 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -8,7 +8,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::mir::{ self, interpret::{ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar}, - BinOp, + BinOp, NonDivergingIntrinsic, }; use rustc_middle::ty; use rustc_middle::ty::layout::LayoutOf as _; @@ -506,12 +506,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // These just return their argument self.copy_op(&args[0], dest, /*allow_transmute*/ false)?; } - sym::assume => { - let cond = self.read_scalar(&args[0])?.to_bool()?; - if !cond { - throw_ub_format!("`assume` intrinsic called with `false`"); - } - } sym::raw_eq => { let result = self.raw_eq_intrinsic(&args[0], &args[1])?; self.write_scalar(result, dest)?; @@ -536,6 +530,32 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(true) } + pub(super) fn emulate_nondiverging_intrinsic( + &mut self, + intrinsic: &NonDivergingIntrinsic<'tcx>, + ) -> InterpResult<'tcx> { + match intrinsic { + NonDivergingIntrinsic::Assume(op) => { + let op = self.eval_operand(op, None)?; + let cond = self.read_scalar(&op)?.to_bool()?; + if !cond { + throw_ub_format!("`assume` called with `false`"); + } + Ok(()) + } + NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping { + count, + src, + dst, + }) => { + let src = self.eval_operand(src, None)?; + let dst = self.eval_operand(dst, None)?; + let count = self.eval_operand(count, None)?; + self.copy_intrinsic(&src, &dst, &count, /* nonoverlapping */ true) + } + } + } + pub fn exact_div( &mut self, a: &ImmTy<'tcx, M::Provenance>, diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 6b827149f505e..c6e04cbfb6bf3 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -114,13 +114,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { M::retag(self, *kind, &dest)?; } - // Call CopyNonOverlapping - CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { src, dst, count }) => { - let src = self.eval_operand(src, None)?; - let dst = self.eval_operand(dst, None)?; - let count = self.eval_operand(count, None)?; - self.copy_intrinsic(&src, &dst, &count, /* nonoverlapping */ true)?; - } + Intrinsic(box ref intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?, // Statements we do not track. AscribeUserType(..) => {} diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index cbfdb47dd1a40..3fa40dc305952 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -678,7 +678,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { | StatementKind::Retag { .. } | StatementKind::AscribeUserType(..) | StatementKind::Coverage(..) - | StatementKind::CopyNonOverlapping(..) + | StatementKind::Intrinsic(..) | StatementKind::Nop => {} } } diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index b798862583952..783ab350faac3 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -7,9 +7,10 @@ use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::NonUseContext::VarDebugInfo; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{ - traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, CastKind, Local, Location, - MirPass, MirPhase, Operand, Place, PlaceElem, PlaceRef, ProjectionElem, RuntimePhase, Rvalue, - SourceScope, Statement, StatementKind, Terminator, TerminatorKind, UnOp, START_BLOCK, + traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, + Local, Location, MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, + ProjectionElem, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator, + TerminatorKind, UnOp, START_BLOCK, }; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::subst::Subst; @@ -636,11 +637,18 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } } - StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { - ref src, - ref dst, - ref count, - }) => { + StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => { + let ty = op.ty(&self.body.local_decls, self.tcx); + if !ty.is_bool() { + self.fail( + location, + format!("`assume` argument must be `bool`, but got: `{}`", ty), + ); + } + } + StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping( + CopyNonOverlapping { src, dst, count }, + )) => { let src_ty = src.ty(&self.body.local_decls, self.tcx); let op_src_ty = if let Some(src_deref) = src_ty.builtin_deref(true) { src_deref.ty diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index f3676604bb0e6..091cc84af3ce6 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1370,13 +1370,7 @@ impl Debug for Statement<'_> { write!(fmt, "Coverage::{:?} for {:?}", kind, rgn) } Coverage(box ref coverage) => write!(fmt, "Coverage::{:?}", coverage.kind), - CopyNonOverlapping(box crate::mir::CopyNonOverlapping { - ref src, - ref dst, - ref count, - }) => { - write!(fmt, "copy_nonoverlapping(src={:?}, dst={:?}, count={:?})", src, dst, count) - } + Intrinsic(box ref intrinsic) => write!(fmt, "{intrinsic}"), Nop => write!(fmt, "nop"), } } diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs index 6e64a3b80c1fb..4e06d91012c0d 100644 --- a/compiler/rustc_middle/src/mir/spanview.rs +++ b/compiler/rustc_middle/src/mir/spanview.rs @@ -249,7 +249,7 @@ pub fn statement_kind_name(statement: &Statement<'_>) -> &'static str { Retag(..) => "Retag", AscribeUserType(..) => "AscribeUserType", Coverage(..) => "Coverage", - CopyNonOverlapping(..) => "CopyNonOverlapping", + Intrinsic(..) => "Intrinsic", Nop => "Nop", } } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index d7b9d59eced51..bf63b8efaf7a2 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -327,6 +327,34 @@ pub enum StatementKind<'tcx> { /// executed. Coverage(Box), + /// Denotes a call to an intrinsic that does not require an unwind path and always returns. + /// This avoids adding a new block and a terminator for simple intrinsics. + Intrinsic(Box>), + + /// No-op. Useful for deleting instructions without affecting statement indices. + Nop, +} + +#[derive( + Clone, + TyEncodable, + TyDecodable, + Debug, + PartialEq, + Hash, + HashStable, + TypeFoldable, + TypeVisitable +)] +pub enum NonDivergingIntrinsic<'tcx> { + /// Denotes a call to the intrinsic function `assume`. + /// + /// The operand must be a boolean. Optimizers may use the value of the boolean to backtrack its + /// computation to infer information about other variables. So if the boolean came from a + /// `x < y` operation, subsequent operations on `x` and `y` could elide various bound checks. + /// If the argument is `false`, this operation is equivalent to `TerminatorKind::Unreachable`. + Assume(Operand<'tcx>), + /// Denotes a call to the intrinsic function `copy_nonoverlapping`. /// /// First, all three operands are evaluated. `src` and `dest` must each be a reference, pointer, @@ -340,10 +368,18 @@ pub enum StatementKind<'tcx> { /// /// **Needs clarification**: Is this typed or not, ie is there a typed load and store involved? /// I vaguely remember Ralf saying somewhere that he thought it should not be. - CopyNonOverlapping(Box>), + CopyNonOverlapping(CopyNonOverlapping<'tcx>), +} - /// No-op. Useful for deleting instructions without affecting statement indices. - Nop, +impl std::fmt::Display for NonDivergingIntrinsic<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Assume(op) => write!(f, "assume({op:?})"), + Self::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => { + write!(f, "copy_nonoverlapping(dst = {dst:?}, src = {src:?}, count = {count:?})") + } + } + } } /// Describes what kind of retag is to be performed. diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 7bd65f42e3f92..708ea4398c852 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -425,14 +425,15 @@ macro_rules! make_mir_visitor { location ) } - StatementKind::CopyNonOverlapping(box crate::mir::CopyNonOverlapping{ - src, - dst, - count, - }) => { - self.visit_operand(src, location); - self.visit_operand(dst, location); - self.visit_operand(count, location) + StatementKind::Intrinsic(box ref $($mutability)? intrinsic) => { + match intrinsic { + NonDivergingIntrinsic::Assume(op) => self.visit_operand(op, location), + NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => { + self.visit_operand(src, location); + self.visit_operand(dst, location); + self.visit_operand(count, location); + } + } } StatementKind::Nop => {} } diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index 483c1e274aa78..3e08a8799ef9a 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -270,7 +270,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> { | StatementKind::Retag(..) | StatementKind::AscribeUserType(..) | StatementKind::Coverage(..) - | StatementKind::CopyNonOverlapping(..) + | StatementKind::Intrinsic(..) | StatementKind::Nop => None, }; if let Some(destination) = destination { diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index f6b5af90a85c8..18760b6c6fa54 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -142,7 +142,7 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc | StatementKind::FakeRead(..) | StatementKind::Nop | StatementKind::Retag(..) - | StatementKind::CopyNonOverlapping(..) + | StatementKind::Intrinsic(..) | StatementKind::StorageLive(..) => {} } } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index c325838622399..f46fd118bde5d 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -330,7 +330,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { StatementKind::Retag { .. } | StatementKind::AscribeUserType(..) | StatementKind::Coverage(..) - | StatementKind::CopyNonOverlapping(..) + | StatementKind::Intrinsic(..) | StatementKind::Nop => {} } } diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 0f5fd77f7ab16..beff19a3ab2e1 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -105,7 +105,8 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { // safe (at least as emitted during MIR construction) } - StatementKind::CopyNonOverlapping(..) => unreachable!(), + // Move to above list once mir construction uses it. + StatementKind::Intrinsic(..) => unreachable!(), } self.super_statement(statement, location); } diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 423e78317aadb..9f842c929dc24 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -825,7 +825,7 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option // Retain spans from all other statements StatementKind::FakeRead(box (_, _)) // Not including `ForGuardBinding` - | StatementKind::CopyNonOverlapping(..) + | StatementKind::Intrinsic(..) | StatementKind::Assign(_) | StatementKind::SetDiscriminant { .. } | StatementKind::Deinit(..) diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index 9163672f57039..3f3870cc7bad2 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -52,7 +52,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Coverage(_) - | StatementKind::CopyNonOverlapping(_) + | StatementKind::Intrinsic(_) | StatementKind::Nop => (), StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => { diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index da55510920e12..9bc47613e4c67 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -537,7 +537,7 @@ impl<'a> Conflicts<'a> { | StatementKind::FakeRead(..) | StatementKind::AscribeUserType(..) | StatementKind::Coverage(..) - | StatementKind::CopyNonOverlapping(..) + | StatementKind::Intrinsic(..) | StatementKind::Nop => {} } } diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index dbff4a6bd696e..705cf776fb29e 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1452,7 +1452,7 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> { | StatementKind::Retag(..) | StatementKind::AscribeUserType(..) | StatementKind::Coverage(..) - | StatementKind::CopyNonOverlapping(..) + | StatementKind::Intrinsic(..) | StatementKind::Nop => {} } } diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index b7ba616510c28..9892580e63dcb 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -46,12 +46,31 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { let mut args = args.drain(..); block.statements.push(Statement { source_info: terminator.source_info, - kind: StatementKind::CopyNonOverlapping(Box::new( - rustc_middle::mir::CopyNonOverlapping { - src: args.next().unwrap(), - dst: args.next().unwrap(), - count: args.next().unwrap(), - }, + kind: StatementKind::Intrinsic(Box::new( + NonDivergingIntrinsic::CopyNonOverlapping( + rustc_middle::mir::CopyNonOverlapping { + src: args.next().unwrap(), + dst: args.next().unwrap(), + count: args.next().unwrap(), + }, + ), + )), + }); + assert_eq!( + args.next(), + None, + "Extra argument for copy_non_overlapping intrinsic" + ); + drop(args); + terminator.kind = TerminatorKind::Goto { target }; + } + sym::assume => { + let target = target.unwrap(); + let mut args = args.drain(..); + block.statements.push(Statement { + source_info: terminator.source_info, + kind: StatementKind::Intrinsic(Box::new( + NonDivergingIntrinsic::Assume(args.next().unwrap()), )), }); assert_eq!( diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs index 41a0bfac41aed..f1bbf2ea7e8ea 100644 --- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs +++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs @@ -51,7 +51,7 @@ impl RemoveNoopLandingPads { StatementKind::Assign { .. } | StatementKind::SetDiscriminant { .. } | StatementKind::Deinit(..) - | StatementKind::CopyNonOverlapping(..) + | StatementKind::Intrinsic(..) | StatementKind::Retag { .. } => { return false; } diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs index 190f9c1ac158c..2f116aaa95849 100644 --- a/compiler/rustc_mir_transform/src/separate_const_switch.rs +++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs @@ -249,7 +249,7 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData< | StatementKind::AscribeUserType(_, _) | StatementKind::Coverage(_) | StatementKind::StorageDead(_) - | StatementKind::CopyNonOverlapping(_) + | StatementKind::Intrinsic(_) | StatementKind::Nop => {} } } @@ -317,7 +317,7 @@ fn find_determining_place<'tcx>( | StatementKind::Retag(_, _) | StatementKind::AscribeUserType(_, _) | StatementKind::Coverage(_) - | StatementKind::CopyNonOverlapping(_) + | StatementKind::Intrinsic(_) | StatementKind::Nop => {} // If the discriminant is set, it is always set diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index bed48db959a53..57d372fda5697 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -499,7 +499,7 @@ impl UsedLocals { impl<'tcx> Visitor<'tcx> for UsedLocals { fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { match statement.kind { - StatementKind::CopyNonOverlapping(..) + StatementKind::Intrinsic(..) | StatementKind::Retag(..) | StatementKind::Coverage(..) | StatementKind::FakeRead(..) diff --git a/src/test/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff new file mode 100644 index 0000000000000..d9898d8e0f015 --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.assume.LowerIntrinsics.diff @@ -0,0 +1,26 @@ +- // MIR for `assume` before LowerIntrinsics ++ // MIR for `assume` after LowerIntrinsics + + fn assume() -> () { + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:17 + let _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:38 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 +- _1 = std::intrinsics::assume(const true) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:38 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:72:9: 72: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 + } + + bb1: { + StorageDead(_1); // scope 1 at $DIR/lower_intrinsics.rs:+2:38: +2:39 + _0 = const (); // scope 1 at $DIR/lower_intrinsics.rs:+1:5: +3:6 + return; // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff new file mode 100644 index 0000000000000..4fb6752b61965 --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff @@ -0,0 +1,72 @@ +- // MIR for `f_copy_nonoverlapping` before LowerIntrinsics ++ // MIR for `f_copy_nonoverlapping` after LowerIntrinsics + + fn f_copy_nonoverlapping() -> () { + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:32: +0:32 + let _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:12 + let _3: (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:9: +4:95 + let mut _4: *const i32; // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:59 + let mut _5: *const (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + let mut _6: *const (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + let _7: &(); // in scope 0 at $DIR/lower_intrinsics.rs:+4:29: +4:33 + let mut _8: *mut i32; // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:91 + let mut _9: *mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + let mut _10: *mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + let mut _11: &mut (); // in scope 0 at $DIR/lower_intrinsics.rs:+4:61: +4:69 + scope 1 { + debug src => _1; // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:12 + let mut _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:16 + scope 2 { + debug dst => _2; // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:16 + scope 3 { + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:12 + Deinit(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:15: +1:17 + StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:16 + Deinit(_2); // scope 1 at $DIR/lower_intrinsics.rs:+2:19: +2:21 + StorageLive(_3); // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 + StorageLive(_4); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:59 + StorageLive(_5); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + StorageLive(_6); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + StorageLive(_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33 + _7 = &_1; // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33 + _6 = &raw const (*_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:33 + _5 = _6; // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:45 + _4 = move _5 as *const i32 (Misc); // scope 3 at $DIR/lower_intrinsics.rs:+4:29: +4:59 + StorageDead(_5); // scope 3 at $DIR/lower_intrinsics.rs:+4:58: +4:59 + StorageLive(_8); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:91 + StorageLive(_9); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + StorageLive(_10); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + StorageLive(_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69 + _11 = &mut _2; // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69 + _10 = &raw mut (*_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:69 + _9 = _10; // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:79 + _8 = move _9 as *mut i32 (Misc); // scope 3 at $DIR/lower_intrinsics.rs:+4:61: +4:91 + StorageDead(_9); // scope 3 at $DIR/lower_intrinsics.rs:+4:90: +4:91 +- _3 = copy_nonoverlapping::(move _4, move _8, const 0_usize) -> bb1; // scope 3 at $DIR/lower_intrinsics.rs:+4:9: +4:95 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:65:9: 65: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 + } + + bb1: { + StorageDead(_8); // scope 3 at $DIR/lower_intrinsics.rs:+4:94: +4:95 + StorageDead(_4); // scope 3 at $DIR/lower_intrinsics.rs:+4:94: +4:95 + StorageDead(_11); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + StorageDead(_10); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + StorageDead(_7); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + StorageDead(_6); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + StorageDead(_3); // scope 3 at $DIR/lower_intrinsics.rs:+4:95: +4:96 + _0 = const (); // scope 3 at $DIR/lower_intrinsics.rs:+3:5: +5:6 + StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:+6:1: +6:2 + StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+6:1: +6:2 + return; // scope 0 at $DIR/lower_intrinsics.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/lower_intrinsics.rs b/src/test/mir-opt/lower_intrinsics.rs index 195543d42bb5b..66dae0e46b9d7 100644 --- a/src/test/mir-opt/lower_intrinsics.rs +++ b/src/test/mir-opt/lower_intrinsics.rs @@ -1,7 +1,7 @@ // unit-test: LowerIntrinsics // ignore-wasm32 compiled with panic=abort by default -#![feature(core_intrinsics)] +#![feature(core_intrinsics, intrinsics)] #![crate_type = "lib"] // EMIT_MIR lower_intrinsics.wrapping.LowerIntrinsics.diff @@ -51,3 +51,24 @@ pub fn discriminant(t: T) { core::intrinsics::discriminant_value(&()); core::intrinsics::discriminant_value(&E::B); } + +extern "rust-intrinsic" { + // Cannot use `std::intrinsics::copy_nonoverlapping` as that is a wrapper function + fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); +} + +// EMIT_MIR lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.diff +pub fn f_copy_nonoverlapping() { + let src = (); + let mut dst = (); + unsafe { + copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0); + } +} + +// EMIT_MIR lower_intrinsics.assume.LowerIntrinsics.diff +pub fn assume() { + unsafe { + std::intrinsics::assume(true); + } +} diff --git a/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff b/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff deleted file mode 100644 index 28536dc28a722..0000000000000 --- a/src/test/mir-opt/separate_const_switch.identity.ConstProp.diff +++ /dev/null @@ -1,146 +0,0 @@ -- // MIR for `identity` before ConstProp -+ // MIR for `identity` after ConstProp - - fn identity(_1: Result) -> Result { - debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14 - let mut _0: std::result::Result; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53 - let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - let mut _3: std::ops::ControlFlow, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - let mut _4: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 - let mut _5: isize; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - let _6: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - let mut _7: !; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - let mut _8: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - scope 1 { - debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10 - scope 2 { - scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10 - debug residual => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _17: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _18: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - scope 9 { - debug e => _16; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - scope 10 (inlined >::from) { // at $SRC_DIR/core/src/result.rs:LL:COL - debug t => _18; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - } - } - } - } - } - scope 3 { - debug val => _9; // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10 - scope 4 { - } - } - scope 5 (inlined as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10 - debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _10: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _12: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _14: std::result::Result; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _15: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - scope 6 { - debug v => _11; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - } - scope 7 { - debug e => _13; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - } - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 - _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 - _10 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - } - - bb1: { - StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - _9 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - _2 = _9; // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10 - StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - Deinit(_0); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 - ((_0 as Ok).0: i32) = move _2; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 - discriminant(_0) = 0; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 - StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 - StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 - return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 - } - - bb2: { - unreachable; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - } - - bb3: { - StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - _6 = ((_3 as Break).0: std::result::Result); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - _8 = _6; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - _16 = move ((_8 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - _18 = move _16; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - _17 = move _18; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageDead(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - ((_0 as Err).0: i32) = move _17; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 - StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 - return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 - } - - bb4: { - StorageLive(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _13 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - _15 = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - ((_14 as Err).0: i32) = move _15; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_14) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_3); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - ((_3 as Break).0: std::result::Result) = move _14; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 -- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -- switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -+ _5 = const 1_isize; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -+ switchInt(const 1_isize) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - } - - bb5: { - unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - } - - bb6: { - StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _11 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - _12 = move _11; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_3); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - ((_3 as Continue).0: i32) = move _12; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 -- _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -- switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -+ _5 = const 0_isize; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 -+ switchInt(const 0_isize) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - } - } - diff --git a/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir b/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir deleted file mode 100644 index df20f0ed36b60..0000000000000 --- a/src/test/mir-opt/separate_const_switch.identity.PreCodegen.after.mir +++ /dev/null @@ -1,124 +0,0 @@ -// MIR for `identity` after PreCodegen - -fn identity(_1: Result) -> Result { - debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:13: +0:14 - let mut _0: std::result::Result; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:37: +0:53 - let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - let mut _3: std::ops::ControlFlow, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - let mut _4: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 - let _5: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - let mut _6: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - let _7: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - scope 1 { - debug residual => _5; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10 - scope 2 { - scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10 - debug residual => _6; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let _14: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _15: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - scope 9 { - debug e => _14; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - scope 10 (inlined >::from) { // at $SRC_DIR/core/src/result.rs:LL:COL - debug t => _16; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - } - } - } - } - } - scope 3 { - debug val => _7; // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10 - scope 4 { - } - } - scope 5 (inlined as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10 - debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _8: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _9: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _10: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _12: std::result::Result; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - scope 6 { - debug v => _9; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - } - scope 7 { - debug e => _11; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - } - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 - _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 - _8 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - switchInt(move _8) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - } - - bb1: { - StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _11 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - _13 = move _11; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - ((_12 as Err).0: i32) = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_12) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_3); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - ((_3 as Break).0: std::result::Result) = move _12; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_5); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - _5 = ((_3 as Break).0: std::result::Result); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_6); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - _6 = _5; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - _14 = move ((_6 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - _16 = move _14; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - _15 = move _16; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageDead(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - ((_0 as Err).0: i32) = move _15; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_6); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageDead(_5); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 - StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 - return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 - } - - bb2: { - unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - } - - bb3: { - StorageLive(_9); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _9 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - _10 = move _9; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - Deinit(_3); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - ((_3 as Continue).0: i32) = move _10; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_9); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_7); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - _7 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 - _2 = _7; // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10 - StorageDead(_7); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 - Deinit(_0); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 - ((_0 as Ok).0: i32) = move _2; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 - discriminant(_0) = 0; // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11 - StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 - StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2 - return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2 - } -} diff --git a/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff b/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff deleted file mode 100644 index 28269165e1c27..0000000000000 --- a/src/test/mir-opt/separate_const_switch.too_complex.ConstProp.diff +++ /dev/null @@ -1,103 +0,0 @@ -- // MIR for `too_complex` before ConstProp -+ // MIR for `too_complex` after ConstProp - - fn too_complex(_1: Result) -> Option { - debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17 - let mut _0: std::option::Option; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53 - let mut _2: std::ops::ControlFlow; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 - let mut _3: isize; // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18 - let _4: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 - let mut _5: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45 - let _6: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 - let mut _7: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:42: +8:43 - let mut _8: isize; // in scope 0 at $DIR/separate_const_switch.rs:+11:9: +11:33 - let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 - let mut _10: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43 - let _11: usize; // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 - scope 1 { - debug v => _4; // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17 - } - scope 2 { - debug r => _6; // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18 - } - scope 3 { - debug v => _9; // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32 - } - scope 4 { - debug r => _11; // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29 - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 - _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 - switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16 - } - - bb1: { - StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 - _6 = ((_1 as Err).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 - StorageLive(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43 - _7 = _6; // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43 - Deinit(_2); // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44 - ((_2 as Break).0: usize) = move _7; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44 - discriminant(_2) = 1; // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44 - StorageDead(_7); // scope 2 at $DIR/separate_const_switch.rs:+8:43: +8:44 - StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44 -- _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 -- switchInt(move _8) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 -+ _8 = const 1_isize; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 -+ switchInt(const 1_isize) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 - } - - bb2: { - unreachable; // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 - } - - bb3: { - StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 - _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 - StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 - _5 = _4; // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 - Deinit(_2); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 - ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 - discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 - StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46 - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46 -- _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 -- switchInt(move _8) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 -+ _8 = const 0_isize; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 -+ switchInt(const 0_isize) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 - } - - bb4: { - StorageLive(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 - _11 = ((_2 as Break).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 - Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 - discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 - StorageDead(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 - goto -> bb7; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 - } - - bb5: { - unreachable; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 - } - - bb6: { - StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 - _9 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 - StorageLive(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 - _10 = _9; // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 - Deinit(_0); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 - ((_0 as Some).0: i32) = move _10; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 - discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 - StorageDead(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44 - StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 - goto -> bb7; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 - } - - bb7: { - StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2 - return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2 - } - } - diff --git a/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir b/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir deleted file mode 100644 index 0ee070619e79d..0000000000000 --- a/src/test/mir-opt/separate_const_switch.too_complex.PreCodegen.after.mir +++ /dev/null @@ -1,73 +0,0 @@ -// MIR for `too_complex` after PreCodegen - -fn too_complex(_1: Result) -> Option { - debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:+0:16: +0:17 - let mut _0: std::option::Option; // return place in scope 0 at $DIR/separate_const_switch.rs:+0:42: +0:53 - let mut _2: std::ops::ControlFlow; // in scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 - let mut _3: isize; // in scope 0 at $DIR/separate_const_switch.rs:+7:13: +7:18 - let _4: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 - let mut _5: i32; // in scope 0 at $DIR/separate_const_switch.rs:+7:44: +7:45 - let _6: usize; // in scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 - let _7: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 - let mut _8: i32; // in scope 0 at $DIR/separate_const_switch.rs:+11:42: +11:43 - let _9: usize; // in scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 - scope 1 { - debug v => _4; // in scope 1 at $DIR/separate_const_switch.rs:+7:16: +7:17 - } - scope 2 { - debug r => _6; // in scope 2 at $DIR/separate_const_switch.rs:+8:17: +8:18 - } - scope 3 { - debug v => _7; // in scope 3 at $DIR/separate_const_switch.rs:+11:31: +11:32 - } - scope 4 { - debug r => _9; // in scope 4 at $DIR/separate_const_switch.rs:+12:28: +12:29 - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 - _3 = discriminant(_1); // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 - switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+6:9: +6:16 - } - - bb1: { - StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18 - StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44 - StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 - Deinit(_0); // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 - discriminant(_0) = 0; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 - StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 - goto -> bb4; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 - } - - bb2: { - unreachable; // scope 0 at $DIR/separate_const_switch.rs:+6:15: +6:16 - } - - bb3: { - StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 - _4 = ((_1 as Ok).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17 - StorageLive(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 - _5 = _4; // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45 - Deinit(_2); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 - ((_2 as Continue).0: i32) = move _5; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 - discriminant(_2) = 0; // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46 - StorageDead(_5); // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46 - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46 - StorageLive(_7); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 - _7 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 - StorageLive(_8); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 - _8 = _7; // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 - Deinit(_0); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 - ((_0 as Some).0: i32) = move _8; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 - discriminant(_0) = 1; // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 - StorageDead(_8); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44 - StorageDead(_7); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 - goto -> bb4; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 - } - - bb4: { - StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2 - return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2 - } -} diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 74c222bbcbeb9..b22a9c817460d 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -7,7 +7,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::mir::{ Body, CastKind, NullOp, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, - TerminatorKind, + TerminatorKind, NonDivergingIntrinsic }; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt}; @@ -212,11 +212,18 @@ fn check_statement<'tcx>( check_place(tcx, **place, span, body) }, - StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { dst, src, count }) => { + StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => { + check_operand(tcx, op, span, body) + }, + + StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping( + rustc_middle::mir::CopyNonOverlapping { dst, src, count }, + )) => { check_operand(tcx, dst, span, body)?; check_operand(tcx, src, span, body)?; check_operand(tcx, count, span, body) }, + // These are all NOPs StatementKind::StorageLive(_) | StatementKind::StorageDead(_)