Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b6b8361

Browse files
committedJan 9, 2025
Auto merge of #133324 - scottmcm:gvn-aggregate-transmute, r=cjgillot
[mir-opt] GVN some more transmute cases We already did `Transmute`-then-`PtrToPtr`; this adds the nearly-identical `PtrToPtr`-then-`Transmute`. It also adds `transmute(Foo(x))` → `transmute(x)`, when `Foo` is a single-field transparent type. That's useful for things like `NonNull { pointer: p }.as_ptr()`. It also detects when a `Transmute` is just an identity-for-the-value `PtrCast` between different raw pointer types, to help such things fold with other GVN passes. Found these as I was looking at <https://github.com/rust-lang/compiler-team/issues/807>-related changes. This also removes the questionably-useful "turn a transmute into a field projection" part of instsimplify (which I added ages ago without an obvious need for it) since that would just put back the field projections that MCP807 is trying to ban. r? mir-opt
2 parents 65d7296 + b421a56 commit b6b8361

File tree

32 files changed

+1842
-681
lines changed

32 files changed

+1842
-681
lines changed
 

‎compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 139 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,57 +1366,108 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
13661366
return self.new_opaque();
13671367
}
13681368

1369-
let mut was_updated = false;
1370-
1371-
// If that cast just casts away the metadata again,
1372-
if let PtrToPtr = kind
1373-
&& let Value::Aggregate(AggregateTy::RawPtr { data_pointer_ty, .. }, _, fields) =
1374-
self.get(value)
1375-
&& let ty::RawPtr(to_pointee, _) = to.kind()
1376-
&& to_pointee.is_sized(self.tcx, self.typing_env())
1377-
{
1378-
from = *data_pointer_ty;
1379-
value = fields[0];
1380-
was_updated = true;
1381-
if *data_pointer_ty == to {
1382-
return Some(fields[0]);
1369+
let mut was_ever_updated = false;
1370+
loop {
1371+
let mut was_updated_this_iteration = false;
1372+
1373+
// Transmuting between raw pointers is just a pointer cast so long as
1374+
// they have the same metadata type (like `*const i32` <=> `*mut u64`
1375+
// or `*mut [i32]` <=> `*const [u64]`), including the common special
1376+
// case of `*const T` <=> `*mut T`.
1377+
if let Transmute = kind
1378+
&& from.is_unsafe_ptr()
1379+
&& to.is_unsafe_ptr()
1380+
&& self.pointers_have_same_metadata(from, to)
1381+
{
1382+
*kind = PtrToPtr;
1383+
was_updated_this_iteration = true;
13831384
}
1384-
}
13851385

1386-
// PtrToPtr-then-PtrToPtr can skip the intermediate step
1387-
if let PtrToPtr = kind
1388-
&& let Value::Cast { kind: inner_kind, value: inner_value, from: inner_from, to: _ } =
1389-
*self.get(value)
1390-
&& let PtrToPtr = inner_kind
1391-
{
1392-
from = inner_from;
1393-
value = inner_value;
1394-
was_updated = true;
1395-
if inner_from == to {
1396-
return Some(inner_value);
1386+
// If a cast just casts away the metadata again, then we can get it by
1387+
// casting the original thin pointer passed to `from_raw_parts`
1388+
if let PtrToPtr = kind
1389+
&& let Value::Aggregate(AggregateTy::RawPtr { data_pointer_ty, .. }, _, fields) =
1390+
self.get(value)
1391+
&& let ty::RawPtr(to_pointee, _) = to.kind()
1392+
&& to_pointee.is_sized(self.tcx, self.typing_env())
1393+
{
1394+
from = *data_pointer_ty;
1395+
value = fields[0];
1396+
was_updated_this_iteration = true;
1397+
if *data_pointer_ty == to {
1398+
return Some(fields[0]);
1399+
}
13971400
}
1398-
}
13991401

1400-
// PtrToPtr-then-Transmute can just transmute the original, so long as the
1401-
// PtrToPtr didn't change metadata (and thus the size of the pointer)
1402-
if let Transmute = kind
1403-
&& let Value::Cast {
1404-
kind: PtrToPtr,
1402+
// Aggregate-then-Transmute can just transmute the original field value,
1403+
// so long as the bytes of a value from only from a single field.
1404+
if let Transmute = kind
1405+
&& let Value::Aggregate(_aggregate_ty, variant_idx, field_values) = self.get(value)
1406+
&& let Some((field_idx, field_ty)) =
1407+
self.value_is_all_in_one_field(from, *variant_idx)
1408+
{
1409+
from = field_ty;
1410+
value = field_values[field_idx.as_usize()];
1411+
was_updated_this_iteration = true;
1412+
if field_ty == to {
1413+
return Some(value);
1414+
}
1415+
}
1416+
1417+
// Various cast-then-cast cases can be simplified.
1418+
if let Value::Cast {
1419+
kind: inner_kind,
14051420
value: inner_value,
14061421
from: inner_from,
14071422
to: inner_to,
14081423
} = *self.get(value)
1409-
&& self.pointers_have_same_metadata(inner_from, inner_to)
1410-
{
1411-
from = inner_from;
1412-
value = inner_value;
1413-
was_updated = true;
1414-
if inner_from == to {
1415-
return Some(inner_value);
1424+
{
1425+
let new_kind = match (inner_kind, *kind) {
1426+
// Even if there's a narrowing cast in here that's fine, because
1427+
// things like `*mut [i32] -> *mut i32 -> *const i32` and
1428+
// `*mut [i32] -> *const [i32] -> *const i32` can skip the middle in MIR.
1429+
(PtrToPtr, PtrToPtr) => Some(PtrToPtr),
1430+
// PtrToPtr-then-Transmute is fine so long as the pointer cast is identity:
1431+
// `*const T -> *mut T -> NonNull<T>` is fine, but we need to check for narrowing
1432+
// to skip things like `*const [i32] -> *const i32 -> NonNull<T>`.
1433+
(PtrToPtr, Transmute)
1434+
if self.pointers_have_same_metadata(inner_from, inner_to) =>
1435+
{
1436+
Some(Transmute)
1437+
}
1438+
// Similarly, for Transmute-then-PtrToPtr. Note that we need to check different
1439+
// variables for their metadata, and thus this can't merge with the previous arm.
1440+
(Transmute, PtrToPtr) if self.pointers_have_same_metadata(from, to) => {
1441+
Some(Transmute)
1442+
}
1443+
// If would be legal to always do this, but we don't want to hide information
1444+
// from the backend that it'd otherwise be able to use for optimizations.
1445+
(Transmute, Transmute)
1446+
if !self.type_may_have_niche_of_interest_to_backend(inner_to) =>
1447+
{
1448+
Some(Transmute)
1449+
}
1450+
_ => None,
1451+
};
1452+
if let Some(new_kind) = new_kind {
1453+
*kind = new_kind;
1454+
from = inner_from;
1455+
value = inner_value;
1456+
was_updated_this_iteration = true;
1457+
if inner_from == to {
1458+
return Some(inner_value);
1459+
}
1460+
}
1461+
}
1462+
1463+
if was_updated_this_iteration {
1464+
was_ever_updated = true;
1465+
} else {
1466+
break;
14161467
}
14171468
}
14181469

1419-
if was_updated && let Some(op) = self.try_as_operand(value, location) {
1470+
if was_ever_updated && let Some(op) = self.try_as_operand(value, location) {
14201471
*operand = op;
14211472
}
14221473

@@ -1438,6 +1489,54 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
14381489
false
14391490
}
14401491
}
1492+
1493+
/// Returns `false` if we know for sure that this type has no interesting niche,
1494+
/// and thus we can skip transmuting through it without worrying.
1495+
///
1496+
/// The backend will emit `assume`s when transmuting between types with niches,
1497+
/// so we want to preserve `i32 -> char -> u32` so that that data is around,
1498+
/// but it's fine to skip whole-range-is-value steps like `A -> u32 -> B`.
1499+
fn type_may_have_niche_of_interest_to_backend(&self, ty: Ty<'tcx>) -> bool {
1500+
let Ok(layout) = self.ecx.layout_of(ty) else {
1501+
// If it's too generic or something, then assume it might be interesting later.
1502+
return true;
1503+
};
1504+
1505+
match layout.backend_repr {
1506+
BackendRepr::Uninhabited => true,
1507+
BackendRepr::Scalar(a) => !a.is_always_valid(&self.ecx),
1508+
BackendRepr::ScalarPair(a, b) => {
1509+
!a.is_always_valid(&self.ecx) || !b.is_always_valid(&self.ecx)
1510+
}
1511+
BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => false,
1512+
}
1513+
}
1514+
1515+
fn value_is_all_in_one_field(
1516+
&self,
1517+
ty: Ty<'tcx>,
1518+
variant: VariantIdx,
1519+
) -> Option<(FieldIdx, Ty<'tcx>)> {
1520+
if let Ok(layout) = self.ecx.layout_of(ty)
1521+
&& let abi::Variants::Single { index } = layout.variants
1522+
&& index == variant
1523+
&& let Some((field_idx, field_layout)) = layout.non_1zst_field(&self.ecx)
1524+
&& layout.size == field_layout.size
1525+
{
1526+
// We needed to check the variant to avoid trying to read the tag
1527+
// field from an enum where no fields have variants, since that tag
1528+
// field isn't in the `Aggregate` from which we're getting values.
1529+
Some((FieldIdx::from_usize(field_idx), field_layout.ty))
1530+
} else if let ty::Adt(adt, args) = ty.kind()
1531+
&& adt.is_struct()
1532+
&& adt.repr().transparent()
1533+
&& let [single_field] = adt.non_enum_variant().fields.raw.as_slice()
1534+
{
1535+
Some((FieldIdx::ZERO, single_field.ty(self.tcx, args)))
1536+
} else {
1537+
None
1538+
}
1539+
}
14411540
}
14421541

14431542
fn op_to_prop_const<'tcx>(

‎compiler/rustc_mir_transform/src/instsimplify.rs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -173,29 +173,6 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
173173
*kind = CastKind::IntToInt;
174174
return;
175175
}
176-
177-
// Transmuting a transparent struct/union to a field's type is a projection
178-
if let ty::Adt(adt_def, args) = operand_ty.kind()
179-
&& adt_def.repr().transparent()
180-
&& (adt_def.is_struct() || adt_def.is_union())
181-
&& let Some(place) = operand.place()
182-
{
183-
let variant = adt_def.non_enum_variant();
184-
for (i, field) in variant.fields.iter_enumerated() {
185-
let field_ty = field.ty(self.tcx, args);
186-
if field_ty == *cast_ty {
187-
let place = place
188-
.project_deeper(&[ProjectionElem::Field(i, *cast_ty)], self.tcx);
189-
let operand = if operand.is_move() {
190-
Operand::Move(place)
191-
} else {
192-
Operand::Copy(place)
193-
};
194-
*rvalue = Rvalue::Use(operand);
195-
return;
196-
}
197-
}
198-
}
199176
}
200177
}
201178
}

‎tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
StorageLive(_7);
5252
_7 = const 1_usize;
5353
_6 = const {0x1 as *mut [bool; 0]};
54-
StorageDead(_7);
5554
StorageLive(_11);
5655
StorageLive(_8);
5756
_8 = UbChecks();
@@ -79,6 +78,7 @@
7978
_11 = const {0x1 as *const [bool; 0]};
8079
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
8180
StorageDead(_11);
81+
StorageDead(_7);
8282
StorageDead(_6);
8383
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
8484
StorageDead(_5);

‎tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
StorageLive(_7);
5252
_7 = const 1_usize;
5353
_6 = const {0x1 as *mut [bool; 0]};
54-
StorageDead(_7);
5554
StorageLive(_11);
5655
StorageLive(_8);
5756
_8 = UbChecks();
@@ -83,6 +82,7 @@
8382
_11 = const {0x1 as *const [bool; 0]};
8483
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
8584
StorageDead(_11);
85+
StorageDead(_7);
8686
StorageDead(_6);
8787
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
8888
StorageDead(_5);

‎tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
StorageLive(_7);
5252
_7 = const 1_usize;
5353
_6 = const {0x1 as *mut [bool; 0]};
54-
StorageDead(_7);
5554
StorageLive(_11);
5655
StorageLive(_8);
5756
_8 = UbChecks();
@@ -79,6 +78,7 @@
7978
_11 = const {0x1 as *const [bool; 0]};
8079
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
8180
StorageDead(_11);
81+
StorageDead(_7);
8282
StorageDead(_6);
8383
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
8484
StorageDead(_5);

‎tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
StorageLive(_7);
5252
_7 = const 1_usize;
5353
_6 = const {0x1 as *mut [bool; 0]};
54-
StorageDead(_7);
5554
StorageLive(_11);
5655
StorageLive(_8);
5756
_8 = UbChecks();
@@ -83,6 +82,7 @@
8382
_11 = const {0x1 as *const [bool; 0]};
8483
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
8584
StorageDead(_11);
85+
StorageDead(_7);
8686
StorageDead(_6);
8787
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
8888
StorageDead(_5);

‎tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
- _6 = copy _7 as *mut [bool; 0] (Transmute);
5454
+ _7 = const 1_usize;
5555
+ _6 = const {0x1 as *mut [bool; 0]};
56-
StorageDead(_7);
5756
StorageLive(_11);
5857
StorageLive(_8);
5958
_8 = UbChecks();
@@ -67,7 +66,7 @@
6766

6867
bb2: {
6968
StorageLive(_10);
70-
- _10 = copy _6 as *mut () (PtrToPtr);
69+
- _10 = copy _7 as *mut () (Transmute);
7170
- _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
7271
+ _10 = const {0x1 as *mut ()};
7372
+ _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable];
@@ -80,11 +79,12 @@
8079

8180
bb4: {
8281
StorageDead(_8);
83-
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
82+
- _11 = copy _7 as *const [bool; 0] (Transmute);
8483
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
8584
+ _11 = const {0x1 as *const [bool; 0]};
8685
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
8786
StorageDead(_11);
87+
StorageDead(_7);
8888
StorageDead(_6);
8989
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
9090
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};

‎tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
- _6 = copy _7 as *mut [bool; 0] (Transmute);
5454
+ _7 = const 1_usize;
5555
+ _6 = const {0x1 as *mut [bool; 0]};
56-
StorageDead(_7);
5756
StorageLive(_11);
5857
StorageLive(_8);
5958
_8 = UbChecks();
@@ -71,7 +70,7 @@
7170

7271
bb3: {
7372
StorageLive(_10);
74-
- _10 = copy _6 as *mut () (PtrToPtr);
73+
- _10 = copy _7 as *mut () (Transmute);
7574
- _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
7675
+ _10 = const {0x1 as *mut ()};
7776
+ _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable];
@@ -84,11 +83,12 @@
8483

