Skip to content

Commit e60fbaf

Browse files
committed
Auto merge of #105229 - saethlin:zst-writes-to-unions, r=oli-obk
Re-enable removal of ZST writes to unions This was previously disabled because Miri was lazily allocating unsized locals. But we aren't doing that anymore since #98831, so we can have this optimization back.
2 parents b685242 + 74a270a commit e60fbaf

6 files changed

+44
-60
lines changed

compiler/rustc_mir_transform/src/remove_zsts.rs

+1-26
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//! Removes assignments to ZST places.
22
33
use crate::MirPass;
4-
use rustc_middle::mir::tcx::PlaceTy;
5-
use rustc_middle::mir::{Body, LocalDecls, Place, StatementKind};
4+
use rustc_middle::mir::{Body, StatementKind};
65
use rustc_middle::ty::{self, Ty, TyCtxt};
76

87
pub struct RemoveZsts;
@@ -35,9 +34,6 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts {
3534
if !layout.is_zst() {
3635
continue;
3736
}
38-
if involves_a_union(place, local_decls, tcx) {
39-
continue;
40-
}
4137
if tcx.consider_optimizing(|| {
4238
format!(
4339
"RemoveZsts - Place: {:?} SourceInfo: {:?}",
@@ -63,24 +59,3 @@ fn maybe_zst(ty: Ty<'_>) -> bool {
6359
_ => false,
6460
}
6561
}
66-
67-
/// Miri lazily allocates memory for locals on assignment,
68-
/// so we must preserve writes to unions and union fields,
69-
/// or it will ICE on reads of those fields.
70-
fn involves_a_union<'tcx>(
71-
place: Place<'tcx>,
72-
local_decls: &LocalDecls<'tcx>,
73-
tcx: TyCtxt<'tcx>,
74-
) -> bool {
75-
let mut place_ty = PlaceTy::from_ty(local_decls[place.local].ty);
76-
if place_ty.ty.is_union() {
77-
return true;
78-
}
79-
for elem in place.projection {
80-
place_ty = place_ty.projection_ty(tcx, elem);
81-
if place_ty.ty.is_union() {
82-
return true;
83-
}
84-
}
85-
return false;
86-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// MIR for `get_union` after PreCodegen
2+
3+
fn get_union() -> Foo {
4+
let mut _0: Foo; // return place in scope 0 at $DIR/remove_zsts.rs:+0:19: +0:22
5+
6+
bb0: {
7+
Deinit(_0); // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18
8+
return; // scope 0 at $DIR/remove_zsts.rs:+2:2: +2:2
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
- // MIR for `get_union` before RemoveZsts
2+
+ // MIR for `get_union` after RemoveZsts
3+
4+
fn get_union() -> Foo {
5+
let mut _0: Foo; // return place in scope 0 at $DIR/remove_zsts.rs:+0:19: +0:22
6+
let mut _1: (); // in scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16
7+
8+
bb0: {
9+
StorageLive(_1); // scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16
10+
- Deinit(_1); // scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16
11+
+ nop; // scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16
12+
Deinit(_0); // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18
13+
- (_0.0: ()) = move _1; // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18
14+
+ nop; // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18
15+
StorageDead(_1); // scope 0 at $DIR/remove_zsts.rs:+1:17: +1:18
16+
return; // scope 0 at $DIR/remove_zsts.rs:+2:2: +2:2
17+
}
18+
}
19+

src/test/mir-opt/remove_zsts.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
union Foo {
2+
x: (),
3+
y: u64,
4+
}
5+
6+
// EMIT_MIR remove_zsts.get_union.RemoveZsts.diff
7+
// EMIT_MIR remove_zsts.get_union.PreCodegen.after.mir
8+
fn get_union() -> Foo {
9+
Foo { x: () }
10+
}
11+
12+
fn main() {
13+
get_union();
14+
}

src/test/mir-opt/remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir

-15
This file was deleted.

src/test/mir-opt/remove_zsts_dont_touch_unions.rs

-19
This file was deleted.

0 commit comments

Comments
 (0)