Skip to content

Commit cf83de7

Browse files
committed
Also skip downcasts if the size of the enum matches the transmute target type
1 parent 3b82712 commit cf83de7

13 files changed

Lines changed: 129 additions & 98 deletions

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1590,10 +1590,22 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
15901590
self.get(value)
15911591
{
15921592
if let Value::Projection(
1593-
_downcast_value,
1593+
downcast_value,
15941594
ProjectionElem::Downcast(_, _variant_idx),
15951595
) = self.get(field_value)
15961596
{
1597+
let downcast_ty = self.ty(downcast_value);
1598+
if let Ok(downcast_layout) = self.ecx.layout_of(downcast_ty)
1599+
&& let Ok(projected_layout) = self.ecx.layout_of(from)
1600+
&& downcast_layout.size == projected_layout.size
1601+
{
1602+
from = downcast_ty;
1603+
value = downcast_value;
1604+
was_updated_this_iteration = true;
1605+
if projected_layout.ty == to {
1606+
return Some(value);
1607+
}
1608+
}
15971609
} else if let Some((f_idx, field_ty)) =
15981610
self.value_is_all_in_one_field(self.ty(field_value), FIRST_VARIANT)
15991611
{

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@
1717
}
1818

1919
bb1: {
20-
- StorageLive(_3);
21-
+ nop;
20+
StorageLive(_3);
2221
_3 = copy ((_1 as Some).0: std::ptr::NonNull<()>);
2322
StorageLive(_4);
2423
_4 = copy _3;
2524
- _0 = move _4 as *const () (Transmute);
26-
+ _0 = copy _3 as *const () (Transmute);
25+
+ _0 = copy _1 as *const () (Transmute);
2726
StorageDead(_4);
28-
- StorageDead(_3);
29-
+ nop;
27+
StorageDead(_3);
3028
goto -> bb3;
3129
}
3230

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@
1717
}
1818

1919
bb1: {
20-
- StorageLive(_3);
21-
+ nop;
20+
StorageLive(_3);
2221
_3 = copy ((_1 as Some).0: std::ptr::NonNull<()>);
2322
StorageLive(_4);
2423
_4 = copy _3;
2524
- _0 = move _4 as *const () (Transmute);
26-
+ _0 = copy _3 as *const () (Transmute);
25+
+ _0 = copy _1 as *const () (Transmute);
2726
StorageDead(_4);
28-
- StorageDead(_3);
29-
+ nop;
27+
StorageDead(_3);
3028
goto -> bb3;
3129
}
3230

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
@@ -68,7 +68,8 @@
6868
StorageLive(_3);
6969
StorageLive(_4);
7070
StorageLive(_5);
71-
StorageLive(_6);
71+
- StorageLive(_6);
72+
+ nop;
7273
StorageLive(_7);
7374
- _7 = copy _1;
7475
- _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb4, unwind unreachable];
@@ -92,10 +93,13 @@
9293
}
9394

9495
bb6: {
95-
_5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
96+
- _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
97+
+ _5 = copy ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
9698
StorageDead(_10);
97-
StorageDead(_6);
98-
_4 = copy _5 as *mut [u8] (Transmute);
99+
- StorageDead(_6);
100+
- _4 = copy _5 as *mut [u8] (Transmute);
101+
+ nop;
102+
+ _4 = copy _6 as *mut [u8] (Transmute);
99103
StorageDead(_5);
100104
_3 = copy _4 as *mut u8 (PtrToPtr);
101105
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
@@ -68,7 +68,8 @@
6868
StorageLive(_3);
6969
StorageLive(_4);
7070
StorageLive(_5);
71-
StorageLive(_6);
71+
- StorageLive(_6);
72+
+ nop;
7273
StorageLive(_7);
7374
- _7 = copy _1;
7475
- _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb4, unwind unreachable];
@@ -92,10 +93,13 @@
9293
}
9394

