Skip to content

Commit

Permalink
[mir-opt] GVN some more transmute cases
Browse files Browse the repository at this point in the history
We already did `Transmute`-then-`PtrToPtr`; this adds the nearly-identical `PtrToPtr`-then-`Transmute`.

It also adds `transmute(Foo(x))` → `transmute(x)`, when `Foo` is a single-field transparent type.  That's useful for things like `NonNull { pointer: p }.as_ptr()`.

Found these as I was looking at MCP807-related changes.
  • Loading branch information
scottmcm committed Dec 5, 2024
1 parent 96e51d9 commit 3a9056e
Show file tree
Hide file tree
Showing 26 changed files with 886 additions and 598 deletions.
42 changes: 42 additions & 0 deletions compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,28 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
}
}

// Aggregate-then-Transmute can just transmute the original field value,
// so long as the type is transparent over only that one single field.
if let Transmute = kind
&& let Value::Aggregate(
AggregateTy::Def(aggregate_did, aggregate_args),
FIRST_VARIANT,
field_values,
) = self.get(value)
&& let [single_field_value] = **field_values
&& let adt = self.tcx.adt_def(aggregate_did)
&& adt.is_struct()
&& adt.repr().transparent()
{
let field_ty = adt.non_enum_variant().single_field().ty(self.tcx, aggregate_args);
from = field_ty;
value = single_field_value;
was_updated = true;
if field_ty == to {
return Some(single_field_value);
}
}

// PtrToPtr-then-Transmute can just transmute the original, so long as the
// PtrToPtr didn't change metadata (and thus the size of the pointer)
if let Transmute = kind
Expand All @@ -1426,6 +1448,26 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
}
}

// PtrToPtr-then-Transmute can just transmute the original, so long as the
// PtrToPtr didn't change metadata (and thus the size of the pointer)
if let PtrToPtr = kind
&& let Value::Cast {
kind: Transmute,
value: inner_value,
from: inner_from,
to: _inner_to,
} = *self.get(value)
&& self.pointers_have_same_metadata(from, to)
{
*kind = Transmute;
from = inner_from;
value = inner_value;
was_updated = true;
if inner_from == to {
return Some(inner_value);
}
}

if was_updated && let Some(op) = self.try_as_operand(value, location) {
*operand = op;
}
Expand Down
23 changes: 0 additions & 23 deletions compiler/rustc_mir_transform/src/instsimplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,29 +187,6 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
*kind = CastKind::IntToInt;
return;
}