8584
bb5: {
8685
StorageDead(_8);
87-
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
86+
- _11 = copy _7 as *const [bool; 0] (Transmute);
8887
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
8988
+ _11 = const {0x1 as *const [bool; 0]};
9089
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
9190
StorageDead(_11);
91+
StorageDead(_7);
9292
StorageDead(_6);
9393
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
9494
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};

‎tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
- _6 = copy _7 as *mut [bool; 0] (Transmute);
5454
+ _7 = const 1_usize;
5555
+ _6 = const {0x1 as *mut [bool; 0]};
56-
StorageDead(_7);
5756
StorageLive(_11);
5857
StorageLive(_8);
5958
_8 = UbChecks();
@@ -67,7 +66,7 @@
6766

6867
bb2: {
6968
StorageLive(_10);
70-
- _10 = copy _6 as *mut () (PtrToPtr);
69+
- _10 = copy _7 as *mut () (Transmute);
7170
- _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
7271
+ _10 = const {0x1 as *mut ()};
7372
+ _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable];
@@ -80,11 +79,12 @@
8079

8180
bb4: {
8281
StorageDead(_8);
83-
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
82+
- _11 = copy _7 as *const [bool; 0] (Transmute);
8483
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
8584
+ _11 = const {0x1 as *const [bool; 0]};
8685
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
8786
StorageDead(_11);
87+
StorageDead(_7);
8888
StorageDead(_6);
8989
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
9090
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};

‎tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
- _6 = copy _7 as *mut [bool; 0] (Transmute);
5454
+ _7 = const 1_usize;
5555
+ _6 = const {0x1 as *mut [bool; 0]};
56-
StorageDead(_7);
5756
StorageLive(_11);
5857
StorageLive(_8);
5958
_8 = UbChecks();
@@ -71,7 +70,7 @@
7170

7271
bb3: {
7372
StorageLive(_10);
74-
- _10 = copy _6 as *mut () (PtrToPtr);
73+
- _10 = copy _7 as *mut () (Transmute);
7574
- _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
7675
+ _10 = const {0x1 as *mut ()};
7776
+ _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable];
@@ -84,11 +83,12 @@
8483