9495
bb6: {
95-
_5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
96+
- _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
97+
+ _5 = copy ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
9698
StorageDead(_10);
97-
StorageDead(_6);
98-
_4 = copy _5 as *mut [u8] (Transmute);
99+
- StorageDead(_6);
100+
- _4 = copy _5 as *mut [u8] (Transmute);
101+
+ nop;
102+
+ _4 = copy _6 as *mut [u8] (Transmute);
99103
StorageDead(_5);
100104
_3 = copy _4 as *mut u8 (PtrToPtr);
101105
StorageDead(_4);

tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -180,23 +180,20 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
180180

181181
bb4: {
182182
StorageLive(_32);
183-
StorageLive(_29);
184183
StorageLive(_30);
185184
StorageLive(_27);
186-
StorageLive(_13);
187-
StorageLive(_14);
188-
StorageLive(_20);
189185
StorageLive(_24);
190-
StorageLive(_15);
191-
StorageLive(_26);
192186
StorageLive(_16);
187+
StorageLive(_13);
193188
_13 = copy _8;
189+
StorageLive(_14);
194190
_14 = copy _11;
195191
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb5, otherwise: bb8];
196192
}
197193

198194
bb5: {
199195
StorageLive(_18);
196+
StorageLive(_15);
200197
_15 = copy _14 as std::ptr::NonNull<T> (Transmute);
201198
_16 = copy _13 as *mut T (Transmute);
202199
StorageLive(_17);
@@ -207,6 +204,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
207204
}
208205

209206
bb6: {
207+
StorageDead(_15);
210208
StorageDead(_18);
211209
StorageLive(_19);
212210
_19 = Offset(copy _16, const 1_usize);
@@ -216,27 +214,27 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
216214
}
217215

218216
bb7: {
217+
StorageDead(_15);
219218
StorageDead(_18);
220219
goto -> bb10;
221220
}
222221

223222
bb8: {
223+
StorageLive(_20);
224224
_20 = copy _14 as usize (Transmute);
225225
switchInt(copy _20) -> [0: bb9, otherwise: bb12];
226226
}
227227

228228
bb9: {
229+
StorageDead(_20);
229230
goto -> bb10;
230231
}
231232

