Skip to content

Commit c50b9af

Browse files
committed
Also skip downcasts if the size of the enum matches the transmute target type
1 parent 6a81ae1 commit c50b9af

6 files changed

Lines changed: 30 additions & 12 deletions

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1556,9 +1556,19 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
15561556
&& let Value::Projection(field_value, ProjectionElem::Field(field_idx, ())) =
15571557
self.get(value)
15581558
{
1559-
if let Value::Projection(_downcast_value, ProjectionElem::Downcast(_, _variant_idx)) =
1559+
if let Value::Projection(downcast_value, ProjectionElem::Downcast(_, _variant_idx)) =
15601560
self.get(field_value)
1561+
&& let downcast_ty = self.ty(downcast_value)
1562+
&& let Ok(downcast_layout) = self.ecx.layout_of(downcast_ty)
1563+
&& let Ok(projected_layout) = self.ecx.layout_of(self.ty(value))
1564+
&& downcast_layout.size == projected_layout.size
15611565
{
1566+
from = downcast_ty;
1567+
value = downcast_value;
1568+
was_updated_this_iteration = true;
1569+
if projected_layout.ty == to {
1570+
return Some(value);
1571+
}
15621572
} else if let Some((f_idx, field_ty)) =
15631573
self.value_is_all_in_one_field(self.ty(field_value), FIRST_VARIANT)
15641574
{

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
StorageLive(_4);
2424
_4 = copy _3;
2525
- _0 = move _4 as *const () (Transmute);
26-
+ _0 = copy _3 as *const () (Transmute);
26+
+ _0 = copy _1 as *const () (Transmute);
2727
StorageDead(_4);
2828
- StorageDead(_3);
2929
+ nop;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
StorageLive(_4);
2424
_4 = copy _3;
2525
- _0 = move _4 as *const () (Transmute);
26-
+ _0 = copy _3 as *const () (Transmute);
26+
+ _0 = copy _1 as *const () (Transmute);
2727
StorageDead(_4);
2828
- StorageDead(_3);
2929
+ nop;

tests/mir-opt/const_prop/transmute.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub unsafe fn unreachable_box() -> ! {
8888
pub unsafe fn option_field(x: Option<std::ptr::NonNull<()>>) -> *const () {
8989
// CHECK-LABEL: fn option_field(
9090
// CHECK: _3 = copy ((_1 as Some).0: std::ptr::NonNull<()>)
91-
// CHECK: _0 = copy _3 as *const () (Transmute)
91+
// CHECK: _0 = copy _1 as *const () (Transmute)
9292
if let Some(x) = x { unsafe { transmute(x) } } else { 0 as *const () }
9393
}
9494

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)