8584
bb5: {
8685
StorageDead(_8);
87-
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
86+
- _11 = copy _7 as *const [bool; 0] (Transmute);
8887
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
8988
+ _11 = const {0x1 as *const [bool; 0]};
9089
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
9190
StorageDead(_11);
91+
StorageDead(_7);
9292
StorageDead(_6);
9393
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
9494
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
- // MIR for `aggregate_struct_then_transmute` before GVN
2+
+ // MIR for `aggregate_struct_then_transmute` after GVN
3+
4+
fn aggregate_struct_then_transmute(_1: u16, _2: *const u8) -> () {
5+
debug id => _1;
6+
debug thin => _2;
7+
let mut _0: ();
8+
let _3: MyId;
9+
let mut _4: u16;
10+
let _5: ();
11+
let mut _6: u16;
12+
let mut _7: MyId;
13+
let mut _9: u16;
14+
let mut _10: std::marker::PhantomData<std::string::String>;
15+
let _11: ();
16+
let mut _12: u16;
17+
let mut _13: TypedId<std::string::String>;
18+
let mut _15: u16;
19+
let _16: ();
20+
let mut _17: u16;
21+
let mut _18: std::result::Result<Never, u16>;
22+
let mut _20: u16;
23+
let _21: ();
24+
let mut _22: u32;
25+
let mut _23: std::option::Option<u16>;
26+
let mut _25: u16;
27+
let _26: ();
28+
let mut _27: i16;
29+
let mut _28: MyId;
30+
let mut _30: u16;
31+
let mut _31: u16;
32+
let _32: ();
33+
let mut _33: u32;
34+
let mut _34: aggregate_struct_then_transmute::Pair;
35+
let mut _36: u16;
36+
let mut _37: u16;
37+
let _38: ();
38+
let mut _39: u16;
39+
let mut _40: aggregate_struct_then_transmute::Pair;
40+
let mut _42: u16;
41+
let _43: ();
42+
let mut _44: u16;
43+
let mut _45: (u16,);
44+
let mut _47: u16;
45+
let _48: ();
46+
let mut _49: u16;
47+
let mut _50: [u16; 1];
48+
let mut _52: *const u8;
49+
let mut _53: ();
50+
let _54: ();
51+
let mut _55: *const u8;
52+
let mut _56: *const i32;
53+
scope 1 {
54+
debug a => _3;
55+
let _8: TypedId<std::string::String>;
56+
scope 2 {
57+
debug b => _8;
58+
let _14: std::result::Result<Never, u16>;
59+
scope 3 {
60+
debug c => _14;
61+
let _19: std::option::Option<u16>;
62+
scope 4 {
63+
debug d => _19;
64+
let _24: MyId;
65+
scope 5 {
66+
debug e => _24;
67+
let _29: aggregate_struct_then_transmute::Pair;
68+
scope 6 {
69+
debug f => _29;
70+
let _35: aggregate_struct_then_transmute::Pair;
71+
scope 7 {
72+
debug g => _35;
73+
let _41: (u16,);
74+
scope 8 {
75+
debug h => _41;
76+
let _46: [u16; 1];
77+
scope 9 {
78+
debug i => _46;
79+
let _51: *const i32;
80+
scope 10 {
81+
debug j => _51;
82+
}
83+
}
84+
}
85+
}
86+
}
87+
}
88+
}
89+
}
90+
}
91+
}
92+
93+
bb0: {
94+
- StorageLive(_3);
95+
+ nop;
96+
StorageLive(_4);
97+
_4 = copy _1;
98+
- _3 = MyId(move _4);
99+
+ _3 = MyId(copy _1);
100+
StorageDead(_4);
101+
StorageLive(_5);
102+
StorageLive(_6);
103+
StorageLive(_7);
104+
- _7 = move _3;
105+
- _6 = move _7 as u16 (Transmute);
106+
+ _7 = copy _3;
107+
+ _6 = copy _1;
108+
StorageDead(_7);
109+
- _5 = opaque::<u16>(move _6) -> [return: bb1, unwind unreachable];
110+
+ _5 = opaque::<u16>(copy _1) -> [return: bb1, unwind unreachable];
111+
}
112+
113+
bb1: {
114+
StorageDead(_6);
115+
StorageDead(_5);
116+
- StorageLive(_8);
117+
+ nop;
118+
StorageLive(_9);
119+
_9 = copy _1;
120+
StorageLive(_10);
121+
- _10 = PhantomData::<String>;
122+
- _8 = TypedId::<String>(move _9, move _10);
123+
+ _10 = const PhantomData::<String>;
124+
+ _8 = TypedId::<String>(copy _1, const PhantomData::<String>);
125+
StorageDead(_10);
126+
StorageDead(_9);
127+
StorageLive(_11);
128+
StorageLive(_12);
129+
StorageLive(_13);
130+
- _13 = move _8;
131+
- _12 = move _13 as u16 (Transmute);
132+
+ _13 = copy _8;
133+
+ _12 = copy _1;
134+
StorageDead(_13);
135+
- _11 = opaque::<u16>(move _12) -> [return: bb2, unwind unreachable];
136+
+ _11 = opaque::<u16>(copy _1) -> [return: bb2, unwind unreachable];
137+
}
138+
139+
bb2: {
140+
StorageDead(_12);
141+
StorageDead(_11);
142+
- StorageLive(_14);
143+
+ nop;
144+
StorageLive(_15);
145+
_15 = copy _1;
146+
- _14 = Result::<Never, u16>::Err(move _15);
147+
+ _14 = Result::<Never, u16>::Err(copy _1);
148+
StorageDead(_15);
149+
StorageLive(_16);
150+
StorageLive(_17);
151+
StorageLive(_18);
152+
- _18 = move _14;
153+
- _17 = move _18 as u16 (Transmute);
154+
+ _18 = copy _14;
155+
+ _17 = copy _1;
156+
StorageDead(_18);
157+
- _16 = opaque::<u16>(move _17) -> [return: bb3, unwind unreachable];
158+
+ _16 = opaque::<u16>(copy _1) -> [return: bb3, unwind unreachable];
159+
}
160+
161+
bb3: {
162+
StorageDead(_17);
163+
StorageDead(_16);
164+
- StorageLive(_19);
165+
+ nop;
166+
StorageLive(_20);
167+
_20 = copy _1;
168+
- _19 = Option::<u16>::Some(move _20);
169+
+ _19 = Option::<u16>::Some(copy _1);
170+
StorageDead(_20);
171+
StorageLive(_21);
172+
StorageLive(_22);
173+
StorageLive(_23);
174+
_23 = copy _19;
175+
- _22 = move _23 as u32 (Transmute);
176+
+ _22 = copy _19 as u32 (Transmute);
177+
StorageDead(_23);
178+
_21 = opaque::<u32>(move _22) -> [return: bb4, unwind unreachable];
179+
}
180+
181+
bb4: {
182+
StorageDead(_22);
183+
StorageDead(_21);
184+
StorageLive(_24);
185+
StorageLive(_25);
186+
_25 = copy _1;
187+
- _24 = MyId(move _25);
188+
+ _24 = copy _3;
189+
StorageDead(_25);
190+
StorageLive(_26);
191+
StorageLive(_27);
192+
StorageLive(_28);
193+
- _28 = move _24;
194+
- _27 = move _28 as i16 (Transmute);
195+
+ _28 = copy _3;
196+
+ _27 = copy _1 as i16 (Transmute);
197+
StorageDead(_28);
198+
_26 = opaque::<i16>(move _27) -> [return: bb5, unwind unreachable];
199+
}
200+
201+
bb5: {
202+
StorageDead(_27);
203+
StorageDead(_26);
204+
- StorageLive(_29);
205+
+ nop;
206+
StorageLive(_30);
207+
_30 = copy _1;
208+
StorageLive(_31);
209+
_31 = copy _1;
210+
- _29 = Pair(move _30, move _31);
211+
+ _29 = Pair(copy _1, copy _1);
212+
StorageDead(_31);
213+
StorageDead(_30);
214+
StorageLive(_32);
215+
StorageLive(_33);
216+
StorageLive(_34);
217+
- _34 = move _29;
218+
- _33 = move _34 as u32 (Transmute);
219+
+ _34 = copy _29;
220+
+ _33 = copy _29 as u32 (Transmute);
221+
StorageDead(_34);
222+
_32 = opaque::<u32>(move _33) -> [return: bb6, unwind unreachable];
223+
}
224+
225+
bb6: {
226+
StorageDead(_33);
227+
StorageDead(_32);
228+
StorageLive(_35);
229+
StorageLive(_36);
230+
_36 = copy _1;
231+
StorageLive(_37);
232+
_37 = copy _1;
233+
- _35 = Pair(move _36, move _37);
234+
+ _35 = copy _29;
235+
StorageDead(_37);
236+
StorageDead(_36);
237+
StorageLive(_38);
238+
StorageLive(_39);
239+
StorageLive(_40);
240+
- _40 = move _35;
241+
- _39 = move _40 as u16 (Transmute);
242+
+ _40 = copy _29;
243+
+ _39 = copy _29 as u16 (Transmute);
244+
StorageDead(_40);
245+
_38 = opaque::<u16>(move _39) -> [return: bb7, unwind unreachable];
246+
}
247+
248+
bb7: {
249+
StorageDead(_39);
250+
StorageDead(_38);
251+
- StorageLive(_41);
252+
+ nop;
253+
StorageLive(_42);
254+
_42 = copy _1;
255+
- _41 = (move _42,);
256+
+ _41 = (copy _1,);
257+
StorageDead(_42);
258+
StorageLive(_43);
259+
StorageLive(_44);
260+
StorageLive(_45);
261+
_45 = copy _41;
262+
- _44 = move _45 as u16 (Transmute);
263+
+ _44 = copy _1;
264+
StorageDead(_45);
265+
- _43 = opaque::<u16>(move _44) -> [return: bb8, unwind unreachable];
266+
+ _43 = opaque::<u16>(copy _1) -> [return: bb8, unwind unreachable];
267+
}
268+
269+
bb8: {
270+
StorageDead(_44);
271+
StorageDead(_43);
272+
- StorageLive(_46);
273+
+ nop;
274+
StorageLive(_47);
275+
_47 = copy _1;
276+
- _46 = [move _47];
277+
+ _46 = [copy _1];
278+
StorageDead(_47);
279+
StorageLive(_48);
280+
StorageLive(_49);
281+
StorageLive(_50);
282+
_50 = copy _46;
283+
- _49 = move _50 as u16 (Transmute);
284+
+ _49 = copy _1;
285+
StorageDead(_50);
286+
- _48 = opaque::<u16>(move _49) -> [return: bb9, unwind unreachable];
287+
+ _48 = opaque::<u16>(copy _1) -> [return: bb9, unwind unreachable];
288+
}
289+
290+
bb9: {
291+
StorageDead(_49);
292+
StorageDead(_48);
293+
- StorageLive(_51);
294+
+ nop;
295+
StorageLive(_52);
296+
_52 = copy _2;
297+
StorageLive(_53);
298+
- _53 = ();
299+
- _51 = *const i32 from (move _52, move _53);
300+
+ _53 = const ();
301+
+ _51 = *const i32 from (copy _2, const ());
302+
StorageDead(_53);
303+
StorageDead(_52);
304+
StorageLive(_54);
305+
StorageLive(_55);
306+
StorageLive(_56);
307+
_56 = copy _51;
308+
- _55 = move _56 as *const u8 (Transmute);
309+
+ _55 = copy _2;
310+
StorageDead(_56);
311+
- _54 = opaque::<*const u8>(move _55) -> [return: bb10, unwind unreachable];
312+
+ _54 = opaque::<*const u8>(copy _2) -> [return: bb10, unwind unreachable];
313+
}
314+
315+
bb10: {
316+
StorageDead(_55);
317+
StorageDead(_54);
318+
_0 = const ();
319+
- StorageDead(_51);
320+
- StorageDead(_46);
321+
- StorageDead(_41);
322+
+ nop;
323+
+ nop;
324+
+ nop;
325+
StorageDead(_35);
326+
- StorageDead(_29);
327+
+ nop;
328+
StorageDead(_24);
329+
- StorageDead(_19);
330+
- StorageDead(_14);
331+
- StorageDead(_8);
332+
- StorageDead(_3);
333+
+ nop;
334+
+ nop;
335+
+ nop;
336+
+ nop;
337+
return;
338+
}
339+
}
340+
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
- // MIR for `aggregate_struct_then_transmute` before GVN
2+
+ // MIR for `aggregate_struct_then_transmute` after GVN
3+
4+
fn aggregate_struct_then_transmute(_1: u16, _2: *const u8) -> () {
5+
debug id => _1;
6+
debug thin => _2;
7+
let mut _0: ();
8+
let _3: MyId;
9+
let mut _4: u16;
10+
let _5: ();
11+
let mut _6: u16;
12+
let mut _7: MyId;
13+
let mut _9: u16;
14+
let mut _10: std::marker::PhantomData<std::string::String>;
15+
let _11: ();
16+
let mut _12: u16;
17+
let mut _13: TypedId<std::string::String>;
18+
let mut _15: u16;
19+
let _16: ();
20+
let mut _17: u16;
21+
let mut _18: std::result::Result<Never, u16>;
22+
let mut _20: u16;
23+
let _21: ();
24+
let mut _22: u32;
25+
let mut _23: std::option::Option<u16>;
26+
let mut _25: u16;
27+
let _26: ();
28+
let mut _27: i16;
29+
let mut _28: MyId;
30+
let mut _30: u16;
31+
let mut _31: u16;
32+
let _32: ();
33+
let mut _33: u32;
34+
let mut _34: aggregate_struct_then_transmute::Pair;
35+
let mut _36: u16;
36+
let mut _37: u16;
37+
let _38: ();
38+
let mut _39: u16;
39+
let mut _40: aggregate_struct_then_transmute::Pair;
40+
let mut _42: u16;
41+
let _43: ();
42+
let mut _44: u16;
43+
let mut _45: (u16,);
44+
let mut _47: u16;
45+
let _48: ();
46+
let mut _49: u16;
47+
let mut _50: [u16; 1];
48+
let mut _52: *const u8;
49+
let mut _53: ();
50+
let _54: ();
51+
let mut _55: *const u8;
52+
let mut _56: *const i32;
53+
scope 1 {
54+
debug a => _3;
55+
let _8: TypedId<std::string::String>;
56+
scope 2 {
57+
debug b => _8;
58+
let _14: std::result::Result<Never, u16>;
59+
scope 3 {
60+
debug c => _14;
61+
let _19: std::option::Option<u16>;
62+
scope 4 {
63+
debug d => _19;
64+
let _24: MyId;
65+
scope 5 {
66+
debug e => _24;
67+
let _29: aggregate_struct_then_transmute::Pair;
68+
scope 6 {
69+
debug f => _29;
70+
let _35: aggregate_struct_then_transmute::Pair;
71+
scope 7 {
72+
debug g => _35;
73+
let _41: (u16,);
74+
scope 8 {
75+
debug h => _41;
76+
let _46: [u16; 1];
77+
scope 9 {
78+
debug i => _46;
79+
let _51: *const i32;
80+
scope 10 {
81+
debug j => _51;
82+
}
83+
}
84+
}
85+
}
86+
}
87+
}
88+
}
89+
}
90+
}
91+
}
92+
93+
bb0: {
94+
- StorageLive(_3);
95+
+ nop;
96+
StorageLive(_4);
97+
_4 = copy _1;
98+
- _3 = MyId(move _4);
99+
+ _3 = MyId(copy _1);
100+
StorageDead(_4);
101+
StorageLive(_5);
102+
StorageLive(_6);
103+
StorageLive(_7);
104+
- _7 = move _3;
105+
- _6 = move _7 as u16 (Transmute);
106+
+ _7 = copy _3;
107+
+ _6 = copy _1;
108+
StorageDead(_7);
109+
- _5 = opaque::<u16>(move _6) -> [return: bb1, unwind continue];
110+
+ _5 = opaque::<u16>(copy _1) -> [return: bb1, unwind continue];
111+
}
112+
113+
bb1: {
114+
StorageDead(_6);
115+
StorageDead(_5);
116+
- StorageLive(_8);
117+
+ nop;
118+
StorageLive(_9);
119+
_9 = copy _1;
120+
StorageLive(_10);
121+
- _10 = PhantomData::<String>;
122+
- _8 = TypedId::<String>(move _9, move _10);
123+
+ _10 = const PhantomData::<String>;
124+
+ _8 = TypedId::<String>(copy _1, const PhantomData::<String>);
125+
StorageDead(_10);
126+
StorageDead(_9);
127+
StorageLive(_11);
128+
StorageLive(_12);
129+
StorageLive(_13);
130+
- _13 = move _8;
131+
- _12 = move _13 as u16 (Transmute);
132+
+ _13 = copy _8;
133+
+ _12 = copy _1;
134+
StorageDead(_13);
135+
- _11 = opaque::<u16>(move _12) -> [return: bb2, unwind continue];
136+
+ _11 = opaque::<u16>(copy _1) -> [return: bb2, unwind continue];
137+
}
138+
139+
bb2: {
140+
StorageDead(_12);
141+
StorageDead(_11);
142+
- StorageLive(_14);
143+
+ nop;
144+
StorageLive(_15);
145+
_15 = copy _1;
146+
- _14 = Result::<Never, u16>::Err(move _15);
147+
+ _14 = Result::<Never, u16>::Err(copy _1);
148+
StorageDead(_15);
149+
StorageLive(_16);
150+
StorageLive(_17);
151+
StorageLive(_18);
152+
- _18 = move _14;
153+
- _17 = move _18 as u16 (Transmute);
154+
+ _18 = copy _14;
155+
+ _17 = copy _1;
156+
StorageDead(_18);
157+
- _16 = opaque::<u16>(move _17) -> [return: bb3, unwind continue];
158+
+ _16 = opaque::<u16>(copy _1) -> [return: bb3, unwind continue];
159+
}
160+
161+
bb3: {
162+
StorageDead(_17);
163+
StorageDead(_16);
164+
- StorageLive(_19);
165+
+ nop;
166+
StorageLive(_20);
167+
_20 = copy _1;
168+
- _19 = Option::<u16>::Some(move _20);
169+
+ _19 = Option::<u16>::Some(copy _1);
170+
StorageDead(_20);
171+
StorageLive(_21);
172+
StorageLive(_22);
173+
StorageLive(_23);
174+
_23 = copy _19;
175+
- _22 = move _23 as u32 (Transmute);
176+
+ _22 = copy _19 as u32 (Transmute);
177+
StorageDead(_23);
178+
_21 = opaque::<u32>(move _22) -> [return: bb4, unwind continue];
179+
}
180+
181+
bb4: {
182+
StorageDead(_22);
183+
StorageDead(_21);
184+
StorageLive(_24);
185+
StorageLive(_25);
186+
_25 = copy _1;
187+
- _24 = MyId(move _25);
188+
+ _24 = copy _3;
189+
StorageDead(_25);
190+
StorageLive(_26);
191+
StorageLive(_27);
192+
StorageLive(_28);
193+
- _28 = move _24;
194+
- _27 = move _28 as i16 (Transmute);
195+
+ _28 = copy _3;
196+
+ _27 = copy _1 as i16 (Transmute);
197+
StorageDead(_28);
198+
_26 = opaque::<i16>(move _27) -> [return: bb5, unwind continue];
199+
}
200+
201+
bb5: {
202+
StorageDead(_27);
203+
StorageDead(_26);
204+
- StorageLive(_29);
205+
+ nop;
206+
StorageLive(_30);
207+
_30 = copy _1;
208+
StorageLive(_31);
209+
_31 = copy _1;
210+
- _29 = Pair(move _30, move _31);
211+
+ _29 = Pair(copy _1, copy _1);
212+
StorageDead(_31);
213+
StorageDead(_30);
214+
StorageLive(_32);
215+
StorageLive(_33);
216+
StorageLive(_34);
217+
- _34 = move _29;
218+
- _33 = move _34 as u32 (Transmute);
219+
+ _34 = copy _29;
220+
+ _33 = copy _29 as u32 (Transmute);
221+
StorageDead(_34);
222+
_32 = opaque::<u32>(move _33) -> [return: bb6, unwind continue];
223+
}
224+
225+
bb6: {
226+
StorageDead(_33);
227+
StorageDead(_32);
228+
StorageLive(_35);
229+
StorageLive(_36);
230+
_36 = copy _1;
231+
StorageLive(_37);
232+
_37 = copy _1;
233+
- _35 = Pair(move _36, move _37);
234+
+ _35 = copy _29;
235+
StorageDead(_37);
236+
StorageDead(_36);
237+
StorageLive(_38);
238+
StorageLive(_39);
239+
StorageLive(_40);
240+
- _40 = move _35;
241+
- _39 = move _40 as u16 (Transmute);
242+
+ _40 = copy _29;
243+
+ _39 = copy _29 as u16 (Transmute);
244+
StorageDead(_40);
245+
_38 = opaque::<u16>(move _39) -> [return: bb7, unwind continue];
246+
}
247+
248+
bb7: {
249+
StorageDead(_39);
250+
StorageDead(_38);
251+
- StorageLive(_41);
252+
+ nop;
253+
StorageLive(_42);
254+
_42 = copy _1;
255+
- _41 = (move _42,);
256+
+ _41 = (copy _1,);
257+
StorageDead(_42);
258+
StorageLive(_43);
259+
StorageLive(_44);
260+
StorageLive(_45);
261+
_45 = copy _41;
262+
- _44 = move _45 as u16 (Transmute);
263+
+ _44 = copy _1;
264+
StorageDead(_45);
265+
- _43 = opaque::<u16>(move _44) -> [return: bb8, unwind continue];
266+
+ _43 = opaque::<u16>(copy _1) -> [return: bb8, unwind continue];
267+
}
268+
269+
bb8: {
270+
StorageDead(_44);
271+
StorageDead(_43);
272+
- StorageLive(_46);
273+
+ nop;
274+
StorageLive(_47);
275+
_47 = copy _1;
276+
- _46 = [move _47];
277+
+ _46 = [copy _1];
278+
StorageDead(_47);
279+
StorageLive(_48);
280+
StorageLive(_49);
281+
StorageLive(_50);
282+
_50 = copy _46;
283+
- _49 = move _50 as u16 (Transmute);
284+
+ _49 = copy _1;
285+
StorageDead(_50);
286+
- _48 = opaque::<u16>(move _49) -> [return: bb9, unwind continue];
287+
+ _48 = opaque::<u16>(copy _1) -> [return: bb9, unwind continue];
288+
}
289+
290+
bb9: {
291+
StorageDead(_49);
292+
StorageDead(_48);
293+
- StorageLive(_51);
294+
+ nop;
295+
StorageLive(_52);
296+
_52 = copy _2;
297+
StorageLive(_53);
298+
- _53 = ();
299+
- _51 = *const i32 from (move _52, move _53);
300+
+ _53 = const ();
301+
+ _51 = *const i32 from (copy _2, const ());
302+
StorageDead(_53);
303+
StorageDead(_52);
304+
StorageLive(_54);
305+
StorageLive(_55);
306+
StorageLive(_56);
307+
_56 = copy _51;
308+
- _55 = move _56 as *const u8 (Transmute);
309+
+ _55 = copy _2;
310+
StorageDead(_56);
311+
- _54 = opaque::<*const u8>(move _55) -> [return: bb10, unwind continue];
312+
+ _54 = opaque::<*const u8>(copy _2) -> [return: bb10, unwind continue];
313+
}
314+
315+
bb10: {
316+
StorageDead(_55);
317+
StorageDead(_54);
318+
_0 = const ();
319+
- StorageDead(_51);
320+
- StorageDead(_46);
321+
- StorageDead(_41);
322+
+ nop;
323+
+ nop;
324+
+ nop;
325+
StorageDead(_35);
326+
- StorageDead(_29);
327+
+ nop;
328+
StorageDead(_24);
329+
- StorageDead(_19);
330+
- StorageDead(_14);
331+
- StorageDead(_8);
332+
- StorageDead(_3);
333+
+ nop;
334+
+ nop;
335+
+ nop;
336+
+ nop;
337+
return;
338+
}
339+
}
340+

‎tests/mir-opt/gvn.rs

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#![allow(unused)]
1313

1414
use std::intrinsics::mir::*;
15-
use std::marker::Freeze;
15+
use std::marker::{Freeze, PhantomData};
1616
use std::mem::transmute;
1717

1818
struct S<T>(T);
@@ -933,6 +933,69 @@ fn cast_pointer_eq(p1: *mut u8, p2: *mut u32, p3: *mut u32, p4: *mut [u32]) {
933933
// CHECK: _0 = const ();
934934
}
935935

936+
unsafe fn aggregate_struct_then_transmute(id: u16, thin: *const u8) {
937+
// CHECK: opaque::<u16>(copy _1)
938+
let a = MyId(id);
939+
opaque(std::intrinsics::transmute::<_, u16>(a));
940+
941+
// CHECK: opaque::<u16>(copy _1)
942+
let b = TypedId::<String>(id, PhantomData);
943+
opaque(std::intrinsics::transmute::<_, u16>(b));
944+
945+
// CHECK: opaque::<u16>(copy _1)
946+
let c = Err::<Never, u16>(id);
947+
opaque(std::intrinsics::transmute::<_, u16>(c));
948+
949+
// CHECK: [[TEMP1:_[0-9]+]] = Option::<u16>::Some(copy _1);
950+
// CHECK: [[TEMP2:_[0-9]+]] = copy [[TEMP1]] as u32 (Transmute);
951+
// CHECK: opaque::<u32>(move [[TEMP2]])
952+
let d = Some(id);
953+
opaque(std::intrinsics::transmute::<_, u32>(d));
954+
955+
// Still need the transmute, but the aggregate can be skipped
956+
// CHECK: [[TEMP:_[0-9]+]] = copy _1 as i16 (Transmute);
957+
// CHECK: opaque::<i16>(move [[TEMP]])
958+
let e = MyId(id);
959+
opaque(std::intrinsics::transmute::<_, i16>(e));
960+
961+
// CHECK: [[PAIR:_[0-9]+]] = Pair(copy _1, copy _1);
962+
// CHECK: [[TEMP:_[0-9]+]] = copy [[PAIR]] as u32 (Transmute);
963+
// CHECK: opaque::<u32>(move [[TEMP]])
964+
struct Pair(u16, u16);
965+
let f = Pair(id, id);
966+
opaque(std::intrinsics::transmute::<_, u32>(f));
967+
968+
// CHECK: [[TEMP:_[0-9]+]] = copy [[PAIR]] as u16 (Transmute);
969+
// CHECK: opaque::<u16>(move [[TEMP]])
970+
let g = Pair(id, id);
971+
opaque(std::intrinsics::transmute_unchecked::<_, u16>(g));
972+
973+
// CHECK: opaque::<u16>(copy _1)
974+
let h = (id,);
975+
opaque(std::intrinsics::transmute::<_, u16>(h));
976+
977+
// CHECK: opaque::<u16>(copy _1)
978+
let i = [id];
979+
opaque(std::intrinsics::transmute::<_, u16>(i));
980+
981+
// CHECK: opaque::<*const u8>(copy _2)
982+
let j: *const i32 = std::intrinsics::aggregate_raw_ptr(thin, ());
983+
opaque(std::intrinsics::transmute::<_, *const u8>(j));
984+
}
985+
986+
unsafe fn transmute_then_transmute_again(a: u32, c: char) {
987+
// CHECK: [[TEMP1:_[0-9]+]] = copy _1 as char (Transmute);
988+
// CHECK: [[TEMP2:_[0-9]+]] = copy [[TEMP1]] as i32 (Transmute);
989+
// CHECK: opaque::<i32>(move [[TEMP2]])
990+
let x = std::intrinsics::transmute::<u32, char>(a);
991+
opaque(std::intrinsics::transmute::<char, i32>(x));
992+
993+
// CHECK: [[TEMP:_[0-9]+]] = copy _2 as i32 (Transmute);
994+
// CHECK: opaque::<i32>(move [[TEMP]])
995+
let x = std::intrinsics::transmute::<char, u32>(c);
996+
opaque(std::intrinsics::transmute::<u32, i32>(x));
997+
}
998+
936999
// Transmuting can skip a pointer cast so long as it wasn't a fat-to-thin cast.
9371000
unsafe fn cast_pointer_then_transmute(thin: *mut u32, fat: *mut [u8]) {
9381001
// CHECK-LABEL: fn cast_pointer_then_transmute
@@ -946,6 +1009,28 @@ unsafe fn cast_pointer_then_transmute(thin: *mut u32, fat: *mut [u8]) {
9461009
let fat_addr: usize = std::intrinsics::transmute(fat as *const ());
9471010
}
9481011

1012+
unsafe fn transmute_then_cast_pointer(addr: usize, fat: *mut [u8]) {
1013+
// CHECK-LABEL: fn transmute_then_cast_pointer
1014+
1015+
// This is roughly what `NonNull::dangling` does
1016+
// CHECK: [[CPTR:_.+]] = copy _1 as *const u8 (Transmute);
1017+
// CHECK: takes_const_ptr::<u8>(move [[CPTR]])
1018+
let p: *mut u8 = std::intrinsics::transmute(addr);
1019+
takes_const_ptr(p);
1020+
1021+
// This cast is fat-to-thin, so can't be merged with the transmute
1022+
// CHECK: [[FAT:_.+]] = move {{.+}} as *const [i32] (Transmute);
1023+
// CHECK: [[THIN:_.+]] = copy [[FAT]] as *const i32 (PtrToPtr);
1024+
// CHECK: takes_const_ptr::<i32>(move [[THIN]])
1025+
let q = std::intrinsics::transmute::<&mut [i32], *const [i32]>(&mut [1, 2, 3]);
1026+
takes_const_ptr(q as *const i32);
1027+
1028+
// CHECK: [[TPTR:_.+]] = copy _2 as *const u8 (PtrToPtr);
1029+
// CHECK: takes_const_ptr::<u8>(move [[TPTR]])
1030+
let w = std::intrinsics::transmute::<*mut [u8], *const [u8]>(fat);
1031+
takes_const_ptr(w as *const u8);
1032+
}
1033+
9491034
#[custom_mir(dialect = "analysis")]
9501035
fn remove_casts_must_change_both_sides(mut_a: &*mut u8, mut_b: *mut u8) -> bool {
9511036
// CHECK-LABEL: fn remove_casts_must_change_both_sides(
@@ -1002,6 +1087,18 @@ fn identity<T>(x: T) -> T {
10021087
x
10031088
}
10041089

1090+
#[inline(never)]
1091+
fn takes_const_ptr<T>(_: *const T) {}
1092+
1093+
#[repr(transparent)]
1094+
#[rustc_layout_scalar_valid_range_end(55555)]
1095+
struct MyId(u16);
1096+
1097+
#[repr(transparent)]
1098+
struct TypedId<T>(u16, PhantomData<T>);
1099+
1100+
enum Never {}
1101+
10051102
// EMIT_MIR gvn.subexpression_elimination.GVN.diff
10061103
// EMIT_MIR gvn.wrap_unwrap.GVN.diff
10071104
// EMIT_MIR gvn.repeated_index.GVN.diff
@@ -1034,5 +1131,8 @@ fn identity<T>(x: T) -> T {
10341131
// EMIT_MIR gvn.dedup_multiple_bounds_checks_lengths.GVN.diff
10351132
// EMIT_MIR gvn.generic_cast_metadata.GVN.diff
10361133
// EMIT_MIR gvn.cast_pointer_eq.GVN.diff
1134+
// EMIT_MIR gvn.aggregate_struct_then_transmute.GVN.diff
1135+
// EMIT_MIR gvn.transmute_then_transmute_again.GVN.diff
10371136
// EMIT_MIR gvn.cast_pointer_then_transmute.GVN.diff
1137+
// EMIT_MIR gvn.transmute_then_cast_pointer.GVN.diff
10381138
// EMIT_MIR gvn.remove_casts_must_change_both_sides.GVN.diff
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
- // MIR for `transmute_then_cast_pointer` before GVN
2+
+ // MIR for `transmute_then_cast_pointer` after GVN
3+
4+
fn transmute_then_cast_pointer(_1: usize, _2: *mut [u8]) -> () {
5+
debug addr => _1;
6+
debug fat => _2;
7+
let mut _0: ();
8+
let _3: *mut u8;
9+
let mut _4: usize;
10+
let _5: ();
11+
let mut _6: *const u8;
12+
let mut _7: *mut u8;
13+
let mut _9: &mut [i32];
14+
let mut _10: &mut [i32; 3];
15+
let mut _11: &mut [i32; 3];
16+
let mut _12: [i32; 3];
17+
let _13: ();
18+
let mut _14: *const i32;
19+
let mut _15: *const [i32];
20+
let mut _17: *mut [u8];
21+
let _18: ();
22+
let mut _19: *const u8;
23+
let mut _20: *const [u8];
24+
scope 1 {
25+
debug p => _3;
26+
let _8: *const [i32];
27+
scope 2 {
28+
debug q => _8;
29+
let _16: *const [u8];
30+
scope 3 {
31+
debug w => _16;
32+
}
33+
}
34+
}
35+
36+
bb0: {
37+
- StorageLive(_3);
38+
+ nop;
39+
StorageLive(_4);
40+
_4 = copy _1;
41+
- _3 = move _4 as *mut u8 (Transmute);
42+
+ _3 = copy _1 as *mut u8 (Transmute);
43+
StorageDead(_4);
44+
StorageLive(_5);
45+
StorageLive(_6);
46+
StorageLive(_7);
47+
_7 = copy _3;
48+
- _6 = move _7 as *const u8 (PtrToPtr);
49+
+ _6 = copy _1 as *const u8 (Transmute);
50+
StorageDead(_7);
51+
_5 = takes_const_ptr::<u8>(move _6) -> [return: bb1, unwind unreachable];
52+
}
53+
54+
bb1: {
55+
StorageDead(_6);
56+
StorageDead(_5);
57+
- StorageLive(_8);
58+
+ nop;
59+
StorageLive(_9);
60+
StorageLive(_10);
61+
StorageLive(_11);
62+
StorageLive(_12);
63+
_12 = [const 1_i32, const 2_i32, const 3_i32];
64+
_11 = &mut _12;
65+
_10 = &mut (*_11);
66+
_9 = move _10 as &mut [i32] (PointerCoercion(Unsize, Implicit));
67+
StorageDead(_10);
68+
_8 = move _9 as *const [i32] (Transmute);
69+
StorageDead(_9);
70+
StorageDead(_12);
71+
StorageDead(_11);
72+
StorageLive(_13);
73+
StorageLive(_14);
74+
StorageLive(_15);
75+
_15 = copy _8;
76+
- _14 = move _15 as *const i32 (PtrToPtr);
77+
+ _14 = copy _8 as *const i32 (PtrToPtr);
78+
StorageDead(_15);
79+
_13 = takes_const_ptr::<i32>(move _14) -> [return: bb2, unwind unreachable];
80+
}
81+
82+
bb2: {
83+
StorageDead(_14);
84+
StorageDead(_13);
85+
- StorageLive(_16);
86+
+ nop;
87+
StorageLive(_17);
88+
_17 = copy _2;
89+
- _16 = move _17 as *const [u8] (Transmute);
90+
+ _16 = copy _2 as *const [u8] (PtrToPtr);
91+
StorageDead(_17);
92+
StorageLive(_18);
93+
StorageLive(_19);
94+
StorageLive(_20);
95+
_20 = copy _16;
96+
- _19 = move _20 as *const u8 (PtrToPtr);
97+
+ _19 = copy _2 as *const u8 (PtrToPtr);
98+
StorageDead(_20);
99+
_18 = takes_const_ptr::<u8>(move _19) -> [return: bb3, unwind unreachable];
100+
}
101+
102+
bb3: {
103+
StorageDead(_19);
104+
StorageDead(_18);
105+
_0 = const ();
106+
- StorageDead(_16);
107+
- StorageDead(_8);
108+
- StorageDead(_3);
109+
+ nop;
110+
+ nop;
111+
+ nop;
112+
return;
113+
}
114+
}
115+
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
- // MIR for `transmute_then_cast_pointer` before GVN
2+
+ // MIR for `transmute_then_cast_pointer` after GVN
3+
4+
fn transmute_then_cast_pointer(_1: usize, _2: *mut [u8]) -> () {
5+
debug addr => _1;
6+
debug fat => _2;
7+
let mut _0: ();
8+
let _3: *mut u8;
9+
let mut _4: usize;
10+
let _5: ();
11+
let mut _6: *const u8;
12+
let mut _7: *mut u8;
13+
let mut _9: &mut [i32];
14+
let mut _10: &mut [i32; 3];
15+
let mut _11: &mut [i32; 3];
16+
let mut _12: [i32; 3];
17+
let _13: ();
18+
let mut _14: *const i32;
19+
let mut _15: *const [i32];
20+
let mut _17: *mut [u8];
21+
let _18: ();
22+
let mut _19: *const u8;
23+
let mut _20: *const [u8];
24+
scope 1 {
25+
debug p => _3;
26+
let _8: *const [i32];
27+
scope 2 {
28+
debug q => _8;
29+
let _16: *const [u8];
30+
scope 3 {
31+
debug w => _16;
32+
}
33+
}
34+
}
35+
36+
bb0: {
37+
- StorageLive(_3);
38+
+ nop;
39+
StorageLive(_4);
40+
_4 = copy _1;
41+
- _3 = move _4 as *mut u8 (Transmute);
42+
+ _3 = copy _1 as *mut u8 (Transmute);
43+
StorageDead(_4);
44+
StorageLive(_5);
45+
StorageLive(_6);
46+
StorageLive(_7);
47+
_7 = copy _3;
48+
- _6 = move _7 as *const u8 (PtrToPtr);
49+
+ _6 = copy _1 as *const u8 (Transmute);
50+
StorageDead(_7);
51+
_5 = takes_const_ptr::<u8>(move _6) -> [return: bb1, unwind continue];
52+
}
53+
54+
bb1: {
55+
StorageDead(_6);
56+
StorageDead(_5);
57+
- StorageLive(_8);
58+
+ nop;
59+
StorageLive(_9);
60+
StorageLive(_10);
61+
StorageLive(_11);
62+
StorageLive(_12);
63+
_12 = [const 1_i32, const 2_i32, const 3_i32];
64+
_11 = &mut _12;
65+
_10 = &mut (*_11);
66+
_9 = move _10 as &mut [i32] (PointerCoercion(Unsize, Implicit));
67+
StorageDead(_10);
68+
_8 = move _9 as *const [i32] (Transmute);
69+
StorageDead(_9);
70+
StorageDead(_12);
71+
StorageDead(_11);
72+
StorageLive(_13);
73+
StorageLive(_14);
74+
StorageLive(_15);
75+
_15 = copy _8;
76+
- _14 = move _15 as *const i32 (PtrToPtr);
77+
+ _14 = copy _8 as *const i32 (PtrToPtr);
78+
StorageDead(_15);
79+
_13 = takes_const_ptr::<i32>(move _14) -> [return: bb2, unwind continue];
80+
}
81+
82+
bb2: {
83+
StorageDead(_14);
84+
StorageDead(_13);
85+
- StorageLive(_16);
86+
+ nop;
87+
StorageLive(_17);
88+
_17 = copy _2;
89+
- _16 = move _17 as *const [u8] (Transmute);
90+
+ _16 = copy _2 as *const [u8] (PtrToPtr);
91+
StorageDead(_17);
92+
StorageLive(_18);
93+
StorageLive(_19);
94+
StorageLive(_20);
95+
_20 = copy _16;
96+
- _19 = move _20 as *const u8 (PtrToPtr);
97+
+ _19 = copy _2 as *const u8 (PtrToPtr);
98+
StorageDead(_20);
99+
_18 = takes_const_ptr::<u8>(move _19) -> [return: bb3, unwind continue];
100+
}
101+
102+
bb3: {
103+
StorageDead(_19);
104+
StorageDead(_18);
105+
_0 = const ();
106+
- StorageDead(_16);
107+
- StorageDead(_8);
108+
- StorageDead(_3);
109+
+ nop;
110+
+ nop;
111+
+ nop;
112+
return;
113+
}
114+
}
115+
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
- // MIR for `transmute_then_transmute_again` before GVN
2+
+ // MIR for `transmute_then_transmute_again` after GVN
3+
4+
fn transmute_then_transmute_again(_1: u32, _2: char) -> () {
5+
debug a => _1;
6+
debug c => _2;
7+
let mut _0: ();
8+
let _3: char;
9+
let mut _4: u32;
10+
let _5: ();
11+
let mut _6: i32;
12+
let mut _7: char;
13+
let mut _9: char;
14+
let _10: ();
15+
let mut _11: i32;
16+
let mut _12: u32;
17+
scope 1 {
18+
debug x => _3;
19+
let _8: u32;
20+
scope 2 {
21+
debug x => _8;
22+
}
23+
}
24+
25+
bb0: {
26+
- StorageLive(_3);
27+
+ nop;
28+
StorageLive(_4);
29+
_4 = copy _1;
30+
- _3 = move _4 as char (Transmute);
31+
+ _3 = copy _1 as char (Transmute);
32+
StorageDead(_4);
33+
StorageLive(_5);
34+
StorageLive(_6);
35+
StorageLive(_7);
36+
_7 = copy _3;
37+
- _6 = move _7 as i32 (Transmute);
38+
+ _6 = copy _3 as i32 (Transmute);
39+
StorageDead(_7);
40+
_5 = opaque::<i32>(move _6) -> [return: bb1, unwind unreachable];
41+
}
42+
43+
bb1: {
44+
StorageDead(_6);
45+
StorageDead(_5);
46+
- StorageLive(_8);
47+
+ nop;
48+
StorageLive(_9);
49+
_9 = copy _2;
50+
- _8 = move _9 as u32 (Transmute);
51+
+ _8 = copy _2 as u32 (Transmute);
52+
StorageDead(_9);
53+
StorageLive(_10);
54+
StorageLive(_11);
55+
StorageLive(_12);
56+
_12 = copy _8;
57+
- _11 = move _12 as i32 (Transmute);
58+
+ _11 = copy _2 as i32 (Transmute);
59+
StorageDead(_12);
60+
_10 = opaque::<i32>(move _11) -> [return: bb2, unwind unreachable];
61+
}
62+
63+
bb2: {
64+
StorageDead(_11);
65+
StorageDead(_10);
66+
_0 = const ();
67+
- StorageDead(_8);
68+
- StorageDead(_3);
69+
+ nop;
70+
+ nop;
71+
return;
72+
}
73+
}
74+
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
- // MIR for `transmute_then_transmute_again` before GVN
2+
+ // MIR for `transmute_then_transmute_again` after GVN
3+
4+
fn transmute_then_transmute_again(_1: u32, _2: char) -> () {
5+
debug a => _1;
6+
debug c => _2;
7+
let mut _0: ();
8+
let _3: char;
9+
let mut _4: u32;
10+
let _5: ();
11+
let mut _6: i32;
12+
let mut _7: char;
13+
let mut _9: char;
14+
let _10: ();
15+
let mut _11: i32;
16+
let mut _12: u32;
17+
scope 1 {
18+
debug x => _3;
19+
let _8: u32;
20+
scope 2 {
21+
debug x => _8;
22+
}
23+
}
24+
25+
bb0: {
26+
- StorageLive(_3);
27+
+ nop;
28+
StorageLive(_4);
29+
_4 = copy _1;
30+
- _3 = move _4 as char (Transmute);
31+
+ _3 = copy _1 as char (Transmute);
32+
StorageDead(_4);
33+
StorageLive(_5);
34+
StorageLive(_6);
35+
StorageLive(_7);
36+
_7 = copy _3;
37+
- _6 = move _7 as i32 (Transmute);
38+
+ _6 = copy _3 as i32 (Transmute);
39+
StorageDead(_7);
40+
_5 = opaque::<i32>(move _6) -> [return: bb1, unwind continue];
41+
}
42+
43+
bb1: {
44+
StorageDead(_6);
45+
StorageDead(_5);
46+
- StorageLive(_8);
47+
+ nop;
48+
StorageLive(_9);
49+
_9 = copy _2;
50+
- _8 = move _9 as u32 (Transmute);
51+
+ _8 = copy _2 as u32 (Transmute);
52+
StorageDead(_9);
53+
StorageLive(_10);
54+
StorageLive(_11);
55+
StorageLive(_12);
56+
_12 = copy _8;
57+
- _11 = move _12 as i32 (Transmute);
58+
+ _11 = copy _2 as i32 (Transmute);
59+
StorageDead(_12);
60+
_10 = opaque::<i32>(move _11) -> [return: bb2, unwind continue];
61+
}
62+
63+
bb2: {
64+
StorageDead(_11);
65+
StorageDead(_10);
66+
_0 = const ();
67+
- StorageDead(_8);
68+
- StorageDead(_3);
69+
+ nop;
70+
+ nop;
71+
return;
72+
}
73+
}
74+

‎tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff

Lines changed: 75 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,43 @@
1111
+ scope 1 (inlined std::ptr::drop_in_place::<Vec<A>> - shim(Some(Vec<A>))) {
1212
+ let mut _6: &mut std::vec::Vec<A>;
1313
+ let mut _7: ();
14+
+ scope 2 (inlined <Vec<A> as Drop>::drop) {
15+
+ let mut _8: *mut [A];
16+
+ let mut _9: *mut A;
17+
+ let mut _10: usize;
18+
+ scope 3 (inlined Vec::<A>::as_mut_ptr) {
19+
+ scope 4 (inlined alloc::raw_vec::RawVec::<A>::ptr) {
20+
+ scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<A>) {
21+
+ scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<A>) {
22+
+ let mut _11: std::ptr::NonNull<u8>;
23+
+ scope 7 (inlined Unique::<u8>::cast::<A>) {
24+
+ scope 8 (inlined NonNull::<u8>::cast::<A>) {
25+
+ scope 9 (inlined NonNull::<u8>::as_ptr) {
26+
+ }
27+
+ }
28+
+ }
29+
+ scope 10 (inlined Unique::<A>::as_non_null_ptr) {
30+
+ }
31+
+ }
32+
+ scope 11 (inlined NonNull::<A>::as_ptr) {
33+
+ }
34+
+ }
35+
+ }
36+
+ }
37+
+ scope 12 (inlined slice_from_raw_parts_mut::<A>) {
38+
+ scope 13 (inlined std::ptr::from_raw_parts_mut::<[A], A>) {
39+
+ }
40+
+ }
41+
+ scope 14 (inlined std::ptr::drop_in_place::<[A]> - shim(Some([A]))) {
42+
+ let mut _12: usize;
43+
+ let mut _13: *mut A;
44+
+ let mut _14: bool;
45+
+ }
46+
+ }
1447
+ }
15-
+ scope 2 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
16-
+ let mut _8: isize;
17-
+ let mut _9: isize;
48+
+ scope 15 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
49+
+ let mut _15: isize;
50+
+ let mut _16: isize;
1851
+ }
1952

2053
bb0: {
@@ -25,7 +58,21 @@
2558
+ StorageLive(_6);
2659
+ StorageLive(_7);
2760
+ _6 = &mut (*_4);
28-
+ _7 = <Vec<A> as Drop>::drop(move _6) -> [return: bb2, unwind unreachable];
61+
+ StorageLive(_10);
62+
+ StorageLive(_8);
63+
+ StorageLive(_9);
64+
+ StorageLive(_11);
65+
+ _11 = copy (((((*_6).0: alloc::raw_vec::RawVec<A>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
66+
+ _9 = copy _11 as *mut A (Transmute);
67+
+ StorageDead(_11);
68+
+ _10 = copy ((*_6).1: usize);
69+
+ _8 = *mut [A] from (copy _9, copy _10);
70+
+ StorageDead(_9);
71+
+ StorageLive(_12);
72+
+ StorageLive(_13);
73+
+ StorageLive(_14);
74+
+ _12 = const 0_usize;
75+
+ goto -> bb4;
2976
}
3077

3178
bb1: {
@@ -36,25 +83,41 @@
3683
StorageLive(_5);
3784
_5 = copy _2;
3885
- _0 = std::ptr::drop_in_place::<Option<B>>(move _5) -> [return: bb2, unwind unreachable];
39-
+ StorageLive(_8);
40-
+ StorageLive(_9);
41-
+ _8 = discriminant((*_5));
42-
+ switchInt(move _8) -> [0: bb3, otherwise: bb4];
86+
+ StorageLive(_15);
87+
+ StorageLive(_16);
88+
+ _15 = discriminant((*_5));
89+
+ switchInt(move _15) -> [0: bb5, otherwise: bb6];
4390
}
4491

4592
bb2: {
93+
+ StorageDead(_14);
94+
+ StorageDead(_13);
95+
+ StorageDead(_12);
96+
+ StorageDead(_8);
97+
+ StorageDead(_10);
4698
+ drop(((*_4).0: alloc::raw_vec::RawVec<A>)) -> [return: bb1, unwind unreachable];
4799
+ }
48100
+
49101
+ bb3: {
50-
+ StorageDead(_9);
51-
+ StorageDead(_8);
102+
+ _13 = &raw mut (*_8)[_12];
103+
+ _12 = Add(move _12, const 1_usize);
104+
+ drop((*_13)) -> [return: bb4, unwind unreachable];
105+
+ }
106+
+
107+
+ bb4: {
108+
+ _14 = Eq(copy _12, copy _10);
109+
+ switchInt(move _14) -> [0: bb3, otherwise: bb2];
110+
+ }
111+
+
112+
+ bb5: {
113+
+ StorageDead(_16);
114+
+ StorageDead(_15);
52115
StorageDead(_5);
53116
return;
54117
+ }
55118
+
56-
+ bb4: {
57-
+ drop((((*_5) as Some).0: B)) -> [return: bb3, unwind unreachable];
119+
+ bb6: {
120+
+ drop((((*_5) as Some).0: B)) -> [return: bb5, unwind unreachable];
58121
}
59122
}
60123

‎tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn b(_1: &mut Box<T>) -> &mut T {
2020
StorageLive(_5);
2121
StorageLive(_6);
2222
_5 = copy (*_4);
23-
_6 = copy (((_5.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T);
23+
_6 = copy ((_5.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>) as *const T (Transmute);
2424
_3 = &mut (*_6);
2525
StorageDead(_6);
2626
StorageDead(_5);

‎tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ fn d(_1: &Box<T>) -> &T {
1818
StorageLive(_4);
1919
StorageLive(_5);
2020
_4 = copy (*_3);
21-
_5 = copy (((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T);
21+
_5 = copy ((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>) as *const T (Transmute);
2222
_2 = &(*_5);
2323
StorageDead(_5);
2424
StorageDead(_4);

‎tests/mir-opt/inline/unsized_argument.caller.Inline.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
StorageLive(_2);
1313
StorageLive(_3);
1414
_3 = move _1;
15-
_4 = copy (((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>).0: *const [i32]);
15+
_4 = copy ((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>) as *const [i32] (Transmute);
1616
_2 = callee(move (*_4)) -> [return: bb1, unwind: bb3];
1717
}
1818

‎tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify-after-simplifycfg.diff

Lines changed: 0 additions & 83 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
- // MIR for `keep_transparent_transmute` before InstSimplify-after-simplifycfg
2+
+ // MIR for `keep_transparent_transmute` after InstSimplify-after-simplifycfg
3+
4+
fn keep_transparent_transmute() -> () {
5+
let mut _0: ();
6+
let _1: i16;
7+
let mut _3: std::num::Wrapping<i16>;
8+
scope 1 {
9+
debug _a => _1;
10+
let _2: i16;
11+
scope 2 {
12+
debug _a => _2;
13+
}
14+
}
15+
16+
bb0: {
17+
StorageLive(_1);
18+
_1 = const keep_transparent_transmute::{constant#0} as i16 (Transmute);
19+
StorageLive(_2);
20+
StorageLive(_3);
21+
_3 = Wrapping::<i16>(const 0_i16);
22+
_2 = move _3 as i16 (Transmute);
23+
StorageDead(_3);
24+
_0 = const ();
25+
StorageDead(_2);
26+
StorageDead(_1);
27+
return;
28+
}
29+
}
30+

‎tests/mir-opt/instsimplify/combine_transmutes.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,19 @@ pub unsafe fn integer_transmutes() {
4343
}
4444
}
4545

46-
// EMIT_MIR combine_transmutes.adt_transmutes.InstSimplify-after-simplifycfg.diff
47-
pub unsafe fn adt_transmutes() {
48-
// CHECK-LABEL: fn adt_transmutes(
49-
// CHECK: as u8 (Transmute);
50-
// CHECK: ({{_.*}}.0: i16);
51-
// CHECK: as u16 (Transmute);
52-
// CHECK: as u32 (Transmute);
53-
// CHECK: as i32 (Transmute);
54-
// CHECK: ({{_.*}}.1: std::mem::ManuallyDrop<std::string::String>);
46+
// EMIT_MIR combine_transmutes.keep_transparent_transmute.InstSimplify-after-simplifycfg.diff
47+
pub unsafe fn keep_transparent_transmute() {
48+
// CHECK-LABEL: fn keep_transparent_transmute(
49+
// CHECK-NOT: .{{[0-9]+}}: i16
50+
// CHECK: as i16 (Transmute);
51+
// CHECK-NOT: .{{[0-9]+}}: i16
52+
// CHECK: as i16 (Transmute);
53+
// CHECK-NOT: .{{[0-9]+}}: i16
5554

56-
let _a: u8 = transmute(Some(std::num::NonZero::<u8>::MAX));
55+
// Transmutes should not be converted to field accesses, because MCP#807
56+
// bans projections into `[rustc_layout_scalar_valid_range_*]` types.
57+
let _a: i16 = transmute(const { std::num::NonZero::new(12345_i16).unwrap() });
5758
let _a: i16 = transmute(std::num::Wrapping(0_i16));
58-
let _a: u16 = transmute(std::num::Wrapping(0_i16));
59-
let _a: u32 = transmute(Union32 { i32: 0 });
60-
let _a: i32 = transmute(Union32 { u32: 0 });
61-
let _a: ManuallyDrop<String> = transmute(MaybeUninit::<String>::uninit());
6259
}
6360

6461
pub union Union32 {

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

Lines changed: 87 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,28 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
44
debug slice => _1;
55
debug f => _2;
66
let mut _0: ();
7-
let mut _13: std::slice::Iter<'_, T>;
8-
let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
9-
let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
10-
let mut _23: std::option::Option<(usize, &T)>;
11-
let mut _26: &impl Fn(usize, &T);
12-
let mut _27: (usize, &T);
13-
let _28: ();
7+
let mut _11: std::slice::Iter<'_, T>;
8+
let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>;
9+
let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>;
10+
let mut _21: std::option::Option<(usize, &T)>;
11+
let mut _24: &impl Fn(usize, &T);
12+
let mut _25: (usize, &T);
13+
let _26: ();
1414
scope 1 {
15-
debug iter => _15;
16-
let _24: usize;
17-
let _25: &T;
15+
debug iter => _13;
16+
let _22: usize;
17+
let _23: &T;
1818
scope 2 {
19-
debug i => _24;
20-
debug x => _25;
19+
debug i => _22;
20+
debug x => _23;
2121
}
2222
scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
23-
let mut _16: &mut std::slice::Iter<'_, T>;
24-
let mut _17: std::option::Option<&T>;
25-
let mut _21: (usize, bool);
26-
let mut _22: (usize, &T);
23+
let mut _14: &mut std::slice::Iter<'_, T>;
24+
let mut _15: std::option::Option<&T>;
25+
let mut _19: (usize, bool);
26+
let mut _20: (usize, &T);
2727
scope 19 {
28-
let _20: usize;
28+
let _18: usize;
2929
scope 24 {
3030
}
3131
}
@@ -40,8 +40,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
4040
}
4141
}
4242
scope 25 (inlined <Option<&T> as Try>::branch) {
43-
let mut _18: isize;
44-
let _19: &T;
43+
let mut _16: isize;
44+
let _17: &T;
4545
scope 26 {
4646
}
4747
}
@@ -50,14 +50,13 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
5050
scope 3 (inlined core::slice::<impl [T]>::iter) {
5151
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
5252
let _3: usize;
53-
let mut _5: std::ptr::NonNull<[T]>;
54-
let mut _9: *mut T;
55-
let mut _10: *mut T;
56-
let mut _12: *const T;
53+
let mut _7: *mut T;
54+
let mut _8: *mut T;
55+
let mut _10: *const T;
5756
scope 5 {
58-
let _8: std::ptr::NonNull<T>;
57+
let _6: std::ptr::NonNull<T>;
5958
scope 6 {
60-
let _11: *const T;
59+
let _9: *const T;
6160
scope 7 {
6261
}
6362
scope 12 (inlined without_provenance::<T>) {
@@ -73,8 +72,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
7372
}
7473
}
7574
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
76-
let mut _6: *mut [T];
77-
let mut _7: *const T;
75+
let mut _5: *const T;
7876
scope 11 (inlined NonNull::<[T]>::as_ptr) {
7977
}
8078
}
@@ -89,82 +87,76 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
8987
}
9088

9189
bb0: {
92-
StorageLive(_13);
90+
StorageLive(_11);
9391
StorageLive(_3);
94-
StorageLive(_8);
95-
_3 = PtrMetadata(copy _1);
96-
StorageLive(_5);
92+
StorageLive(_6);
9793
StorageLive(_4);
94+
_3 = PtrMetadata(copy _1);
9895
_4 = &raw const (*_1);
99-
_5 = NonNull::<[T]> { pointer: move _4 };
100-
StorageDead(_4);
101-
StorageLive(_6);
102-
StorageLive(_7);
103-
_6 = copy _5 as *mut [T] (Transmute);
104-
_7 = copy _6 as *const T (PtrToPtr);
105-
_8 = NonNull::<T> { pointer: move _7 };
106-
StorageDead(_7);
107-
StorageDead(_6);
96+
StorageLive(_5);
97+
_5 = copy _4 as *const T (PtrToPtr);
98+
_6 = NonNull::<T> { pointer: move _5 };
10899
StorageDead(_5);
109-
StorageLive(_11);
100+
StorageLive(_9);
110101
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
111102
}
112103

113104
bb1: {
114-
StorageLive(_10);
115-
StorageLive(_9);
116-
_9 = copy _8 as *mut T (Transmute);
117-
_10 = Offset(copy _9, copy _3);
118-
StorageDead(_9);
119-
_11 = move _10 as *const T (PtrToPtr);
120-
StorageDead(_10);
105+
StorageLive(_8);
106+
StorageLive(_7);
107+
_7 = copy _4 as *mut T (PtrToPtr);
108+
_8 = Offset(copy _7, copy _3);
109+
StorageDead(_7);
110+
_9 = move _8 as *const T (PtrToPtr);
111+
StorageDead(_8);
121112
goto -> bb3;
122113
}
123114

124115
bb2: {
125-
_11 = copy _3 as *const T (Transmute);
116+
_9 = copy _3 as *const T (Transmute);
126117
goto -> bb3;
127118
}
128119

129120
bb3: {
130-
StorageLive(_12);
131-
_12 = copy _11;
132-
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
133-
StorageDead(_12);
134-
StorageDead(_11);
135-
StorageDead(_8);
121+
StorageLive(_10);
122+
_10 = copy _9;
123+
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
124+
StorageDead(_10);
125+
StorageDead(_9);
126+
StorageDead(_4);
127+
StorageDead(_6);
136128
StorageDead(_3);
137-
_14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
138-
StorageDead(_13);
139-
StorageLive(_15);
140-
_15 = copy _14;
129+
_12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
130+
StorageDead(_11);
131+
StorageLive(_13);
132+
_13 = copy _12;
141133
goto -> bb4;
142134
}
143135

144136
bb4: {
145-
StorageLive(_23);
146-
StorageLive(_20);
147137
StorageLive(_21);
148-
StorageLive(_17);
149-
StorageLive(_16);
150-
_16 = &mut (_15.0: std::slice::Iter<'_, T>);
151-
_17 = <std::slice::Iter<'_, T> as Iterator>::next(move _16) -> [return: bb5, unwind unreachable];
138+
StorageLive(_18);
139+
StorageLive(_19);
140+
StorageLive(_15);
141+
StorageLive(_14);
142+
_14 = &mut (_13.0: std::slice::Iter<'_, T>);
143+
_15 = <std::slice::Iter<'_, T> as Iterator>::next(move _14) -> [return: bb5, unwind unreachable];
152144
}
153145

154146
bb5: {
155-
StorageDead(_16);
156-
StorageLive(_18);
157-
_18 = discriminant(_17);
158-
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb11];
147+
StorageDead(_14);
148+
StorageLive(_16);
149+
_16 = discriminant(_15);
150+
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb11];
159151
}
160152

161153
bb6: {
154+
StorageDead(_16);
155+
StorageDead(_15);
156+
StorageDead(_19);
162157
StorageDead(_18);
163-
StorageDead(_17);
164158
StorageDead(_21);
165-
StorageDead(_20);
166-
StorageDead(_23);
167-
StorageDead(_15);
159+
StorageDead(_13);
168160
drop(_2) -> [return: bb7, unwind unreachable];
169161
}
170162

@@ -173,35 +165,35 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
173165
}
174166

175167
bb8: {
176-
_19 = move ((_17 as Some).0: &T);
177-
StorageDead(_18);
178-
StorageDead(_17);
179-
_20 = copy (_15.1: usize);
180-
_21 = AddWithOverflow(copy (_15.1: usize), const 1_usize);
181-
assert(!move (_21.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_15.1: usize), const 1_usize) -> [success: bb9, unwind unreachable];
168+
_17 = move ((_15 as Some).0: &T);
169+
StorageDead(_16);
170+
StorageDead(_15);
171+
_18 = copy (_13.1: usize);
172+
_19 = AddWithOverflow(copy (_13.1: usize), const 1_usize);
173+
assert(!move (_19.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_13.1: usize), const 1_usize) -> [success: bb9, unwind unreachable];
182174
}
183175

184176
bb9: {
185-
(_15.1: usize) = move (_21.0: usize);
186-
StorageLive(_22);
187-
_22 = (copy _20, copy _19);
188-
_23 = Option::<(usize, &T)>::Some(move _22);
189-
StorageDead(_22);
190-
StorageDead(_21);
177+
(_13.1: usize) = move (_19.0: usize);
178+
StorageLive(_20);
179+
_20 = (copy _18, copy _17);
180+
_21 = Option::<(usize, &T)>::Some(move _20);
191181
StorageDead(_20);
192-
_24 = copy (((_23 as Some).0: (usize, &T)).0: usize);
193-
_25 = copy (((_23 as Some).0: (usize, &T)).1: &T);
194-
StorageLive(_26);
195-
_26 = &_2;
196-
StorageLive(_27);
197-
_27 = (copy _24, copy _25);
198-
_28 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _26, move _27) -> [return: bb10, unwind unreachable];
182+
StorageDead(_19);
183+
StorageDead(_18);
184+
_22 = copy (((_21 as Some).0: (usize, &T)).0: usize);
185+
_23 = copy (((_21 as Some).0: (usize, &T)).1: &T);
186+
StorageLive(_24);
187+
_24 = &_2;
188+
StorageLive(_25);
189+
_25 = (copy _22, copy _23);
190+
_26 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _24, move _25) -> [return: bb10, unwind unreachable];
199191
}
200192

201193
bb10: {
202-
StorageDead(_27);
203-
StorageDead(_26);
204-
StorageDead(_23);
194+
StorageDead(_25);
195+
StorageDead(_24);
196+
StorageDead(_21);
205197
goto -> bb4;
206198
}
207199

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

Lines changed: 62 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,34 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
44
debug slice => _1;
55
debug f => _2;
66
let mut _0: ();
7-
let mut _13: std::slice::Iter<'_, T>;
8-
let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
9-
let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
10-
let mut _16: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
11-
let mut _17: std::option::Option<(usize, &T)>;
12-
let mut _18: isize;
13-
let mut _21: &impl Fn(usize, &T);
14-
let mut _22: (usize, &T);
15-
let _23: ();
7+
let mut _11: std::slice::Iter<'_, T>;
8+
let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>;
9+
let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>;
10+
let mut _14: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
11+
let mut _15: std::option::Option<(usize, &T)>;
12+
let mut _16: isize;
13+
let mut _19: &impl Fn(usize, &T);
14+
let mut _20: (usize, &T);
15+
let _21: ();
1616
scope 1 {
17-
debug iter => _15;
18-
let _19: usize;
19-
let _20: &T;
17+
debug iter => _13;
18+
let _17: usize;
19+
let _18: &T;
2020
scope 2 {
21-
debug i => _19;
22-
debug x => _20;
21+
debug i => _17;
22+
debug x => _18;
2323
}
2424
}
2525
scope 3 (inlined core::slice::<impl [T]>::iter) {
2626
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
2727
let _3: usize;
28-
let mut _5: std::ptr::NonNull<[T]>;
29-
let mut _9: *mut T;
30-
let mut _10: *mut T;
31-
let mut _12: *const T;
28+
let mut _7: *mut T;
29+
let mut _8: *mut T;
30+
let mut _10: *const T;
3231
scope 5 {
33-
let _8: std::ptr::NonNull<T>;
32+
let _6: std::ptr::NonNull<T>;
3433
scope 6 {
35-
let _11: *const T;
34+
let _9: *const T;
3635
scope 7 {
3736
}
3837
scope 12 (inlined without_provenance::<T>) {
@@ -48,8 +47,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
4847
}
4948
}
5049
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
51-
let mut _6: *mut [T];
52-
let mut _7: *const T;
50+
let mut _5: *const T;
5351
scope 11 (inlined NonNull::<[T]>::as_ptr) {
5452
}
5553
}
@@ -64,72 +62,66 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
6462
}
6563

6664
bb0: {
67-
StorageLive(_13);
65+
StorageLive(_11);
6866
StorageLive(_3);
69-
StorageLive(_8);
70-
_3 = PtrMetadata(copy _1);
71-
StorageLive(_5);
67+
StorageLive(_6);
7268
StorageLive(_4);
69+
_3 = PtrMetadata(copy _1);
7370
_4 = &raw const (*_1);
74-
_5 = NonNull::<[T]> { pointer: move _4 };
75-
StorageDead(_4);
76-
StorageLive(_6);
77-
StorageLive(_7);
78-
_6 = copy _5 as *mut [T] (Transmute);
79-
_7 = copy _6 as *const T (PtrToPtr);
80-
_8 = NonNull::<T> { pointer: move _7 };
81-
StorageDead(_7);
82-
StorageDead(_6);
71+
StorageLive(_5);
72+
_5 = copy _4 as *const T (PtrToPtr);
73+
_6 = NonNull::<T> { pointer: move _5 };
8374
StorageDead(_5);
84-
StorageLive(_11);
75+
StorageLive(_9);
8576
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
8677
}
8778

8879
bb1: {
89-
StorageLive(_10);
90-
StorageLive(_9);
91-
_9 = copy _8 as *mut T (Transmute);
92-
_10 = Offset(copy _9, copy _3);
93-
StorageDead(_9);
94-
_11 = move _10 as *const T (PtrToPtr);
95-
StorageDead(_10);
80+
StorageLive(_8);
81+
StorageLive(_7);
82+
_7 = copy _4 as *mut T (PtrToPtr);
83+
_8 = Offset(copy _7, copy _3);
84+
StorageDead(_7);
85+
_9 = move _8 as *const T (PtrToPtr);
86+
StorageDead(_8);
9687
goto -> bb3;
9788
}
9889

9990
bb2: {
100-
_11 = copy _3 as *const T (Transmute);
91+
_9 = copy _3 as *const T (Transmute);
10192
goto -> bb3;
10293
}
10394

10495
bb3: {
105-
StorageLive(_12);
106-
_12 = copy _11;
107-
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
108-
StorageDead(_12);
109-
StorageDead(_11);
110-
StorageDead(_8);
96+
StorageLive(_10);
97+
_10 = copy _9;
98+
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
99+
StorageDead(_10);
100+
StorageDead(_9);
101+
StorageDead(_4);
102+
StorageDead(_6);
111103
StorageDead(_3);
112-
_14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
113-
StorageDead(_13);
114-
StorageLive(_15);
115-
_15 = copy _14;
104+
_12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
105+
StorageDead(_11);
106+
StorageLive(_13);
107+
_13 = copy _12;
116108
goto -> bb4;
117109
}
118110

119111
bb4: {
120-
StorageLive(_17);
121-
_16 = &mut _15;
122-
_17 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _16) -> [return: bb5, unwind: bb11];
112+
StorageLive(_15);
113+
_14 = &mut _13;
114+
_15 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _14) -> [return: bb5, unwind: bb11];
123115
}
124116

125117
bb5: {
126-
_18 = discriminant(_17);
127-
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
118+
_16 = discriminant(_15);
119+
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
128120
}
129121

130122
bb6: {
131-
StorageDead(_17);
132123
StorageDead(_15);
124+
StorageDead(_13);
133125
drop(_2) -> [return: bb7, unwind continue];
134126
}
135127

@@ -138,19 +130,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
138130
}
139131

140132
bb8: {
141-
_19 = copy (((_17 as Some).0: (usize, &T)).0: usize);
142-
_20 = copy (((_17 as Some).0: (usize, &T)).1: &T);
143-
StorageLive(_21);
144-
_21 = &_2;
145-
StorageLive(_22);
146-
_22 = (copy _19, copy _20);
147-
_23 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _21, move _22) -> [return: bb9, unwind: bb11];
133+
_17 = copy (((_15 as Some).0: (usize, &T)).0: usize);
134+
_18 = copy (((_15 as Some).0: (usize, &T)).1: &T);
135+
StorageLive(_19);
136+
_19 = &_2;
137+
StorageLive(_20);
138+
_20 = (copy _17, copy _18);
139+
_21 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
148140
}
149141

150142
bb9: {
151-
StorageDead(_22);
152-
StorageDead(_21);
153-
StorageDead(_17);
143+
StorageDead(_20);
144+
StorageDead(_19);
145+
StorageDead(_15);
154146
goto -> bb4;
155147
}
156148

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

Lines changed: 54 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
44
debug slice => _1;
55
debug f => _2;
66
let mut _0: ();
7-
let mut _13: std::slice::Iter<'_, T>;
8-
let mut _14: std::slice::Iter<'_, T>;
9-
let mut _15: &mut std::slice::Iter<'_, T>;
10-
let mut _16: std::option::Option<&T>;
11-
let mut _17: isize;
12-
let mut _19: &impl Fn(&T);
13-
let mut _20: (&T,);
14-
let _21: ();
7+
let mut _11: std::slice::Iter<'_, T>;
8+
let mut _12: std::slice::Iter<'_, T>;
9+
let mut _13: &mut std::slice::Iter<'_, T>;
10+
let mut _14: std::option::Option<&T>;
11+
let mut _15: isize;
12+
let mut _17: &impl Fn(&T);
13+
let mut _18: (&T,);
14+
let _19: ();
1515
scope 1 {
16-
debug iter => _14;
17-
let _18: &T;
16+
debug iter => _12;
17+
let _16: &T;
1818
scope 2 {
19-
debug x => _18;
19+
debug x => _16;
2020
}
2121
}
2222
scope 3 (inlined core::slice::<impl [T]>::iter) {
2323
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
2424
let _3: usize;
25-
let mut _5: std::ptr::NonNull<[T]>;
26-
let mut _9: *mut T;
27-
let mut _10: *mut T;
28-
let mut _12: *const T;
25+
let mut _7: *mut T;
26+
let mut _8: *mut T;
27+
let mut _10: *const T;
2928
scope 5 {
30-
let _8: std::ptr::NonNull<T>;
29+
let _6: std::ptr::NonNull<T>;
3130
scope 6 {
32-
let _11: *const T;
31+
let _9: *const T;
3332
scope 7 {
3433
}
3534
scope 12 (inlined without_provenance::<T>) {
@@ -45,8 +44,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
4544
}
4645
}
4746
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
48-
let mut _6: *mut [T];
49-
let mut _7: *const T;
47+
let mut _5: *const T;
5048
scope 11 (inlined NonNull::<[T]>::as_ptr) {
5149
}
5250
}
@@ -58,68 +56,62 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
5856

5957
bb0: {
6058
StorageLive(_3);
61-
StorageLive(_8);
62-
_3 = PtrMetadata(copy _1);
63-
StorageLive(_5);
59+
StorageLive(_6);
6460
StorageLive(_4);
61+
_3 = PtrMetadata(copy _1);
6562
_4 = &raw const (*_1);
66-
_5 = NonNull::<[T]> { pointer: move _4 };
67-
StorageDead(_4);
68-
StorageLive(_6);
69-
StorageLive(_7);
70-
_6 = copy _5 as *mut [T] (Transmute);
71-
_7 = copy _6 as *const T (PtrToPtr);
72-
_8 = NonNull::<T> { pointer: move _7 };
73-
StorageDead(_7);
74-
StorageDead(_6);
63+
StorageLive(_5);
64+
_5 = copy _4 as *const T (PtrToPtr);
65+
_6 = NonNull::<T> { pointer: move _5 };
7566
StorageDead(_5);
76-
StorageLive(_11);
67+
StorageLive(_9);
7768
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
7869
}
7970

8071
bb1: {
81-
StorageLive(_10);
82-
StorageLive(_9);
83-
_9 = copy _8 as *mut T (Transmute);
84-
_10 = Offset(copy _9, copy _3);
85-
StorageDead(_9);
86-
_11 = move _10 as *const T (PtrToPtr);
87-
StorageDead(_10);
72+
StorageLive(_8);
73+
StorageLive(_7);
74+
_7 = copy _4 as *mut T (PtrToPtr);
75+
_8 = Offset(copy _7, copy _3);
76+
StorageDead(_7);
77+
_9 = move _8 as *const T (PtrToPtr);
78+
StorageDead(_8);
8879
goto -> bb3;
8980
}
9081

9182
bb2: {
92-
_11 = copy _3 as *const T (Transmute);
83+
_9 = copy _3 as *const T (Transmute);
9384
goto -> bb3;
9485
}
9586

9687
bb3: {
88+
StorageLive(_10);
89+
_10 = copy _9;
90+
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
91+
StorageDead(_10);
92+
StorageDead(_9);
93+
StorageDead(_4);
94+
StorageDead(_6);
95+
StorageDead(_3);
9796
StorageLive(_12);
9897
_12 = copy _11;
99-
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
100-
StorageDead(_12);
101-
StorageDead(_11);
102-
StorageDead(_8);
103-
StorageDead(_3);
104-
StorageLive(_14);
105-
_14 = copy _13;
10698
goto -> bb4;
10799
}
108100

109101
bb4: {
110-
StorageLive(_16);
111-
_15 = &mut _14;
112-
_16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind unreachable];
102+
StorageLive(_14);
103+
_13 = &mut _12;
104+
_14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind unreachable];
113105
}
114106

115107
bb5: {
116-
_17 = discriminant(_16);
117-
switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
108+
_15 = discriminant(_14);
109+
switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10];
118110
}
119111

120112
bb6: {
121-
StorageDead(_16);
122113
StorageDead(_14);
114+
StorageDead(_12);
123115
drop(_2) -> [return: bb7, unwind unreachable];
124116
}
125117

@@ -128,18 +120,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
128120
}
129121

130122
bb8: {
131-
_18 = copy ((_16 as Some).0: &T);
132-
StorageLive(_19);
133-
_19 = &_2;
134-
StorageLive(_20);
135-
_20 = (copy _18,);
136-
_21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind unreachable];
123+
_16 = copy ((_14 as Some).0: &T);
124+
StorageLive(_17);
125+
_17 = &_2;
126+
StorageLive(_18);
127+
_18 = (copy _16,);
128+
_19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind unreachable];
137129
}
138130

139131
bb9: {
140-
StorageDead(_20);
141-
StorageDead(_19);
142-
StorageDead(_16);
132+
StorageDead(_18);
133+
StorageDead(_17);
134+
StorageDead(_14);
143135
goto -> bb4;
144136
}
145137

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

Lines changed: 54 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
44
debug slice => _1;
55
debug f => _2;
66
let mut _0: ();
7-
let mut _13: std::slice::Iter<'_, T>;
8-
let mut _14: std::slice::Iter<'_, T>;
9-
let mut _15: &mut std::slice::Iter<'_, T>;
10-
let mut _16: std::option::Option<&T>;
11-
let mut _17: isize;
12-
let mut _19: &impl Fn(&T);
13-
let mut _20: (&T,);
14-
let _21: ();
7+
let mut _11: std::slice::Iter<'_, T>;
8+
let mut _12: std::slice::Iter<'_, T>;
9+
let mut _13: &mut std::slice::Iter<'_, T>;
10+
let mut _14: std::option::Option<&T>;
11+
let mut _15: isize;
12+
let mut _17: &impl Fn(&T);
13+
let mut _18: (&T,);
14+
let _19: ();
1515
scope 1 {
16-
debug iter => _14;
17-
let _18: &T;
16+
debug iter => _12;
17+
let _16: &T;
1818
scope 2 {
19-
debug x => _18;
19+
debug x => _16;
2020
}
2121
}
2222
scope 3 (inlined core::slice::<impl [T]>::iter) {
2323
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
2424
let _3: usize;
25-
let mut _5: std::ptr::NonNull<[T]>;
26-
let mut _9: *mut T;
27-
let mut _10: *mut T;
28-
let mut _12: *const T;
25+
let mut _7: *mut T;
26+
let mut _8: *mut T;
27+
let mut _10: *const T;
2928
scope 5 {
30-
let _8: std::ptr::NonNull<T>;
29+
let _6: std::ptr::NonNull<T>;
3130
scope 6 {
32-
let _11: *const T;
31+
let _9: *const T;
3332
scope 7 {
3433
}
3534
scope 12 (inlined without_provenance::<T>) {
@@ -45,8 +44,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
4544
}
4645
}
4746
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
48-
let mut _6: *mut [T];
49-
let mut _7: *const T;
47+
let mut _5: *const T;
5048
scope 11 (inlined NonNull::<[T]>::as_ptr) {
5149
}
5250
}
@@ -58,68 +56,62 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
5856

5957
bb0: {
6058
StorageLive(_3);
61-
StorageLive(_8);
62-
_3 = PtrMetadata(copy _1);
63-
StorageLive(_5);
59+
StorageLive(_6);
6460
StorageLive(_4);
61+
_3 = PtrMetadata(copy _1);
6562
_4 = &raw const (*_1);
66-
_5 = NonNull::<[T]> { pointer: move _4 };
67-
StorageDead(_4);
68-
StorageLive(_6);
69-
StorageLive(_7);
70-
_6 = copy _5 as *mut [T] (Transmute);
71-
_7 = copy _6 as *const T (PtrToPtr);
72-
_8 = NonNull::<T> { pointer: move _7 };
73-
StorageDead(_7);
74-
StorageDead(_6);
63+
StorageLive(_5);
64+
_5 = copy _4 as *const T (PtrToPtr);
65+
_6 = NonNull::<T> { pointer: move _5 };
7566
StorageDead(_5);
76-
StorageLive(_11);
67+
StorageLive(_9);
7768
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
7869
}
7970

8071
bb1: {
81-
StorageLive(_10);
82-
StorageLive(_9);
83-
_9 = copy _8 as *mut T (Transmute);
84-
_10 = Offset(copy _9, copy _3);
85-
StorageDead(_9);
86-
_11 = move _10 as *const T (PtrToPtr);
87-
StorageDead(_10);
72+
StorageLive(_8);
73+
StorageLive(_7);
74+
_7 = copy _4 as *mut T (PtrToPtr);
75+
_8 = Offset(copy _7, copy _3);
76+
StorageDead(_7);
77+
_9 = move _8 as *const T (PtrToPtr);
78+
StorageDead(_8);
8879
goto -> bb3;
8980
}
9081

9182
bb2: {
92-
_11 = copy _3 as *const T (Transmute);
83+
_9 = copy _3 as *const T (Transmute);
9384
goto -> bb3;
9485
}
9586

9687
bb3: {
88+
StorageLive(_10);
89+
_10 = copy _9;
90+
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
91+
StorageDead(_10);
92+
StorageDead(_9);
93+
StorageDead(_4);
94+
StorageDead(_6);
95+
StorageDead(_3);
9796
StorageLive(_12);
9897
_12 = copy _11;
99-
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
100-
StorageDead(_12);
101-
StorageDead(_11);
102-
StorageDead(_8);
103-
StorageDead(_3);
104-
StorageLive(_14);
105-
_14 = copy _13;
10698
goto -> bb4;
10799
}
108100

109101
bb4: {
110-
StorageLive(_16);
111-
_15 = &mut _14;
112-
_16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind: bb11];
102+
StorageLive(_14);
103+
_13 = &mut _12;
104+
_14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind: bb11];
113105
}
114106

115107
bb5: {
116-
_17 = discriminant(_16);
117-
switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
108+
_15 = discriminant(_14);
109+
switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10];
118110
}
119111

120112
bb6: {
121-
StorageDead(_16);
122113
StorageDead(_14);
114+
StorageDead(_12);
123115
drop(_2) -> [return: bb7, unwind continue];
124116
}
125117

@@ -128,18 +120,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
128120
}
129121

