Skip to content

Commit 1de5951

Browse files
committed
[mir-opt] GVN some more transmute cases
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.
1 parent 2d0ea79 commit 1de5951

14 files changed

+432
-17
lines changed

Diff for: compiler/rustc_mir_transform/src/gvn.rs

+42
Original file line numberDiff line numberDiff line change
@@ -1405,6 +1405,28 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
14051405
}
14061406
}
14071407

1408+
// Aggregate-then-Transmute can just transmute the original field value,
1409+
// so long as the type is transparent over only that one single field.
1410+
if let Transmute = kind
1411+
&& let Value::Aggregate(
1412+
AggregateTy::Def(aggregate_did, aggregate_args),
1413+
FIRST_VARIANT,
1414+
field_values,
1415+
) = self.get(value)
1416+
&& let [single_field_value] = **field_values
1417+
&& let adt = self.tcx.adt_def(aggregate_did)
1418+
&& adt.is_struct()
1419+
&& adt.repr().transparent()
1420+
{
1421+
let field_ty = adt.non_enum_variant().single_field().ty(self.tcx, aggregate_args);
1422+
from = field_ty;
1423+
value = single_field_value;
1424+
was_updated = true;
1425+
if field_ty == to {
1426+
return Some(single_field_value);
1427+
}
1428+
}
1429+
14081430
// PtrToPtr-then-Transmute can just transmute the original, so long as the
14091431
// PtrToPtr didn't change metadata (and thus the size of the pointer)
14101432
if let Transmute = kind
@@ -1424,6 +1446,26 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
14241446
}
14251447
}
14261448

1449+
// PtrToPtr-then-Transmute can just transmute the original, so long as the
1450+
// PtrToPtr didn't change metadata (and thus the size of the pointer)
1451+
if let PtrToPtr = kind
1452+
&& let Value::Cast {
1453+
kind: Transmute,
1454+
value: inner_value,
1455+
from: inner_from,
1456+
to: _inner_to,
1457+
} = *self.get(value)
1458+
&& self.pointers_have_same_metadata(from, to)
1459+
{
1460+
*kind = Transmute;
1461+
from = inner_from;
1462+
value = inner_value;
1463+
was_updated = true;
1464+
if inner_from == to {
1465+
return Some(inner_value);
1466+
}
1467+
}
1468+
14271469
if was_updated && let Some(op) = self.try_as_operand(value, location) {
14281470
*operand = op;
14291471
}

Diff for: tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
StorageLive(_7);
5252
_7 = const 1_usize;
5353
_6 = const {0x1 as *mut [bool; 0]};
54-
StorageDead(_7);
5554
StorageLive(_11);
5655
StorageLive(_8);
5756
_8 = UbChecks();
@@ -79,6 +78,7 @@
7978
_11 = const {0x1 as *const [bool; 0]};
8079
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
8180
StorageDead(_11);
81+
StorageDead(_7);
8282
StorageDead(_6);
8383
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
8484
StorageDead(_5);

Diff for: tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
StorageLive(_7);
5252
_7 = const 1_usize;
5353
_6 = const {0x1 as *mut [bool; 0]};
54-
StorageDead(_7);
5554
StorageLive(_11);
5655
StorageLive(_8);
5756
_8 = UbChecks();
@@ -83,6 +82,7 @@
8382
_11 = const {0x1 as *const [bool; 0]};
8483
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
8584
StorageDead(_11);
85+
StorageDead(_7);
8686
StorageDead(_6);
8787
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
8888
StorageDead(_5);

Diff for: tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
StorageLive(_7);
5252
_7 = const 1_usize;
5353
_6 = const {0x1 as *mut [bool; 0]};
54-
StorageDead(_7);
5554
StorageLive(_11);
5655
StorageLive(_8);
5756
_8 = UbChecks();
@@ -79,6 +78,7 @@
7978
_11 = const {0x1 as *const [bool; 0]};
8079
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
8180
StorageDead(_11);
81+
StorageDead(_7);
8282
StorageDead(_6);
8383
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
8484
StorageDead(_5);

Diff for: tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
StorageLive(_7);
5252
_7 = const 1_usize;
5353
_6 = const {0x1 as *mut [bool; 0]};
54-
StorageDead(_7);
5554
StorageLive(_11);
5655
StorageLive(_8);
5756
_8 = UbChecks();
@@ -83,6 +82,7 @@
8382
_11 = const {0x1 as *const [bool; 0]};
8483
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
8584
StorageDead(_11);
85+
StorageDead(_7);
8686
StorageDead(_6);
8787
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
8888
StorageDead(_5);

Diff for: tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
- _6 = copy _7 as *mut [bool; 0] (Transmute);
5454
+ _7 = const 1_usize;
5555
+ _6 = const {0x1 as *mut [bool; 0]};
56-
StorageDead(_7);
5756
StorageLive(_11);
5857
StorageLive(_8);
5958
_8 = UbChecks();
@@ -67,7 +66,7 @@
6766

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

8180
bb4: {
8281
StorageDead(_8);
83-
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
82+
- _11 = copy _7 as *const [bool; 0] (Transmute);
8483
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
8584
+ _11 = const {0x1 as *const [bool; 0]};
8685
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
8786
StorageDead(_11);
87+
StorageDead(_7);
8888
StorageDead(_6);
8989
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
9090
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};

