Skip to content

Commit 45a1603

Browse files
committed
Turn field accesses into a transmute if followed by a transmute anyway
1 parent 98e7077 commit 45a1603

9 files changed

Lines changed: 51 additions & 14 deletions

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
14941494
}
14951495
}
14961496

1497+
#[instrument(level = "trace", skip(self), ret)]
14971498
fn simplify_cast(
14981499
&mut self,
14991500
initial_kind: &mut CastKind,
@@ -1549,6 +1550,30 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
15491550
}
15501551
}
15511552

1553+
// Field-Access-then-Transmute can just transmute the original value,
1554+
// so long as the bytes of a value from only from a single field.
1555+
if let Transmute = kind
1556+
&& let Value::Projection(field_value, ProjectionElem::Field(field_idx, ())) =
1557+
self.get(value)
1558+
{
1559+
if let Value::Projection(
1560+
_downcast_value,
1561+
ProjectionElem::Downcast(_, _variant_idx),
1562+
) = self.get(field_value)
1563+
{
1564+
} else if let Some((f_idx, field_ty)) =
1565+
self.value_is_all_in_one_field(self.ty(field_value), FIRST_VARIANT)
1566+
{
1567+
assert_eq!(field_idx, f_idx, "{from} -> {field_ty}");
1568+
from = self.ty(field_value);
1569+
value = field_value;
1570+
was_updated_this_iteration = true;
1571+
if field_ty == to {
1572+
return Some(value);
1573+
}
1574+
}
1575+
}
1576+
15521577
// Aggregate-then-Transmute can just transmute the original field value,
15531578
// so long as the bytes of a value from only from a single field.
15541579
if let Transmute = kind

tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
- _1 = const 1_usize as std::boxed::Box<Never> (Transmute);
1515
- _2 = copy ((_1.0: std::ptr::Unique<Never>).0: std::ptr::NonNull<Never>) as *const Never (Transmute);
1616
+ _1 = const Box::<Never>(std::ptr::Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global);
17-
+ _2 = const std::ptr::NonNull::<Never> {{ pointer: {0x1 as *const Never} }} as *const Never (Transmute);
17+
+ _2 = const std::boxed::Box::<Never>(std::ptr::Unique::<Never> {{ pointer: std::ptr::NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: std::marker::PhantomData::<Never> }}, std::alloc::Global) as *const Never (Transmute);
1818
unreachable;
1919
}
2020
}

tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
- _1 = const 1_usize as std::boxed::Box<Never> (Transmute);
1515
- _2 = copy ((_1.0: std::ptr::Unique<Never>).0: std::ptr::NonNull<Never>) as *const Never (Transmute);
1616
+ _1 = const Box::<Never>(std::ptr::Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global);
17-
+ _2 = const std::ptr::NonNull::<Never> {{ pointer: {0x1 as *const Never} }} as *const Never (Transmute);
17+
+ _2 = const std::boxed::Box::<Never>(std::ptr::Unique::<Never> {{ pointer: std::ptr::NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: std::marker::PhantomData::<Never> }}, std::alloc::Global) as *const Never (Transmute);
1818
unreachable;
1919
}
2020
}

tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@
7474
- StorageLive(_5);
7575
+ nop;
7676
_10 = copy (*_1);
77-
_11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
77+
- _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
78+
+ _11 = copy _10 as *const () (Transmute);
7879
_5 = &raw const (*_11);
7980
- StorageLive(_6);
8081
+ nop;

tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454
- StorageLive(_5);
5555
+ nop;
5656
_10 = copy (*_1);
57-
_11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
57+
- _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
58+
+ _11 = copy _10 as *const () (Transmute);
5859
_5 = &raw const (*_11);
5960
- StorageLive(_6);
6061
+ nop;

tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@
7474
- StorageLive(_5);
7575
+ nop;
7676
_10 = copy (*_1);
77-
_11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
77+
- _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
78+
+ _11 = copy _10 as *const () (Transmute);
7879
_5 = &raw const (*_11);
7980
- StorageLive(_6);
8081
+ nop;

tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454
- StorageLive(_5);
5555
+ nop;
5656
_10 = copy (*_1);
57-
_11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
57+
- _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
58+
+ _11 = copy _10 as *const () (Transmute);
5859
_5 = &raw const (*_11);
5960
- StorageLive(_6);
6061
+ nop;

tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@
6969
StorageLive(_3);
7070
StorageLive(_4);
7171
StorageLive(_5);
72-
StorageLive(_6);
72+
- StorageLive(_6);
73+
+ nop;
7374
StorageLive(_7);
7475
- _7 = copy _1;
7576
- _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb4, unwind unreachable];
@@ -93,11 +94,14 @@
9394
}
9495

9596
bb6: {
96-
_5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
97+
- _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
98+
+ _5 = copy ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
9799
StorageDead(_14);
98100
StorageDead(_10);
99-
StorageDead(_6);
100-
_4 = copy _5 as *mut [u8] (Transmute);
101+
- StorageDead(_6);
102+
- _4 = copy _5 as *mut [u8] (Transmute);
103+
+ nop;
104+
+ _4 = copy _6 as *mut [u8] (Transmute);
101105
StorageDead(_5);
102106
_3 = copy _4 as *mut u8 (PtrToPtr);
103107
StorageDead(_4);

tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@
6969
StorageLive(_3);
7070
StorageLive(_4);
7171
StorageLive(_5);
72-
StorageLive(_6);
72+
- StorageLive(_6);
73+
+ nop;
7374
StorageLive(_7);
7475
- _7 = copy _1;
7576
- _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb4, unwind unreachable];
@@ -93,11 +94,14 @@
9394
}
9495

9596
bb6: {
96-
_5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
97+
- _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
98+
+ _5 = copy ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
9799
StorageDead(_14);
98100
StorageDead(_10);
99-
StorageDead(_6);
100-
_4 = copy _5 as *mut [u8] (Transmute);
101+
- StorageDead(_6);
102+
- _4 = copy _5 as *mut [u8] (Transmute);
103+
+ nop;
104+
+ _4 = copy _6 as *mut [u8] (Transmute);
101105
StorageDead(_5);
102106
_3 = copy _4 as *mut u8 (PtrToPtr);
103107
StorageDead(_4);

0 commit comments

Comments
 (0)