[GVN] Add tests for generic pointees with PtrMetadata
This commit is contained in:
parent
4341cb709d
commit
55d13379ac
@ -193,6 +193,10 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
|||||||
let source = self.parse_operand(args[0])?;
|
let source = self.parse_operand(args[0])?;
|
||||||
Ok(Rvalue::Cast(CastKind::Transmute, source, expr.ty))
|
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) => {
|
@call(mir_checked, args) => {
|
||||||
parse_by_kind!(self, args[0], _, "binary op",
|
parse_by_kind!(self, args[0], _, "binary op",
|
||||||
ExprKind::Binary { op, lhs, rhs } => {
|
ExprKind::Binary { op, lhs, rhs } => {
|
||||||
|
@ -1175,6 +1175,7 @@ symbols! {
|
|||||||
mir_assume,
|
mir_assume,
|
||||||
mir_basic_block,
|
mir_basic_block,
|
||||||
mir_call,
|
mir_call,
|
||||||
|
mir_cast_ptr_to_ptr,
|
||||||
mir_cast_transmute,
|
mir_cast_transmute,
|
||||||
mir_checked,
|
mir_checked,
|
||||||
mir_copy_for_deref,
|
mir_copy_for_deref,
|
||||||
|
@ -444,6 +444,13 @@ define!(
|
|||||||
/// generated via the normal `mem::transmute`.
|
/// generated via the normal `mem::transmute`.
|
||||||
fn CastTransmute<T, U>(operand: T) -> U
|
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!(
|
define!(
|
||||||
"mir_make_place",
|
"mir_make_place",
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
38
tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff
Normal file
38
tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -834,6 +834,55 @@ fn array_len(x: &mut [i32; 42]) -> usize {
|
|||||||
std::intrinsics::ptr_metadata(x)
|
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() {
|
fn main() {
|
||||||
subexpression_elimination(2, 4, 5);
|
subexpression_elimination(2, 4, 5);
|
||||||
wrap_unwrap(5);
|
wrap_unwrap(5);
|
||||||
@ -900,3 +949,4 @@ fn identity<T>(x: T) -> T {
|
|||||||
// EMIT_MIR gvn.casts_before_aggregate_raw_ptr.GVN.diff
|
// EMIT_MIR gvn.casts_before_aggregate_raw_ptr.GVN.diff
|
||||||
// EMIT_MIR gvn.manual_slice_mut_len.GVN.diff
|
// EMIT_MIR gvn.manual_slice_mut_len.GVN.diff
|
||||||
// EMIT_MIR gvn.array_len.GVN.diff
|
// EMIT_MIR gvn.array_len.GVN.diff
|
||||||
|
// EMIT_MIR gvn.generic_cast_metadata.GVN.diff
|
||||||
|
Loading…
x
Reference in New Issue
Block a user