Diff for: tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
- _6 = copy _7 as *mut [bool; 0] (Transmute);
5454
+ _7 = const 1_usize;
5555
+ _6 = const {0x1 as *mut [bool; 0]};
56-
StorageDead(_7);
5756
StorageLive(_11);
5857
StorageLive(_8);
5958
_8 = UbChecks();
@@ -71,7 +70,7 @@
7170

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

8584
bb5: {
8685
StorageDead(_8);
87-
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
86+
- _11 = copy _7 as *const [bool; 0] (Transmute);
8887
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
8988
+ _11 = const {0x1 as *const [bool; 0]};
9089
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
9190
StorageDead(_11);
91+
StorageDead(_7);
9292
StorageDead(_6);
9393
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
9494
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};

Diff for: tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
- _6 = copy _7 as *mut [bool; 0] (Transmute);
5454
+ _7 = const 1_usize;
5555
+ _6 = const {0x1 as *mut [bool; 0]};
56-
StorageDead(_7);
5756
StorageLive(_11);
5857
StorageLive(_8);
5958
_8 = UbChecks();
@@ -67,7 +66,7 @@
6766

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

8180
bb4: {
8281
StorageDead(_8);
83-
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
82+
- _11 = copy _7 as *const [bool; 0] (Transmute);
8483
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
8584
+ _11 = const {0x1 as *const [bool; 0]};
8685
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
8786
StorageDead(_11);
87+
StorageDead(_7);
8888
StorageDead(_6);
8989
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
9090
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};

Diff for: tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
- _6 = copy _7 as *mut [bool; 0] (Transmute);
5454
+ _7 = const 1_usize;
5555
+ _6 = const {0x1 as *mut [bool; 0]};
56-
StorageDead(_7);
5756
StorageLive(_11);
5857
StorageLive(_8);
5958
_8 = UbChecks();
@@ -71,7 +70,7 @@
7170

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

8584
bb5: {
8685
StorageDead(_8);
87-
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
86+
- _11 = copy _7 as *const [bool; 0] (Transmute);
8887
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
8988
+ _11 = const {0x1 as *const [bool; 0]};
9089
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
9190
StorageDead(_11);
91+
StorageDead(_7);
9292
StorageDead(_6);
9393
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
9494
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
- // MIR for `aggregate_struct_then_transmute` before GVN
2+
+ // MIR for `aggregate_struct_then_transmute` after GVN
3+
4+
fn aggregate_struct_then_transmute(_1: u16) -> () {
5+
debug id => _1;
6+
let mut _0: ();
7+
let _2: MyId;
8+
let mut _3: u16;
9+
let _4: ();
10+
let mut _5: u16;
11+
let mut _6: MyId;
12+
let mut _8: u16;
13+
let mut _9: std::marker::PhantomData<std::string::String>;
14+
let _10: ();
15+
let mut _11: u16;
16+
let mut _12: TypedId<std::string::String>;
17+
scope 1 {
18+
debug a => _2;
19+
let _7: TypedId<std::string::String>;
20+
scope 2 {
21+
debug b => _7;
22+
}
23+
}
24+
25+
bb0: {
26+
- StorageLive(_2);
27+
+ nop;
28+
StorageLive(_3);
29+
_3 = copy _1;
30+
- _2 = MyId(move _3);
31+
+ _2 = MyId(copy _1);
32+
StorageDead(_3);
33+
StorageLive(_4);
34+
StorageLive(_5);
35+
StorageLive(_6);
36+
- _6 = move _2;
37+
- _5 = move _6 as u16 (Transmute);
38+
+ _6 = copy _2;
39+
+ _5 = copy _1;
40+
StorageDead(_6);
41+
- _4 = opaque::<u16>(move _5) -> [return: bb1, unwind unreachable];
42+
+ _4 = opaque::<u16>(copy _1) -> [return: bb1, unwind unreachable];
43+
}
44+
45+
bb1: {
46+
StorageDead(_5);
47+
StorageDead(_4);
48+
- StorageLive(_7);
49+
+ nop;
50+
StorageLive(_8);
51+
_8 = copy _1;
52+
StorageLive(_9);
53+
- _9 = PhantomData::<String>;
54+
- _7 = TypedId::<String>(move _8, move _9);
55+
+ _9 = const PhantomData::<String>;
56+
+ _7 = TypedId::<String>(copy _1, const PhantomData::<String>);
57+
StorageDead(_9);
58+
StorageDead(_8);
59+
StorageLive(_10);
60+
StorageLive(_11);
61+
StorageLive(_12);
62+
- _12 = move _7;
63+
- _11 = move _12 as u16 (Transmute);
64+
+ _12 = copy _7;
65+
+ _11 = copy _7 as u16 (Transmute);
66+
StorageDead(_12);
67+
_10 = opaque::<u16>(move _11) -> [return: bb2, unwind unreachable];
68+
}
69+
70+
bb2: {
71+
StorageDead(_11);
72+
StorageDead(_10);
73+
_0 = const ();
74+
- StorageDead(_7);
75+
- StorageDead(_2);
76+
+ nop;
77+
+ nop;
78+
return;
79+
}
80+
}
81+

0 commit comments

Comments
 (0)