232233
bb10: {
233-
StorageDead(_16);
234-
StorageDead(_26);
235-
StorageDead(_15);
236-
StorageDead(_24);
237-
StorageDead(_20);
238234
StorageDead(_14);
239235
StorageDead(_13);
236+
StorageDead(_16);
237+
StorageDead(_24);
240238
StorageDead(_27);
241239
StorageLive(_21);
242240
StorageLive(_23);
@@ -246,7 +244,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
246244
StorageDead(_23);
247245
StorageDead(_21);
248246
StorageDead(_30);
249-
StorageDead(_29);
250247
StorageDead(_32);
251248
StorageDead(_12);
252249
drop(_2) -> [return: bb11, unwind unreachable];
@@ -259,24 +256,25 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
259256
bb12: {
260257
_24 = SubUnchecked(copy _20, const 1_usize);
261258
_11 = copy _24 as *const T (Transmute);
259+
StorageDead(_20);
262260
goto -> bb13;
263261
}
264262

265263
bb13: {
264+
StorageLive(_26);
266265
StorageLive(_25);
267266
_25 = copy _13 as *const T (Transmute);
268267
_26 = &(*_25);
269268
StorageDead(_25);
270269
_27 = Option::<&T>::Some(copy _26);
271-
StorageDead(_16);
272270
StorageDead(_26);
273-
StorageDead(_15);
274-
StorageDead(_24);
275-
StorageDead(_20);
276271
StorageDead(_14);
277272
StorageDead(_13);
273+
StorageDead(_16);
274+
StorageDead(_24);
278275
_28 = copy ((_27 as Some).0: &T);
279276
StorageDead(_27);
277+
StorageLive(_29);
280278
_29 = copy _12;
281279
_30 = AddWithOverflow(copy _12, const 1_usize);
282280
assert(!move (_30.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _12, const 1_usize) -> [success: bb14, unwind unreachable];
@@ -288,9 +286,11 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
288286
_31 = (copy _29, copy _28);
289287
_32 = Option::<(usize, &T)>::Some(move _31);
290288
StorageDead(_31);
291-
StorageDead(_30);
292289
StorageDead(_29);
290+
StorageDead(_30);
291+
StorageLive(_33);
293292
_33 = copy (((_32 as Some).0: (usize, &T)).0: usize);
293+
StorageLive(_34);
294294
_34 = copy (((_32 as Some).0: (usize, &T)).1: &T);
295295
StorageLive(_35);
296296
_35 = &_2;
@@ -302,6 +302,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
302302
bb15: {
303303
StorageDead(_36);
304304
StorageDead(_35);
305+
StorageDead(_34);
306+
StorageDead(_33);
305307
StorageDead(_32);
306308
goto -> bb4;
307309
}

tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -142,20 +142,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
142142

143143
bb4: {
144144
StorageLive(_23);
145-
StorageLive(_12);
146-
StorageLive(_13);
147-
StorageLive(_19);
148145
StorageLive(_20);
149-
StorageLive(_14);
150-
StorageLive(_22);
151146
StorageLive(_15);
147+
StorageLive(_12);
152148
_12 = copy _8;
149+
StorageLive(_13);
153150
_13 = copy _11;
154151
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb5, otherwise: bb8];
155152
}
156153

157154
bb5: {
158155
StorageLive(_17);
156+
StorageLive(_14);
159157
_14 = copy _13 as std::ptr::NonNull<T> (Transmute);
160158
_15 = copy _12 as *mut T (Transmute);
161159
StorageLive(_16);
@@ -166,6 +164,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
166164
}
167165

168166
bb6: {
167+
StorageDead(_14);
169168
StorageDead(_17);
170169
StorageLive(_18);
171170
_18 = Offset(copy _15, const 1_usize);
@@ -175,27 +174,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
175174
}
176175

177176
bb7: {
177+
StorageDead(_14);
178178
StorageDead(_17);
179179
goto -> bb10;
180180
}
181181

182182
bb8: {
183+
StorageLive(_19);
183184
_19 = copy _13 as usize (Transmute);
184185
switchInt(copy _19) -> [0: bb9, otherwise: bb12];
185186
}
186187

187188
bb9: {
189+
StorageDead(_19);
188190
goto -> bb10;
189191
}
190192

191193
bb10: {
192-
StorageDead(_15);
193-
StorageDead(_22);
194-
StorageDead(_14);
195-
StorageDead(_20);
196-
StorageDead(_19);
197194
StorageDead(_13);
198195
StorageDead(_12);
196+
StorageDead(_15);
197+
StorageDead(_20);
199198
StorageDead(_23);
200199
drop(_2) -> [return: bb11, unwind unreachable];
201200
}
@@ -207,22 +206,23 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
207206
bb12: {
208207
_20 = SubUnchecked(copy _19, const 1_usize);
209208
_11 = copy _20 as *const T (Transmute);
209+
StorageDead(_19);
210210
goto -> bb13;
211211
}
212212

213213
bb13: {
214+
StorageLive(_22);
214215
StorageLive(_21);
215216
_21 = copy _12 as *const T (Transmute);
216217
_22 = &(*_21);
217218
StorageDead(_21);
218219
_23 = Option::<&T>::Some(copy _22);
219-
StorageDead(_15);
220220
StorageDead(_22);
221-
StorageDead(_14);
222-
StorageDead(_20);
223-
StorageDead(_19);
224221
StorageDead(_13);
225222
StorageDead(_12);
223+
StorageDead(_15);
224+
StorageDead(_20);
225+
StorageLive(_24);
226226
_24 = copy ((_23 as Some).0: &T);
227227
StorageLive(_25);
228228
_25 = &_2;
@@ -234,6 +234,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
234234
bb14: {
235235
StorageDead(_26);
236236
StorageDead(_25);
237+
StorageDead(_24);
237238
StorageDead(_23);
238239
goto -> bb4;
239240
}

tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,15 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
7272
}
7373

7474
bb4: {
75+
StorageLive(_7);
7576
_7 = copy _4;
7677
_4 = AddUnchecked(copy _7, const 1_usize);
7778
_8 = Option::<usize>::Some(copy _7);
79+
StorageDead(_7);
7880
StorageDead(_6);
81+
StorageLive(_9);
7982
_9 = copy ((_8 as Some).0: usize);
83+
StorageLive(_11);
8084
_10 = Lt(copy _9, copy _3);
8185
assert(move _10, "index out of bounds: the length is {} but the index is {}", copy _3, copy _9) -> [success: bb5, unwind unreachable];
8286
}
@@ -93,6 +97,8 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
9397
bb6: {
9498
StorageDead(_13);
9599
StorageDead(_12);
100+
StorageDead(_11);
101+
StorageDead(_9);
96102
StorageDead(_8);
97103
goto -> bb1;
98104
}

0 commit comments

Comments
 (0)