130122
bb8: {
131-
_18 = copy ((_16 as Some).0: &T);
132-
StorageLive(_19);
133-
_19 = &_2;
134-
StorageLive(_20);
135-
_20 = (copy _18,);
136-
_21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
123+
_16 = copy ((_14 as Some).0: &T);
124+
StorageLive(_17);
125+
_17 = &_2;
126+
StorageLive(_18);
127+
_18 = (copy _16,);
128+
_19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind: bb11];
137129
}
138130

139131
bb9: {
140-
StorageDead(_20);
141-
StorageDead(_19);
142-
StorageDead(_16);
132+
StorageDead(_18);
133+
StorageDead(_17);
134+
StorageDead(_14);
143135
goto -> bb4;
144136
}
145137

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

Lines changed: 61 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,34 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
44
debug slice => _1;
55
debug f => _2;
66
let mut _0: ();
7-
let mut _13: std::slice::Iter<'_, T>;
8-
let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
9-
let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
10-
let mut _17: std::option::Option<&T>;
11-
let mut _18: isize;
12-
let mut _20: &impl Fn(&T);
13-
let mut _21: (&T,);
14-
let _22: ();
7+
let mut _11: std::slice::Iter<'_, T>;
8+
let mut _12: std::iter::Rev<std::slice::Iter<'_, T>>;
9+
let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>;
10+
let mut _15: std::option::Option<&T>;
11+
let mut _16: isize;
12+
let mut _18: &impl Fn(&T);
13+
let mut _19: (&T,);
14+
let _20: ();
1515
scope 1 {
16-
debug iter => _15;
17-
let _19: &T;
16+
debug iter => _13;
17+
let _17: &T;
1818
scope 2 {
19-
debug x => _19;
19+
debug x => _17;
2020
}
2121
scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
22-
let mut _16: &mut std::slice::Iter<'_, T>;
22+
let mut _14: &mut std::slice::Iter<'_, T>;
2323
}
2424
}
2525
scope 3 (inlined core::slice::<impl [T]>::iter) {
2626
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
2727
let _3: usize;
28-
let mut _5: std::ptr::NonNull<[T]>;
29-
let mut _9: *mut T;
30-
let mut _10: *mut T;
31-
let mut _12: *const T;
28+
let mut _7: *mut T;
29+
let mut _8: *mut T;
30+
let mut _10: *const T;
3231
scope 5 {
33-
let _8: std::ptr::NonNull<T>;
32+
let _6: std::ptr::NonNull<T>;
3433
scope 6 {
35-
let _11: *const T;
34+
let _9: *const T;
3635
scope 7 {
3736
}
3837
scope 12 (inlined without_provenance::<T>) {
@@ -48,8 +47,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
4847
}
4948
}
5049
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
51-
let mut _6: *mut [T];
52-
let mut _7: *const T;
50+
let mut _5: *const T;
5351
scope 11 (inlined NonNull::<[T]>::as_ptr) {
5452
}
5553
}
@@ -64,74 +62,68 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
6462
}
6563

