From 9520cebfc50947f04280a6dbf288dfb5475c1637 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 14 Apr 2024 11:12:32 -0700 Subject: [PATCH] =?UTF-8?q?InstSimplify=20`from=5Fraw=5Fparts(p,=20())`=20?= =?UTF-8?q?=E2=86=92=20`p=20as=20=5F`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rustc_mir_transform/src/instsimplify.rs | 36 ++++++++++++++++++- tests/mir-opt/instsimplify/casts.rs | 9 +++++ ...e_add_fat.PreCodegen.after.panic-abort.mir | 10 +----- ..._add_fat.PreCodegen.after.panic-unwind.mir | 10 +----- ..._add_thin.PreCodegen.after.panic-abort.mir | 12 +------ ...add_thin.PreCodegen.after.panic-unwind.mir | 12 +------ 6 files changed, 48 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index ff786d44d6a9..bae959963b53 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -36,6 +36,7 @@ impl<'tcx> MirPass<'tcx> for InstSimplify { ctx.simplify_bool_cmp(&statement.source_info, rvalue); ctx.simplify_ref_deref(&statement.source_info, rvalue); ctx.simplify_len(&statement.source_info, rvalue); + ctx.simplify_ptr_aggregate(&statement.source_info, rvalue); ctx.simplify_cast(rvalue); } _ => {} @@ -58,8 +59,17 @@ struct InstSimplifyContext<'tcx, 'a> { impl<'tcx> InstSimplifyContext<'tcx, '_> { fn should_simplify(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool { + self.should_simplify_custom(source_info, "Rvalue", rvalue) + } + + fn should_simplify_custom( + &self, + source_info: &SourceInfo, + label: &str, + value: impl std::fmt::Debug, + ) -> bool { self.tcx.consider_optimizing(|| { - format!("InstSimplify - Rvalue: {rvalue:?} SourceInfo: {source_info:?}") + format!("InstSimplify - {label}: {value:?} SourceInfo: {source_info:?}") }) } @@ -147,6 +157,30 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { } } + /// Transform "Aggregate(RawPtr, \[p, ()\])" ==> "Cast(PtrToPtr, p)". + fn simplify_ptr_aggregate(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue + { + let meta_ty = fields.raw[1].ty(self.local_decls, self.tcx); + if meta_ty.is_unit() { + // The mutable borrows we're holding prevent printing `rvalue` here + if !self.should_simplify_custom( + source_info, + "Aggregate::RawPtr", + (&pointee_ty, *mutability, &fields), + ) { + return; + } + + let mut fields = std::mem::take(fields); + let _meta = fields.pop().unwrap(); + let data = fields.pop().unwrap(); + let ptr_ty = Ty::new_ptr(self.tcx, *pointee_ty, *mutability); + *rvalue = Rvalue::Cast(CastKind::PtrToPtr, data, ptr_ty); + } + } + } + fn simplify_ub_check(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::NullaryOp(NullOp::UbChecks, _) = *rvalue { let const_ = Const::from_bool(self.tcx, self.tcx.sess.ub_checks()); diff --git a/tests/mir-opt/instsimplify/casts.rs b/tests/mir-opt/instsimplify/casts.rs index b3bc34af5b70..a7786fa570f1 100644 --- a/tests/mir-opt/instsimplify/casts.rs +++ b/tests/mir-opt/instsimplify/casts.rs @@ -1,6 +1,7 @@ //@ test-mir-pass: InstSimplify //@ compile-flags: -Zinline-mir #![crate_type = "lib"] +#![feature(core_intrinsics)] #[inline(always)] fn generic_cast(x: *const T) -> *const U { @@ -23,3 +24,11 @@ pub fn roundtrip(x: *const u8) -> *const u8 { // CHECK: _2 = move _3 as *const u8 (PointerCoercion(MutToConstPointer)); x as *mut u8 as *const u8 } + +// EMIT_MIR casts.roundtrip.InstSimplify.diff +pub fn cast_thin_via_aggregate(x: *const u8) -> *const () { + // CHECK-LABEL: fn cast_thin_via_aggregate( + // CHECK: _2 = _1; + // CHECK: _0 = move _2 as *const () (PtrToPtr); + std::intrinsics::aggregate_raw_ptr(x, ()) +} diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir index 81474306eecb..37f50d25fc85 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir @@ -28,8 +28,6 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] { scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) { debug data_pointer => _5; debug metadata => _7; - let mut _8: std::ptr::metadata::PtrComponents<[u32]>; - let mut _9: std::ptr::metadata::PtrRepr<[u32]>; } } } @@ -47,13 +45,7 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] { _6 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _1 }; _7 = ((_6.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize); StorageDead(_6); - StorageLive(_9); - StorageLive(_8); - _8 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: _5, metadata: _7 }; - _9 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _8 }; - StorageDead(_8); - _0 = (_9.0: *const [u32]); - StorageDead(_9); + _0 = *const [u32] from (_5, _7); StorageDead(_7); StorageDead(_5); StorageDead(_4); diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir index 81474306eecb..37f50d25fc85 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir @@ -28,8 +28,6 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] { scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) { debug data_pointer => _5; debug metadata => _7; - let mut _8: std::ptr::metadata::PtrComponents<[u32]>; - let mut _9: std::ptr::metadata::PtrRepr<[u32]>; } } } @@ -47,13 +45,7 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] { _6 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _1 }; _7 = ((_6.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize); StorageDead(_6); - StorageLive(_9); - StorageLive(_8); - _8 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: _5, metadata: _7 }; - _9 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _8 }; - StorageDead(_8); - _0 = (_9.0: *const [u32]); - StorageDead(_9); + _0 = *const [u32] from (_5, _7); StorageDead(_7); StorageDead(_5); StorageDead(_4); diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir index d86f2d1106ac..9551f30c7e93 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir @@ -26,29 +26,19 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 { scope 6 (inlined std::ptr::from_raw_parts::) { debug data_pointer => _5; debug metadata => const (); - let mut _6: std::ptr::metadata::PtrComponents; - let mut _7: std::ptr::metadata::PtrRepr; } } } bb0: { - StorageLive(_4); StorageLive(_3); _3 = _1 as *const u8 (PtrToPtr); _4 = Offset(_3, _2); StorageDead(_3); StorageLive(_5); _5 = _4 as *const () (PtrToPtr); - StorageLive(_7); - StorageLive(_6); - _6 = std::ptr::metadata::PtrComponents:: { data_pointer: _5, metadata: const () }; - _7 = std::ptr::metadata::PtrRepr:: { const_ptr: move _6 }; - StorageDead(_6); - _0 = (_7.0: *const u32); - StorageDead(_7); + _0 = _4 as *const u32 (PtrToPtr); StorageDead(_5); - StorageDead(_4); return; } } diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir index d86f2d1106ac..9551f30c7e93 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir @@ -26,29 +26,19 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 { scope 6 (inlined std::ptr::from_raw_parts::) { debug data_pointer => _5; debug metadata => const (); - let mut _6: std::ptr::metadata::PtrComponents; - let mut _7: std::ptr::metadata::PtrRepr; } } } bb0: { - StorageLive(_4); StorageLive(_3); _3 = _1 as *const u8 (PtrToPtr); _4 = Offset(_3, _2); StorageDead(_3); StorageLive(_5); _5 = _4 as *const () (PtrToPtr); - StorageLive(_7); - StorageLive(_6); - _6 = std::ptr::metadata::PtrComponents:: { data_pointer: _5, metadata: const () }; - _7 = std::ptr::metadata::PtrRepr:: { const_ptr: move _6 }; - StorageDead(_6); - _0 = (_7.0: *const u32); - StorageDead(_7); + _0 = _4 as *const u32 (PtrToPtr); StorageDead(_5); - StorageDead(_4); return; } }