diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index d03c2d18c0c35..38c79e1f54592 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -18,7 +18,7 @@ use std::iter; use crate::{ abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, deref_separator, - mentioned_items, pass_manager as pm, remove_noop_landing_pads, simplify, + lower_intrinsics, mentioned_items, pass_manager as pm, remove_noop_landing_pads, simplify, }; use rustc_middle::mir::patch::MirPatch; use rustc_mir_dataflow::elaborate_drops::{self, DropElaborator, DropFlagMode, DropStyle}; @@ -154,6 +154,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' &add_moves_for_packed_drops::AddMovesForPackedDrops, &deref_separator::Derefer, &remove_noop_landing_pads::RemoveNoopLandingPads, + &lower_intrinsics::LowerIntrinsics, &simplify::SimplifyCfg::MakeShim, &abort_unwinding_calls::AbortUnwindingCalls, &add_call_guards::CriticalCallEdges, diff --git a/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-discriminant_value.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-discriminant_value.LowerIntrinsics.diff new file mode 100644 index 0000000000000..ef3bcf4be0362 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-discriminant_value.LowerIntrinsics.diff @@ -0,0 +1,23 @@ +- // MIR for `discriminant_value` before LowerIntrinsics ++ // MIR for `discriminant_value` after LowerIntrinsics + + fn discriminant_value(_1: &T) -> ::Discriminant { + let mut _0: ::Discriminant; // return place in scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + + bb0: { +- _0 = discriminant_value::(move _1) -> bb1; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL +- // mir::Constant +- // + span: $SRC_DIR/core/src/intrinsics.rs:LL:COL +- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r T) -> ::Discriminant {std::intrinsics::discriminant_value::}, val: Value(Scalar()) } ++ _0 = discriminant((*_1)); // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ goto -> bb1; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb1: { + return; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb2 (cleanup): { + resume; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } \ No newline at end of file diff --git a/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-forget.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-forget.LowerIntrinsics.diff new file mode 100644 index 0000000000000..23d0092e0e957 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-forget.LowerIntrinsics.diff @@ -0,0 +1,23 @@ +- // MIR for `std::intrinsics::forget` before LowerIntrinsics ++ // MIR for `std::intrinsics::forget` after LowerIntrinsics + + fn std::intrinsics::forget(_1: T) -> () { + let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + + bb0: { +- _0 = std::intrinsics::forget::(move _1) -> bb1; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL +- // mir::Constant +- // + span: $SRC_DIR/core/src/intrinsics.rs:LL:COL +- // + literal: Const { ty: extern "rust-intrinsic" fn(T) {std::intrinsics::forget::}, val: Value(Scalar()) } ++ _0 = const (); // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ goto -> bb1; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb1: { + return; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb2 (cleanup): { + resume; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } \ No newline at end of file diff --git a/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-size_of.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-size_of.LowerIntrinsics.diff new file mode 100644 index 0000000000000..461689a2d1a23 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-size_of.LowerIntrinsics.diff @@ -0,0 +1,23 @@ +- // MIR for `std::intrinsics::size_of` before LowerIntrinsics ++ // MIR for `std::intrinsics::size_of` after LowerIntrinsics + + fn std::intrinsics::size_of() -> usize { + let mut _0: usize; // return place in scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + + bb0: { +- _0 = std::intrinsics::size_of::() -> bb1; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL +- // mir::Constant +- // + span: $SRC_DIR/core/src/intrinsics.rs:LL:COL +- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::}, val: Value(Scalar()) } ++ _0 = SizeOf(T); // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ goto -> bb1; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb1: { + return; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb2 (cleanup): { + resume; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } \ No newline at end of file diff --git a/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-unreachable.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-unreachable.LowerIntrinsics.diff new file mode 100644 index 0000000000000..01bfbc158c553 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-unreachable.LowerIntrinsics.diff @@ -0,0 +1,22 @@ +- // MIR for `std::intrinsics::unreachable` before LowerIntrinsics ++ // MIR for `std::intrinsics::unreachable` after LowerIntrinsics + + fn std::intrinsics::unreachable() -> ! { + let mut _0: !; // return place in scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + + bb0: { +- _0 = std::intrinsics::unreachable() -> bb1; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL +- // mir::Constant +- // + span: $SRC_DIR/core/src/intrinsics.rs:LL:COL +- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value(Scalar()) } ++ unreachable; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb1: { + return; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb2 (cleanup): { + resume; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } \ No newline at end of file diff --git a/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-wrapping_add.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-wrapping_add.LowerIntrinsics.diff new file mode 100644 index 0000000000000..1965aca03a889 --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.core.intrinsics-#1-wrapping_add.LowerIntrinsics.diff @@ -0,0 +1,23 @@ +- // MIR for `wrapping_add` before LowerIntrinsics ++ // MIR for `wrapping_add` after LowerIntrinsics + + fn wrapping_add(_1: T, _2: T) -> T { + let mut _0: T; // return place in scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + + bb0: { +- _0 = wrapping_add::(move _1, move _2) -> bb1; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL +- // mir::Constant +- // + span: $SRC_DIR/core/src/intrinsics.rs:LL:COL +- // + literal: Const { ty: extern "rust-intrinsic" fn(T, T) -> T {std::intrinsics::wrapping_add::}, val: Value(Scalar()) } ++ _0 = Add(move _1, move _2); // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ goto -> bb1; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb1: { + return; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb2 (cleanup): { + resume; // scope 0 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } \ No newline at end of file diff --git a/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs index 2569f4f4de5df..ed3c9e2378a15 100644 --- a/tests/mir-opt/lower_intrinsics.rs +++ b/tests/mir-opt/lower_intrinsics.rs @@ -267,3 +267,20 @@ pub fn get_metadata(a: *const i32, b: *const [u8], c: *const dyn std::fmt::Debug let _usize = ptr_metadata(b); let _vtable = ptr_metadata(c); } + +// Check that the MIR shims used for reifying intrinsics to `fn` pointers, +// also go through the lowering pass. +pub fn reify_intrinsics() -> impl Copy { + ( + // EMIT_MIR core.intrinsics-#1-wrapping_add.LowerIntrinsics.diff + core::intrinsics::wrapping_add:: as unsafe fn(_, _) -> _, + // EMIT_MIR core.intrinsics-#1-size_of.LowerIntrinsics.diff + core::intrinsics::size_of:: as unsafe fn() -> _, + // EMIT_MIR core.intrinsics-#1-unreachable.LowerIntrinsics.diff + core::intrinsics::unreachable as unsafe fn() -> !, + // EMIT_MIR core.intrinsics-#1-forget.LowerIntrinsics.diff + core::intrinsics::forget:: as unsafe fn(_), + // EMIT_MIR core.intrinsics-#1-discriminant_value.LowerIntrinsics.diff + core::intrinsics::discriminant_value:: as unsafe fn(_) -> _, + ) +}