Skip to content

Commit 55d1337

Browse files
committed
[GVN] Add tests for generic pointees with PtrMetadata
1 parent 4341cb7 commit 55d1337

File tree

6 files changed

+138
-0
lines changed

6 files changed

+138
-0
lines changed

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

+4
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,10 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
193193
let source = self.parse_operand(args[0])?;
194194
Ok(Rvalue::Cast(CastKind::Transmute, source, expr.ty))
195195
},
196+
@call(mir_cast_ptr_to_ptr, args) => {
197+
let source = self.parse_operand(args[0])?;
198+
Ok(Rvalue::Cast(CastKind::PtrToPtr, source, expr.ty))
199+
},
196200
@call(mir_checked, args) => {
197201
parse_by_kind!(self, args[0], _, "binary op",
198202
ExprKind::Binary { op, lhs, rhs } => {

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,7 @@ symbols! {
11751175
mir_assume,
11761176
mir_basic_block,
11771177
mir_call,
1178+
mir_cast_ptr_to_ptr,
11781179
mir_cast_transmute,
11791180
mir_checked,
11801181
mir_copy_for_deref,

library/core/src/intrinsics/mir.rs

+7
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,13 @@ define!(
444444
/// generated via the normal `mem::transmute`.
445445
fn CastTransmute<T, U>(operand: T) -> U
446446
);
447+
define!(
448+
"mir_cast_ptr_to_ptr",
449+
/// Emits a `CastKind::PtrToPtr` cast.
450+
///
451+
/// This allows bypassing normal validation to generate strange casts.
452+
fn CastPtrToPtr<T, U>(operand: T) -> U
453+
);
447454
define!(
448455
"mir_make_place",
449456
#[doc(hidden)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
- // MIR for `generic_cast_metadata` before GVN
2+
+ // MIR for `generic_cast_metadata` after GVN
3+
4+
fn generic_cast_metadata(_1: *const [T], _2: *const A, _3: *const B) -> () {
5+
let mut _0: ();
6+
let mut _4: *const T;
7+
let mut _5: ();
8+
let mut _6: *const (&A, [T]);
9+
let mut _7: usize;
10+
let mut _8: *const (T, B);
11+
let mut _9: <B as std::ptr::Pointee>::Metadata;
12+
let mut _10: *const (T, A);
13+
let mut _11: <A as std::ptr::Pointee>::Metadata;
14+
let mut _12: *mut A;
15+
let mut _13: <A as std::ptr::Pointee>::Metadata;
16+
let mut _14: *mut B;
17+
let mut _15: <B as std::ptr::Pointee>::Metadata;
18+
19+
bb0: {
20+
_4 = _1 as *const T (PtrToPtr);
21+
_5 = PtrMetadata(_4);
22+
_6 = _1 as *const (&A, [T]) (PtrToPtr);
23+
- _7 = PtrMetadata(_6);
24+
+ _7 = PtrMetadata(_1);
25+
_8 = _2 as *const (T, B) (PtrToPtr);
26+
_9 = PtrMetadata(_8);
27+
_10 = _2 as *const (T, A) (PtrToPtr);
28+
- _11 = PtrMetadata(_10);
29+
+ _11 = PtrMetadata(_2);
30+
_12 = _3 as *mut A (PtrToPtr);
31+
_13 = PtrMetadata(_12);
32+
_14 = _3 as *mut B (PtrToPtr);
33+
- _15 = PtrMetadata(_14);
34+
+ _15 = PtrMetadata(_3);
35+
return;
36+
}
37+
}
38+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
- // MIR for `generic_cast_metadata` before GVN
2+
+ // MIR for `generic_cast_metadata` after GVN
3+
4+
fn generic_cast_metadata(_1: *const [T], _2: *const A, _3: *const B) -> () {
5+
let mut _0: ();
6+
let mut _4: *const T;
7+
let mut _5: ();
8+
let mut _6: *const (&A, [T]);
9+
let mut _7: usize;
10+
let mut _8: *const (T, B);
11+
let mut _9: <B as std::ptr::Pointee>::Metadata;
12+
let mut _10: *const (T, A);
13+
let mut _11: <A as std::ptr::Pointee>::Metadata;
14+
let mut _12: *mut A;
15+
let mut _13: <A as std::ptr::Pointee>::Metadata;
16+
let mut _14: *mut B;
17+
let mut _15: <B as std::ptr::Pointee>::Metadata;
18+
19+
bb0: {
20+
_4 = _1 as *const T (PtrToPtr);
21+
_5 = PtrMetadata(_4);
22+
_6 = _1 as *const (&A, [T]) (PtrToPtr);
23+
- _7 = PtrMetadata(_6);
24+
+ _7 = PtrMetadata(_1);
25+
_8 = _2 as *const (T, B) (PtrToPtr);
26+
_9 = PtrMetadata(_8);
27+
_10 = _2 as *const (T, A) (PtrToPtr);
28+
- _11 = PtrMetadata(_10);
29+
+ _11 = PtrMetadata(_2);
30+
_12 = _3 as *mut A (PtrToPtr);
31+
_13 = PtrMetadata(_12);
32+
_14 = _3 as *mut B (PtrToPtr);
33+
- _15 = PtrMetadata(_14);
34+
+ _15 = PtrMetadata(_3);
35+
return;
36+
}
37+
}
38+

tests/mir-opt/gvn.rs

+50
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,55 @@ fn array_len(x: &mut [i32; 42]) -> usize {
834834
std::intrinsics::ptr_metadata(x)
835835
}
836836

837+
#[custom_mir(dialect = "runtime")]
838+
fn generic_cast_metadata<T, A: ?Sized, B: ?Sized>(ps: *const [T], pa: *const A, pb: *const B) {
839+
// CHECK-LABEL: fn generic_cast_metadata
840+
mir! {
841+
{
842+
// These tests check that we correctly do or don't elide casts
843+
// when the pointee metadata do or don't match, respectively.
844+
845+
// Metadata usize -> (), do not optimize.
846+
// CHECK: [[T:_.+]] = _1 as
847+
// CHECK-NEXT: PtrMetadata([[T]])
848+
let t1 = CastPtrToPtr::<_, *const T>(ps);
849+
let m1 = PtrMetadata(t1);
850+
851+
// `(&A, [T])` has `usize` metadata, same as `[T]`, yes optimize.
852+
// CHECK: [[T:_.+]] = _1 as
853+
// CHECK-NEXT: PtrMetadata(_1)
854+
let t2 = CastPtrToPtr::<_, *const (&A, [T])>(ps);
855+
let m2 = PtrMetadata(t2);
856+
857+
// Tail `A` and tail `B`, do not optimize.
858+
// CHECK: [[T:_.+]] = _2 as
859+
// CHECK-NEXT: PtrMetadata([[T]])
860+
let t3 = CastPtrToPtr::<_, *const (T, B)>(pa);
861+
let m3 = PtrMetadata(t3);
862+
863+
// Both have tail `A`, yes optimize.
864+
// CHECK: [[T:_.+]] = _2 as
865+
// CHECK-NEXT: PtrMetadata(_2)
866+
let t4 = CastPtrToPtr::<_, *const (T, A)>(pa);
867+
let m4 = PtrMetadata(t4);
868+
869+
// Tail `B` and tail `A`, do not optimize.
870+
// CHECK: [[T:_.+]] = _3 as
871+
// CHECK-NEXT: PtrMetadata([[T]])
872+
let t5 = CastPtrToPtr::<_, *mut A>(pb);
873+
let m5 = PtrMetadata(t5);
874+
875+
// Both have tail `B`, yes optimize.
876+
// CHECK: [[T:_.+]] = _3 as
877+
// CHECK-NEXT: PtrMetadata(_3)
878+
let t6 = CastPtrToPtr::<_, *mut B>(pb);
879+
let m6 = PtrMetadata(t6);
880+
881+
Return()
882+
}
883+
}
884+
}
885+
837886
fn main() {
838887
subexpression_elimination(2, 4, 5);
839888
wrap_unwrap(5);
@@ -900,3 +949,4 @@ fn identity<T>(x: T) -> T {
900949
// EMIT_MIR gvn.casts_before_aggregate_raw_ptr.GVN.diff
901950
// EMIT_MIR gvn.manual_slice_mut_len.GVN.diff
902951
// EMIT_MIR gvn.array_len.GVN.diff
952+
// EMIT_MIR gvn.generic_cast_metadata.GVN.diff

0 commit comments

Comments
 (0)