6664
bb0: {
67-
StorageLive(_13);
65+
StorageLive(_11);
6866
StorageLive(_3);
69-
StorageLive(_8);
70-
_3 = PtrMetadata(copy _1);
71-
StorageLive(_5);
67+
StorageLive(_6);
7268
StorageLive(_4);
69+
_3 = PtrMetadata(copy _1);
7370
_4 = &raw const (*_1);
74-
_5 = NonNull::<[T]> { pointer: move _4 };
75-
StorageDead(_4);
76-
StorageLive(_6);
77-
StorageLive(_7);
78-
_6 = copy _5 as *mut [T] (Transmute);
79-
_7 = copy _6 as *const T (PtrToPtr);
80-
_8 = NonNull::<T> { pointer: move _7 };
81-
StorageDead(_7);
82-
StorageDead(_6);
71+
StorageLive(_5);
72+
_5 = copy _4 as *const T (PtrToPtr);
73+
_6 = NonNull::<T> { pointer: move _5 };
8374
StorageDead(_5);
84-
StorageLive(_11);
75+
StorageLive(_9);
8576
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
8677
}
8778

8879
bb1: {
89-
StorageLive(_10);
90-
StorageLive(_9);
91-
_9 = copy _8 as *mut T (Transmute);
92-
_10 = Offset(copy _9, copy _3);
93-
StorageDead(_9);
94-
_11 = move _10 as *const T (PtrToPtr);
95-
StorageDead(_10);
80+
StorageLive(_8);
81+
StorageLive(_7);
82+
_7 = copy _4 as *mut T (PtrToPtr);
83+
_8 = Offset(copy _7, copy _3);
84+
StorageDead(_7);
85+
_9 = move _8 as *const T (PtrToPtr);
86+
StorageDead(_8);
9687
goto -> bb3;
9788
}
9889