// Transmuting a transparent struct/union to a field's type is a projection
if let ty::Adt(adt_def, args) = operand_ty.kind()
&& adt_def.repr().transparent()
&& (adt_def.is_struct() || adt_def.is_union())
&& let Some(place) = operand.place()
{
let variant = adt_def.non_enum_variant();
for (i, field) in variant.fields.iter_enumerated() {
let field_ty = field.ty(self.tcx, args);
if field_ty == *cast_ty {
let place = place
.project_deeper(&[ProjectionElem::Field(i, *cast_ty)], self.tcx);
let operand = if operand.is_move() {
Operand::Move(place)
} else {
Operand::Copy(place)
};
*rvalue = Rvalue::Use(operand);
return;
}
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
StorageLive(_7);
_7 = const 1_usize;
_6 = const {0x1 as *mut [bool; 0]};
StorageDead(_7);
StorageLive(_11);
StorageLive(_8);
_8 = UbChecks();
Expand Down Expand Up @@ -79,6 +78,7 @@
_11 = const {0x1 as *const [bool; 0]};
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
StorageDead(_11);
StorageDead(_7);
StorageDead(_6);
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
StorageDead(_5);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
StorageLive(_7);
_7 = const 1_usize;
_6 = const {0x1 as *mut [bool; 0]};
StorageDead(_7);
StorageLive(_11);
StorageLive(_8);
_8 = UbChecks();
Expand Down Expand Up @@ -83,6 +82,7 @@
_11 = const {0x1 as *const [bool; 0]};
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
StorageDead(_11);
StorageDead(_7);
StorageDead(_6);
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
StorageDead(_5);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
StorageLive(_7);
_7 = const 1_usize;
_6 = const {0x1 as *mut [bool; 0]};
StorageDead(_7);
StorageLive(_11);
StorageLive(_8);
_8 = UbChecks();
Expand Down Expand Up @@ -79,6 +78,7 @@
_11 = const {0x1 as *const [bool; 0]};
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
StorageDead(_11);
StorageDead(_7);
StorageDead(_6);
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
StorageDead(_5);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
StorageLive(_7);
_7 = const 1_usize;
_6 = const {0x1 as *mut [bool; 0]};
StorageDead(_7);
StorageLive(_11);
StorageLive(_8);
_8 = UbChecks();
Expand Down Expand Up @@ -83,6 +82,7 @@
_11 = const {0x1 as *const [bool; 0]};
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
StorageDead(_11);
StorageDead(_7);
StorageDead(_6);
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
StorageDead(_5);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
- _6 = copy _7 as *mut [bool; 0] (Transmute);
+ _7 = const 1_usize;
+ _6 = const {0x1 as *mut [bool; 0]};
StorageDead(_7);
StorageLive(_11);
StorageLive(_8);
_8 = UbChecks();
Expand All @@ -67,7 +66,7 @@

bb2: {
StorageLive(_10);
- _10 = copy _6 as *mut () (PtrToPtr);
- _10 = copy _7 as *mut () (Transmute);
- _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
+ _10 = const {0x1 as *mut ()};
+ _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable];
Expand All @@ -80,11 +79,12 @@

bb4: {
StorageDead(_8);
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
- _11 = copy _7 as *const [bool; 0] (Transmute);
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
+ _11 = const {0x1 as *const [bool; 0]};
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
StorageDead(_11);
StorageDead(_7);
StorageDead(_6);
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
- _6 = copy _7 as *mut [bool; 0] (Transmute);
+ _7 = const 1_usize;
+ _6 = const {0x1 as *mut [bool; 0]};
StorageDead(_7);
StorageLive(_11);
StorageLive(_8);
_8 = UbChecks();
Expand All @@ -71,7 +70,7 @@

bb3: {
StorageLive(_10);
- _10 = copy _6 as *mut () (PtrToPtr);
- _10 = copy _7 as *mut () (Transmute);
- _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
+ _10 = const {0x1 as *mut ()};
+ _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable];
Expand All @@ -84,11 +83,12 @@

bb5: {
StorageDead(_8);
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
- _11 = copy _7 as *const [bool; 0] (Transmute);
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
+ _11 = const {0x1 as *const [bool; 0]};
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
StorageDead(_11);
StorageDead(_7);
StorageDead(_6);
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
- _6 = copy _7 as *mut [bool; 0] (Transmute);
+ _7 = const 1_usize;
+ _6 = const {0x1 as *mut [bool; 0]};
StorageDead(_7);
StorageLive(_11);
StorageLive(_8);
_8 = UbChecks();
Expand All @@ -67,7 +66,7 @@

bb2: {
StorageLive(_10);
- _10 = copy _6 as *mut () (PtrToPtr);
- _10 = copy _7 as *mut () (Transmute);
- _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
+ _10 = const {0x1 as *mut ()};
+ _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable];
Expand All @@ -80,11 +79,12 @@

bb4: {
StorageDead(_8);
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
- _11 = copy _7 as *const [bool; 0] (Transmute);
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
+ _11 = const {0x1 as *const [bool; 0]};
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
StorageDead(_11);
StorageDead(_7);
StorageDead(_6);
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
- _6 = copy _7 as *mut [bool; 0] (Transmute);
+ _7 = const 1_usize;
+ _6 = const {0x1 as *mut [bool; 0]};
StorageDead(_7);
StorageLive(_11);
StorageLive(_8);
_8 = UbChecks();
Expand All @@ -71,7 +70,7 @@

bb3: {
StorageLive(_10);
- _10 = copy _6 as *mut () (PtrToPtr);
- _10 = copy _7 as *mut () (Transmute);
- _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
+ _10 = const {0x1 as *mut ()};
+ _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable];
Expand All @@ -84,11 +83,12 @@

bb5: {
StorageDead(_8);
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
- _11 = copy _7 as *const [bool; 0] (Transmute);
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
+ _11 = const {0x1 as *const [bool; 0]};
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
StorageDead(_11);
StorageDead(_7);
StorageDead(_6);
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
- // MIR for `aggregate_struct_then_transmute` before GVN
+ // MIR for `aggregate_struct_then_transmute` after GVN

fn aggregate_struct_then_transmute(_1: u16) -> () {
debug id => _1;
let mut _0: ();
let _2: MyId;
let mut _3: u16;
let _4: ();
let mut _5: u16;
let mut _6: MyId;
let mut _8: u16;
let mut _9: std::marker::PhantomData<std::string::String>;
let _10: ();
let mut _11: u16;
let mut _12: TypedId<std::string::String>;
scope 1 {
debug a => _2;
let _7: TypedId<std::string::String>;
scope 2 {
debug b => _7;
}
}

bb0: {
- StorageLive(_2);
+ nop;
StorageLive(_3);
_3 = copy _1;
- _2 = MyId(move _3);
+ _2 = MyId(copy _1);
StorageDead(_3);
StorageLive(_4);
StorageLive(_5);
StorageLive(_6);
- _6 = move _2;
- _5 = move _6 as u16 (Transmute);
+ _6 = copy _2;
+ _5 = copy _1;
StorageDead(_6);
- _4 = opaque::<u16>(move _5) -> [return: bb1, unwind unreachable];
+ _4 = opaque::<u16>(copy _1) -> [return: bb1, unwind unreachable];
}

bb1: {
StorageDead(_5);
StorageDead(_4);
- StorageLive(_7);
+ nop;
StorageLive(_8);
_8 = copy _1;
StorageLive(_9);
- _9 = PhantomData::<String>;
- _7 = TypedId::<String>(move _8, move _9);
+ _9 = const PhantomData::<String>;
+ _7 = TypedId::<String>(copy _1, const PhantomData::<String>);
StorageDead(_9);
StorageDead(_8);
StorageLive(_10);
StorageLive(_11);
StorageLive(_12);
- _12 = move _7;
- _11 = move _12 as u16 (Transmute);
+ _12 = copy _7;
+ _11 = copy _7 as u16 (Transmute);
StorageDead(_12);
_10 = opaque::<u16>(move _11) -> [return: bb2, unwind unreachable];
}

bb2: {
StorageDead(_11);
StorageDead(_10);
_0 = const ();
- StorageDead(_7);
- StorageDead(_2);
+ nop;
+ nop;
return;
}
}

Loading

0 comments on commit 3a9056e

Please sign in to comment.