Skip to content

Commit abca6ef

Browse files
committed
Turn field accesses into a transmute if followed by a transmute anyway
1 parent 241cd7e commit abca6ef

7 files changed

Lines changed: 33 additions & 6 deletions

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 23 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,28 @@ 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(_downcast_value, ProjectionElem::Downcast(_, _variant_idx)) =
1560+
self.get(field_value)
1561+
{
1562+
} else if let Some((f_idx, field_ty)) =
1563+
self.value_is_all_in_one_field(self.ty(field_value), FIRST_VARIANT)
1564+
{
1565+
assert_eq!(field_idx, f_idx, "{from} -> {field_ty}");
1566+
from = self.ty(field_value);
1567+
value = field_value;
1568+
was_updated_this_iteration = true;
1569+
if field_ty == to {
1570+
return Some(value);
1571+
}
1572+
}
1573+
}
1574+
15521575
// Aggregate-then-Transmute can just transmute the original field value,
15531576
// so long as the bytes of a value from only from a single field.
15541577
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;

0 commit comments

Comments
 (0)