9990
bb2: {
100-
_11 = copy _3 as *const T (Transmute);
91+
_9 = copy _3 as *const T (Transmute);
10192
goto -> bb3;
10293
}
10394

10495
bb3: {
105-
StorageLive(_12);
106-
_12 = copy _11;
107-
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
108-
StorageDead(_12);
109-
StorageDead(_11);
110-
StorageDead(_8);
96+
StorageLive(_10);
97+
_10 = copy _9;
98+
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
99+
StorageDead(_10);
100+
StorageDead(_9);
101+
StorageDead(_4);
102+
StorageDead(_6);
111103
StorageDead(_3);
112-
_14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 };
113-
StorageDead(_13);
114-
StorageLive(_15);
115-
_15 = copy _14;
104+
_12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 };
105+
StorageDead(_11);
106+
StorageLive(_13);
107+
_13 = copy _12;
116108
goto -> bb4;
117109
}
118110

119111
bb4: {
120-
StorageLive(_17);
121-
StorageLive(_16);
122-
_16 = &mut (_15.0: std::slice::Iter<'_, T>);
123-
_17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind unreachable];
112+
StorageLive(_15);
113+
StorageLive(_14);
114+
_14 = &mut (_13.0: std::slice::Iter<'_, T>);
115+
_15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable];
124116
}
125117

