Skip to content

Commit

Permalink
[GVN] Add tests for generic pointees with PtrMetadata
Browse files Browse the repository at this point in the history
  • Loading branch information
scottmcm committed Jun 21, 2024
1 parent 4341cb7 commit 55d1337
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 } => {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions library/core/src/intrinsics/mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,13 @@ define!(
/// generated via the normal `mem::transmute`.
fn CastTransmute<T, U>(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<T, U>(operand: T) -> U
);
define!(
"mir_make_place",
#[doc(hidden)]
Expand Down
38 changes: 38 additions & 0 deletions tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff
Original file line number Diff line number Diff line change
@@ -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: <B as std::ptr::Pointee>::Metadata;
let mut _10: *const (T, A);
let mut _11: <A as std::ptr::Pointee>::Metadata;
let mut _12: *mut A;
let mut _13: <A as std::ptr::Pointee>::Metadata;
let mut _14: *mut B;
let mut _15: <B as std::ptr::Pointee>::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;
}
}

38 changes: 38 additions & 0 deletions tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff
Original file line number Diff line number Diff line change
@@ -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: <B as std::ptr::Pointee>::Metadata;
let mut _10: *const (T, A);
let mut _11: <A as std::ptr::Pointee>::Metadata;
let mut _12: *mut A;
let mut _13: <A as std::ptr::Pointee>::Metadata;
let mut _14: *mut B;
let mut _15: <B as std::ptr::Pointee>::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;
}
}

50 changes: 50 additions & 0 deletions tests/mir-opt/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,55 @@ fn array_len(x: &mut [i32; 42]) -> usize {
std::intrinsics::ptr_metadata(x)
}

#[custom_mir(dialect = "runtime")]
fn generic_cast_metadata<T, A: ?Sized, B: ?Sized>(ps: *const [T], pa: *const A, pb: *const B) {
// CHECK-LABEL: fn generic_cast_metadata
mir! {
{
// These tests check that we correctly do or don't elide casts
// when the pointee metadata do or don't match, respectively.

// Metadata usize -> (), do not optimize.
// CHECK: [[T:_.+]] = _1 as
// CHECK-NEXT: PtrMetadata([[T]])
let t1 = CastPtrToPtr::<_, *const T>(ps);
let m1 = PtrMetadata(t1);

// `(&A, [T])` has `usize` metadata, same as `[T]`, yes optimize.
// CHECK: [[T:_.+]] = _1 as
// CHECK-NEXT: PtrMetadata(_1)
let t2 = CastPtrToPtr::<_, *const (&A, [T])>(ps);
let m2 = PtrMetadata(t2);

// Tail `A` and tail `B`, do not optimize.
// CHECK: [[T:_.+]] = _2 as
// CHECK-NEXT: PtrMetadata([[T]])
let t3 = CastPtrToPtr::<_, *const (T, B)>(pa);
let m3 = PtrMetadata(t3);

// Both have tail `A`, yes optimize.
// CHECK: [[T:_.+]] = _2 as
// CHECK-NEXT: PtrMetadata(_2)
let t4 = CastPtrToPtr::<_, *const (T, A)>(pa);
let m4 = PtrMetadata(t4);

// Tail `B` and tail `A`, do not optimize.
// CHECK: [[T:_.+]] = _3 as
// CHECK-NEXT: PtrMetadata([[T]])
let t5 = CastPtrToPtr::<_, *mut A>(pb);
let m5 = PtrMetadata(t5);

// Both have tail `B`, yes optimize.
// 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);
Expand Down Expand Up @@ -900,3 +949,4 @@ fn identity<T>(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

0 comments on commit 55d1337

Please sign in to comment.