From 511bd8b44706a419526d6efa928436cafd602abf Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 16 Jun 2024 22:25:57 -0700 Subject: [PATCH] [GVN] Add tests for generic pointees with PtrMetadata --- .../src/build/custom/parse/instruction.rs | 4 ++ compiler/rustc_span/src/symbol.rs | 1 + library/core/src/intrinsics/mir.rs | 7 ++++ ...generic_cast_metadata.GVN.panic-abort.diff | 38 +++++++++++++++++ ...eneric_cast_metadata.GVN.panic-unwind.diff | 38 +++++++++++++++++ tests/mir-opt/gvn.rs | 41 +++++++++++++++++++ 6 files changed, 129 insertions(+) create mode 100644 tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff create mode 100644 tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index b1a305efa4c68..7549481c1b301 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -193,6 +193,10 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { let source = self.parse_operand(args[0])?; Ok(Rvalue::Cast(CastKind::Transmute, source, expr.ty)) }, + @call(mir_cast_ptr_to_ptr, args) => { + let source = self.parse_operand(args[0])?; + Ok(Rvalue::Cast(CastKind::PtrToPtr, source, expr.ty)) + }, @call(mir_checked, args) => { parse_by_kind!(self, args[0], _, "binary op", ExprKind::Binary { op, lhs, rhs } => { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 55eba257ca21d..a508c2794390e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1175,6 +1175,7 @@ symbols! { mir_assume, mir_basic_block, mir_call, + mir_cast_ptr_to_ptr, mir_cast_transmute, mir_checked, mir_copy_for_deref, diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index ec8488009b96b..1daf1d723fb95 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -444,6 +444,13 @@ define!( /// generated via the normal `mem::transmute`. fn CastTransmute(operand: T) -> U ); +define!( + "mir_cast_ptr_to_ptr", + /// Emits a `CastKind::PtrToPtr` cast. + /// + /// This allows bypassing normal validation to generate strange casts. + fn CastPtrToPtr(operand: T) -> U +); define!( "mir_make_place", #[doc(hidden)] diff --git a/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff new file mode 100644 index 0000000000000..1d462a8a23c2e --- /dev/null +++ b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff @@ -0,0 +1,38 @@ +- // MIR for `generic_cast_metadata` before GVN ++ // MIR for `generic_cast_metadata` after GVN + + fn generic_cast_metadata(_1: *const [T], _2: *const A, _3: *const B) -> () { + let mut _0: (); + let mut _4: *const T; + let mut _5: (); + let mut _6: *const (&A, [T]); + let mut _7: usize; + let mut _8: *const (T, B); + let mut _9: ::Metadata; + let mut _10: *const (T, A); + let mut _11: ::Metadata; + let mut _12: *mut A; + let mut _13: ::Metadata; + let mut _14: *mut B; + let mut _15: ::Metadata; + + bb0: { + _4 = _1 as *const T (PtrToPtr); + _5 = PtrMetadata(_4); + _6 = _1 as *const (&A, [T]) (PtrToPtr); +- _7 = PtrMetadata(_6); ++ _7 = PtrMetadata(_1); + _8 = _2 as *const (T, B) (PtrToPtr); + _9 = PtrMetadata(_8); + _10 = _2 as *const (T, A) (PtrToPtr); +- _11 = PtrMetadata(_10); ++ _11 = PtrMetadata(_2); + _12 = _3 as *mut A (PtrToPtr); + _13 = PtrMetadata(_12); + _14 = _3 as *mut B (PtrToPtr); +- _15 = PtrMetadata(_14); ++ _15 = PtrMetadata(_3); + return; + } + } + diff --git a/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff new file mode 100644 index 0000000000000..1d462a8a23c2e --- /dev/null +++ b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff @@ -0,0 +1,38 @@ +- // MIR for `generic_cast_metadata` before GVN ++ // MIR for `generic_cast_metadata` after GVN + + fn generic_cast_metadata(_1: *const [T], _2: *const A, _3: *const B) -> () { + let mut _0: (); + let mut _4: *const T; + let mut _5: (); + let mut _6: *const (&A, [T]); + let mut _7: usize; + let mut _8: *const (T, B); + let mut _9: ::Metadata; + let mut _10: *const (T, A); + let mut _11: ::Metadata; + let mut _12: *mut A; + let mut _13: ::Metadata; + let mut _14: *mut B; + let mut _15: ::Metadata; + + bb0: { + _4 = _1 as *const T (PtrToPtr); + _5 = PtrMetadata(_4); + _6 = _1 as *const (&A, [T]) (PtrToPtr); +- _7 = PtrMetadata(_6); ++ _7 = PtrMetadata(_1); + _8 = _2 as *const (T, B) (PtrToPtr); + _9 = PtrMetadata(_8); + _10 = _2 as *const (T, A) (PtrToPtr); +- _11 = PtrMetadata(_10); ++ _11 = PtrMetadata(_2); + _12 = _3 as *mut A (PtrToPtr); + _13 = PtrMetadata(_12); + _14 = _3 as *mut B (PtrToPtr); +- _15 = PtrMetadata(_14); ++ _15 = PtrMetadata(_3); + return; + } + } + diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 74f1849c42a91..9d114472b4c5c 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -834,6 +834,46 @@ fn array_len(x: &mut [i32; 42]) -> usize { std::intrinsics::ptr_metadata(x) } +#[custom_mir(dialect = "runtime")] +fn generic_cast_metadata(ps: *const [T], pa: *const A, pb: *const B) { + // CHECK-LABEL: fn generic_cast_metadata + mir! { + { + // CHECK: [[T:_.+]] = _1 as + // CHECK-NEXT: PtrMetadata([[T]]) + let t1 = CastPtrToPtr::<_, *const T>(ps); + let m1 = PtrMetadata(t1); + + // CHECK: [[T:_.+]] = _1 as + // CHECK-NEXT: PtrMetadata(_1) + let t2 = CastPtrToPtr::<_, *const (&A, [T])>(ps); + let m2 = PtrMetadata(t2); + + // CHECK: [[T:_.+]] = _2 as + // CHECK-NEXT: PtrMetadata([[T]]) + let t3 = CastPtrToPtr::<_, *const (T, B)>(pa); + let m3 = PtrMetadata(t3); + + // CHECK: [[T:_.+]] = _2 as + // CHECK-NEXT: PtrMetadata(_2) + let t4 = CastPtrToPtr::<_, *const (T, A)>(pa); + let m4 = PtrMetadata(t4); + + // CHECK: [[T:_.+]] = _3 as + // CHECK-NEXT: PtrMetadata([[T]]) + let t5 = CastPtrToPtr::<_, *mut A>(pb); + let m5 = PtrMetadata(t5); + + // CHECK: [[T:_.+]] = _3 as + // CHECK-NEXT: PtrMetadata(_3) + let t6 = CastPtrToPtr::<_, *mut B>(pb); + let m6 = PtrMetadata(t6); + + Return() + } + } +} + fn main() { subexpression_elimination(2, 4, 5); wrap_unwrap(5); @@ -900,3 +940,4 @@ fn identity(x: T) -> T { // EMIT_MIR gvn.casts_before_aggregate_raw_ptr.GVN.diff // EMIT_MIR gvn.manual_slice_mut_len.GVN.diff // EMIT_MIR gvn.array_len.GVN.diff +// EMIT_MIR gvn.generic_cast_metadata.GVN.diff