126118
bb5: {
127-
StorageDead(_16);
128-
_18 = discriminant(_17);
129-
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
119+
StorageDead(_14);
120+
_16 = discriminant(_15);
121+
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
130122
}
131123

132124
bb6: {
133-
StorageDead(_17);
134125
StorageDead(_15);
126+
StorageDead(_13);
135127
drop(_2) -> [return: bb7, unwind unreachable];
136128
}
137129

@@ -140,18 +132,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
140132
}
141133

142134
bb8: {
143-
_19 = copy ((_17 as Some).0: &T);
144-
StorageLive(_20);
145-
_20 = &_2;
146-
StorageLive(_21);
147-
_21 = (copy _19,);
148-
_22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind unreachable];
135+
_17 = copy ((_15 as Some).0: &T);
136+
StorageLive(_18);
137+
_18 = &_2;
138+
StorageLive(_19);
139+
_19 = (copy _17,);
140+
_20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind unreachable];
149141
}
150142

151143
bb9: {
152-
StorageDead(_21);
153-
StorageDead(_20);
154-
StorageDead(_17);
144+
StorageDead(_19);
145+
StorageDead(_18);
146+
StorageDead(_15);
155147
goto -> bb4;
156148
}
157149

‎tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir

Lines changed: 61 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,34 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
44
debug slice => _1;
55
debug f => _2;
66
let mut _0: ();
7-
let mut _13: std::slice::Iter<'_, T>;
8-
let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
9-
let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
10-
let mut _17: std::option::Option<&T>;
11-
let mut _18: isize;
12-
let mut _20: &impl Fn(&T);
13-
let mut _21: (&T,);
14-
let _22: ();
7+
let mut _11: std::slice::Iter<'_, T>;
8+
let mut _12: std::iter::Rev<std::slice::Iter<'_, T>>;
9+
let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>;
10+
let mut _15: std::option::Option<&T>;
11+
let mut _16: isize;
12+
let mut _18: &impl Fn(&T);
13+
let mut _19: (&T,);
14+
let _20: ();
1515
scope 1 {
16-
debug iter => _15;
17-
let _19: &T;
16+
debug iter => _13;
17+
let _17: &T;
1818
scope 2 {
19-
debug x => _19;
19+
debug x => _17;
2020
}
2121
scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
22-
let mut _16: &mut std::slice::Iter<'_, T>;
22+
let mut _14: &mut std::slice::Iter<'_, T>;
2323
}
2424
}
2525
scope 3 (inlined core::slice::<impl [T]>::iter) {
2626
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
2727
let _3: usize;
28-
let mut _5: std::ptr::NonNull<[T]>;
29-
let mut _9: *mut T;
30-
let mut _10: *mut T;
31-
let mut _12: *const T;
28+
let mut _7: *mut T;
29+
let mut _8: *mut T;
30+
let mut _10: *const T;
3231
scope 5 {
33-
let _8: std::ptr::NonNull<T>;
32+
let _6: std::ptr::NonNull<T>;
3433
scope 6 {
35-
let _11: *const T;
34+
let _9: *const T;
3635
scope 7 {
3736
}
3837
scope 12 (inlined without_provenance::<T>) {
@@ -48,8 +47,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
4847
}
4948
}
5049
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
51-
let mut _6: *mut [T];
52-
let mut _7: *const T;
50+
let mut _5: *const T;
5351
scope 11 (inlined NonNull::<[T]>::as_ptr) {
5452
}
5553
}
@@ -64,74 +62,68 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
6462
}
6563

