Skip to content

Commit 8097bd7

Browse files
committed
Turn field accesses into a transmute if followed by a transmute anyway
1 parent 92c7010 commit 8097bd7

7 files changed

Lines changed: 35 additions & 6 deletions

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
15271527
}
15281528
}
15291529

1530+
#[instrument(level = "trace", skip(self), ret)]
15301531
fn simplify_cast(
15311532
&mut self,
15321533
initial_kind: &mut CastKind,
@@ -1582,6 +1583,30 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
15821583
}
15831584
}
15841585

1586+
// Field-Access-then-Transmute can just transmute the original value,
1587+
// so long as the bytes of a value from only from a single field.
1588+
if let Transmute = kind
1589+
&& let Value::Projection(field_value, ProjectionElem::Field(field_idx, ())) =
1590+
self.get(value)
1591+
{
1592+
if let Value::Projection(
1593+
_downcast_value,
1594+
ProjectionElem::Downcast(_, _variant_idx),
1595+
) = self.get(field_value)
1596+
{
1597+
} else if let Some((f_idx, field_ty)) =
1598+
self.value_is_all_in_one_field(self.ty(field_value), FIRST_VARIANT)
1599+
{
1600+
assert_eq!(field_idx, f_idx, "{from} -> {field_ty}");
1601+
from = self.ty(field_value);
1602+
value = field_value;
1603+
was_updated_this_iteration = true;
1604+
if field_ty == to {
1605+
return Some(value);
1606+
}
1607+
}
1608+
}
1609+
15851610
// Aggregate-then-Transmute can just transmute the original field value,
15861611
// so long as the bytes of a value from only from a single field.
15871612
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} is !null }}, _marker: PhantomData::<Never> }}, std::alloc::Global);
17-
+ _2 = const std::ptr::NonNull::<Never> {{ pointer: {0x1 as *const Never} is !null }} 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} is !null }}, _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} is !null }}, _marker: PhantomData::<Never> }}, std::alloc::Global);
17-
+ _2 = const std::ptr::NonNull::<Never> {{ pointer: {0x1 as *const Never} is !null }} 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} is !null }}, _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
@@ -73,7 +73,8 @@
7373
StorageDead(_2);
7474
StorageLive(_5);
7575
_10 = copy (*_1);
76-
_11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
76+
- _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
77+
+ _11 = copy _10 as *const () (Transmute);
7778
_5 = &raw const (*_11);
7879
StorageLive(_6);
7980
StorageLive(_7);

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
@@ -53,7 +53,8 @@
5353
StorageDead(_2);
5454
StorageLive(_5);
5555
_10 = copy (*_1);
56-
_11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
56+
- _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
57+
+ _11 = copy _10 as *const () (Transmute);
5758
_5 = &raw const (*_11);
5859
StorageLive(_6);
5960
StorageLive(_7);

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
@@ -73,7 +73,8 @@
7373
StorageDead(_2);
7474
StorageLive(_5);
7575
_10 = copy (*_1);
76-
_11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
76+
- _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
77+
+ _11 = copy _10 as *const () (Transmute);
7778
_5 = &raw const (*_11);
7879
StorageLive(_6);
7980
StorageLive(_7);

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
@@ -53,7 +53,8 @@
5353
StorageDead(_2);
5454
StorageLive(_5);
5555
_10 = copy (*_1);
56-
_11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
56+
- _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
57+
+ _11 = copy _10 as *const () (Transmute);
5758
_5 = &raw const (*_11);
5859
StorageLive(_6);
5960
StorageLive(_7);

0 commit comments

Comments
 (0)