Skip to content

Commit e8c2976

Browse files
committed
Turn field accesses into a transmute if followed by a transmute anyway
1 parent 8d50bcc commit e8c2976

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
@@ -1495,6 +1495,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
14951495
}
14961496
}
14971497

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

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