6664
bb0: {
67-
StorageLive(_13);
65+
StorageLive(_11);
6866
StorageLive(_3);
69-
StorageLive(_8);
70-
_3 = PtrMetadata(copy _1);
71-
StorageLive(_5);
67+
StorageLive(_6);
7268
StorageLive(_4);
69+
_3 = PtrMetadata(copy _1);
7370
_4 = &raw const (*_1);
74-
_5 = NonNull::<[T]> { pointer: move _4 };
75-
StorageDead(_4);
76-
StorageLive(_6);
77-
StorageLive(_7);
78-
_6 = copy _5 as *mut [T] (Transmute);
79-
_7 = copy _6 as *const T (PtrToPtr);
80-
_8 = NonNull::<T> { pointer: move _7 };
81-
StorageDead(_7);
82-
StorageDead(_6);
71+
StorageLive(_5);
72+
_5 = copy _4 as *const T (PtrToPtr);
73+
_6 = NonNull::<T> { pointer: move _5 };
8374
StorageDead(_5);
84-
StorageLive(_11);
75+
StorageLive(_9);
8576
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
8677
}
8778

8879
bb1: {
89-
StorageLive(_10);
90-
StorageLive(_9);
91-
_9 = copy _8 as *mut T (Transmute);
92-
_10 = Offset(copy _9, copy _3);
93-
StorageDead(_9);
94-
_11 = move _10 as *const T (PtrToPtr);
95-
StorageDead(_10);
80+
StorageLive(_8);
81+
StorageLive(_7);
82+
_7 = copy _4 as *mut T (PtrToPtr);
83+
_8 = Offset(copy _7, copy _3);
84+
StorageDead(_7);
85+
_9 = move _8 as *const T (PtrToPtr);
86+
StorageDead(_8);
9687
goto -> bb3;
9788
}
9889

9990
bb2: {
100-
_11 = copy _3 as *const T (Transmute);
91+
_9 = copy _3 as *const T (Transmute);
10192
goto -> bb3;
10293
}
10394

10495
bb3: {
105-
StorageLive(_12);
106-
_12 = copy _11;
107-
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
108-
StorageDead(_12);
109-
StorageDead(_11);
110-
StorageDead(_8);
96+
StorageLive(_10);
97+
_10 = copy _9;
98+
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
99+
StorageDead(_10);
100+
StorageDead(_9);
101+
StorageDead(_4);
102+
StorageDead(_6);
111103
StorageDead(_3);
112-
_14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 };
113-
StorageDead(_13);
114-
StorageLive(_15);
115-
_15 = copy _14;
104+
_12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 };
105+
StorageDead(_11);
106+
StorageLive(_13);
107+
_13 = copy _12;
116108
goto -> bb4;
117109
}
118110

119111
bb4: {
120-
StorageLive(_17);
121-
StorageLive(_16);
122-
_16 = &mut (_15.0: std::slice::Iter<'_, T>);
123-
_17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind: bb11];
112+
StorageLive(_15);
113+
StorageLive(_14);
114+
_14 = &mut (_13.0: std::slice::Iter<'_, T>);
115+
_15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11];
124116
}
125117

126118
bb5: {
127-
StorageDead(_16);
128-
_18 = discriminant(_17);
129-
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
119+
StorageDead(_14);
120+
_16 = discriminant(_15);
121+
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
130122
}
131123

132124
bb6: {
133-
StorageDead(_17);
134125
StorageDead(_15);
126+
StorageDead(_13);
135127
drop(_2) -> [return: bb7, unwind continue];
136128
}
137129

@@ -140,18 +132,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
140132
}
141133

142134
bb8: {
143-
_19 = copy ((_17 as Some).0: &T);
144-
StorageLive(_20);
145-
_20 = &_2;
146-
StorageLive(_21);
147-
_21 = (copy _19,);
148-
_22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind: bb11];
135+
_17 = copy ((_15 as Some).0: &T);
136+
StorageLive(_18);
137+
_18 = &_2;
138+
StorageLive(_19);
139+
_19 = (copy _17,);
140+
_20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind: bb11];
149141
}
150142

151143
bb9: {
152-
StorageDead(_21);
153-
StorageDead(_20);
154-
StorageDead(_17);
144+
StorageDead(_19);
145+
StorageDead(_18);
146+
StorageDead(_15);
155147
goto -> bb4;
156148
}
157149

‎tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,16 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
77
debug self => _1;
88
scope 2 (inlined Vec::<u8>::as_slice) {
99
debug self => _1;
10-
let mut _7: *const u8;
11-
let mut _8: usize;
10+
let mut _3: *const u8;
11+
let mut _4: usize;
1212
scope 3 (inlined Vec::<u8>::as_ptr) {
1313
debug self => _1;
14-
let mut _6: *mut u8;
1514
scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
1615
scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
17-
let mut _5: std::ptr::NonNull<u8>;
1816
scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
1917
let mut _2: std::ptr::NonNull<u8>;
2018
scope 7 (inlined Unique::<u8>::cast::<u8>) {
2119
scope 8 (inlined NonNull::<u8>::cast::<u8>) {
22-
let mut _3: *mut u8;
23-
let mut _4: *const u8;
2420
scope 9 (inlined NonNull::<u8>::as_ptr) {
2521
}
2622
}
@@ -34,9 +30,9 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
3430
}
3531
}
3632
scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
37-
debug data => _7;
38-
debug len => _8;
39-
let _9: *const [u8];
33+
debug data => _3;
34+
debug len => _4;
35+
let _5: *const [u8];
4036
scope 13 (inlined core::ub_checks::check_language_ub) {
4137
scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
4238
}
@@ -46,42 +42,30 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
4642
scope 16 (inlined align_of::<u8>) {
4743
}
4844
scope 17 (inlined slice_from_raw_parts::<u8>) {
49-
debug data => _7;
50-
debug len => _8;
45+
debug data => _3;
46+
debug len => _4;
5147
scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
52-
debug data_pointer => _7;
48+
debug data_pointer => _3;
5349
}
5450
}
5551
}
5652
}
5753
}
5854

5955
bb0: {
60-
StorageLive(_6);
61-
StorageLive(_7);
62-
StorageLive(_5);
6356
StorageLive(_2);
64-
_2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
6557
StorageLive(_3);
58+
_2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
59+
_3 = copy _2 as *const u8 (Transmute);
6660
StorageLive(_4);
67-
_3 = copy _2 as *mut u8 (Transmute);
68-
_4 = copy _3 as *const u8 (PtrToPtr);
69-
_5 = NonNull::<u8> { pointer: move _4 };
61+
_4 = copy ((*_1).1: usize);
62+
StorageLive(_5);
63+
_5 = *const [u8] from (copy _3, copy _4);
64+
_0 = &(*_5);
65+
StorageDead(_5);
7066
StorageDead(_4);
7167
StorageDead(_3);
7268
StorageDead(_2);
73-
_6 = copy _5 as *mut u8 (Transmute);
74-
StorageDead(_5);
75-
_7 = copy _6 as *const u8 (PtrToPtr);
76-
StorageLive(_8);
77-
_8 = copy ((*_1).1: usize);
78-
StorageLive(_9);
79-
_9 = *const [u8] from (copy _7, copy _8);
80-
_0 = &(*_9);
81-
StorageDead(_9);
82-
StorageDead(_8);
83-
StorageDead(_7);
84-
StorageDead(_6);
8569
return;
8670
}
8771
}

‎tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,16 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
77
debug self => _1;
88
scope 2 (inlined Vec::<u8>::as_slice) {
99
debug self => _1;
10-
let mut _7: *const u8;
11-
let mut _8: usize;
10+
let mut _3: *const u8;
11+
let mut _4: usize;
1212
scope 3 (inlined Vec::<u8>::as_ptr) {
1313
debug self => _1;
14-
let mut _6: *mut u8;
1514
scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
1615
scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
17-
let mut _5: std::ptr::NonNull<u8>;
1816
scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
1917
let mut _2: std::ptr::NonNull<u8>;
2018
scope 7 (inlined Unique::<u8>::cast::<u8>) {
2119
scope 8 (inlined NonNull::<u8>::cast::<u8>) {
22-
let mut _3: *mut u8;
23-
let mut _4: *const u8;
2420
scope 9 (inlined NonNull::<u8>::as_ptr) {
2521
}
2622
}
@@ -34,9 +30,9 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
3430
}
3531
}
3632
scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
37-
debug data => _7;
38-
debug len => _8;
39-
let _9: *const [u8];
33+
debug data => _3;
34+
debug len => _4;
35+
let _5: *const [u8];
4036
scope 13 (inlined core::ub_checks::check_language_ub) {
4137
scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
4238
}
@@ -46,42 +42,30 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
4642
scope 16 (inlined align_of::<u8>) {
4743
}
4844
scope 17 (inlined slice_from_raw_parts::<u8>) {
49-
debug data => _7;
50-
debug len => _8;
45+
debug data => _3;
46+
debug len => _4;
5147
scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
52-
debug data_pointer => _7;
48+
debug data_pointer => _3;
5349
}
5450
}
5551
}
5652
}
5753
}
5854

5955
bb0: {
60-
StorageLive(_6);
61-
StorageLive(_7);
62-
StorageLive(_5);
6356
StorageLive(_2);
64-
_2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
6557
StorageLive(_3);
58+
_2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
59+
_3 = copy _2 as *const u8 (Transmute);
6660
StorageLive(_4);
67-
_3 = copy _2 as *mut u8 (Transmute);
68-
_4 = copy _3 as *const u8 (PtrToPtr);
69-
_5 = NonNull::<u8> { pointer: move _4 };
61+
_4 = copy ((*_1).1: usize);
62+
StorageLive(_5);
63+
_5 = *const [u8] from (copy _3, copy _4);
64+
_0 = &(*_5);
65+
StorageDead(_5);
7066
StorageDead(_4);
7167
StorageDead(_3);
7268
StorageDead(_2);
73-
_6 = copy _5 as *mut u8 (Transmute);
74-
StorageDead(_5);
75-
_7 = copy _6 as *const u8 (PtrToPtr);
76-
StorageLive(_8);
77-
_8 = copy ((*_1).1: usize);
78-
StorageLive(_9);
79-
_9 = *const [u8] from (copy _7, copy _8);
80-
_0 = &(*_9);
81-
StorageDead(_9);
82-
StorageDead(_8);
83-
StorageDead(_7);
84-
StorageDead(_6);
8569
return;
8670
}
8771
}

0 commit comments

Comments
 (0)
Please sign in to comment.