[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()`.
Found these as I was looking at MCP807-related changes.
This commit is contained in:
parent
e26ff2f908
commit
8dcc676c92
30 changed files with 1045 additions and 659 deletions
|
|
@ -1368,7 +1368,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
|
||||
let mut was_updated = false;
|
||||
|
||||
// If that cast just casts away the metadata again,
|
||||
// Transmuting `*const T` <=> `*mut T` is just a pointer cast,
|
||||
// which we might be able to merge with other ones later.
|
||||
if let Transmute = kind
|
||||
&& let ty::RawPtr(from_pointee, _) = from.kind()
|
||||
&& let ty::RawPtr(to_pointee, _) = to.kind()
|
||||
&& from_pointee == to_pointee
|
||||
{
|
||||
*kind = PtrToPtr;
|
||||
was_updated = true;
|
||||
}
|
||||
|
||||
// If a cast just casts away the metadata again, then we can get it by
|
||||
// casting the original thin pointer passed to `from_raw_parts`
|
||||
if let PtrToPtr = kind
|
||||
&& let Value::Aggregate(AggregateTy::RawPtr { data_pointer_ty, .. }, _, fields) =
|
||||
self.get(value)
|
||||
|
|
@ -1397,6 +1409,28 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// Aggregate-then-Transmute can just transmute the original field value,
|
||||
// so long as the type is transparent over only that one single field.
|
||||
if let Transmute = kind
|
||||
&& let Value::Aggregate(
|
||||
AggregateTy::Def(aggregate_did, aggregate_args),
|
||||
FIRST_VARIANT,
|
||||
field_values,
|
||||
) = self.get(value)
|
||||
&& let [single_field_value] = **field_values
|
||||
&& let adt = self.tcx.adt_def(aggregate_did)
|
||||
&& adt.is_struct()
|
||||
&& adt.repr().transparent()
|
||||
{
|
||||
let field_ty = adt.non_enum_variant().single_field().ty(self.tcx, aggregate_args);
|
||||
from = field_ty;
|
||||
value = single_field_value;
|
||||
was_updated = true;
|
||||
if field_ty == to {
|
||||
return Some(single_field_value);
|
||||
}
|
||||
}
|
||||
|
||||
// PtrToPtr-then-Transmute can just transmute the original, so long as the
|
||||
// PtrToPtr didn't change metadata (and thus the size of the pointer)
|
||||
if let Transmute = kind
|
||||
|
|
@ -1416,6 +1450,26 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// PtrToPtr-then-Transmute can just transmute the original, so long as the
|
||||
// PtrToPtr didn't change metadata (and thus the size of the pointer)
|
||||
if let PtrToPtr = kind
|
||||
&& let Value::Cast {
|
||||
kind: Transmute,
|
||||
value: inner_value,
|
||||
from: inner_from,
|
||||
to: _inner_to,
|
||||
} = *self.get(value)
|
||||
&& self.pointers_have_same_metadata(from, to)
|
||||
{
|
||||
*kind = Transmute;
|
||||
from = inner_from;
|
||||
value = inner_value;
|
||||
was_updated = true;
|
||||
if inner_from == to {
|
||||
return Some(inner_value);
|
||||
}
|
||||
}
|
||||
|
||||
if was_updated && let Some(op) = self.try_as_operand(value, location) {
|
||||
*operand = op;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,29 +173,6 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
|
|||
*kind = CastKind::IntToInt;
|
||||
return;
|
||||
}
|
||||
|
||||
// Transmuting a transparent struct/union to a field's type is a projection
|
||||
if let ty::Adt(adt_def, args) = operand_ty.kind()
|
||||
&& adt_def.repr().transparent()
|
||||
&& (adt_def.is_struct() || adt_def.is_union())
|
||||
&& let Some(place) = operand.place()
|
||||
{
|
||||
let variant = adt_def.non_enum_variant();
|
||||
for (i, field) in variant.fields.iter_enumerated() {
|
||||
let field_ty = field.ty(self.tcx, args);
|
||||
if field_ty == *cast_ty {
|
||||
let place = place
|
||||
.project_deeper(&[ProjectionElem::Field(i, *cast_ty)], self.tcx);
|
||||
let operand = if operand.is_move() {
|
||||
Operand::Move(place)
|
||||
} else {
|
||||
Operand::Copy(place)
|
||||
};
|
||||
*rvalue = Rvalue::Use(operand);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
StorageLive(_7);
|
||||
_7 = const 1_usize;
|
||||
_6 = const {0x1 as *mut [bool; 0]};
|
||||
StorageDead(_7);
|
||||
StorageLive(_11);
|
||||
StorageLive(_8);
|
||||
_8 = UbChecks();
|
||||
|
|
@ -79,6 +78,7 @@
|
|||
_11 = const {0x1 as *const [bool; 0]};
|
||||
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||
StorageDead(_11);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
|
||||
StorageDead(_5);
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
StorageLive(_7);
|
||||
_7 = const 1_usize;
|
||||
_6 = const {0x1 as *mut [bool; 0]};
|
||||
StorageDead(_7);
|
||||
StorageLive(_11);
|
||||
StorageLive(_8);
|
||||
_8 = UbChecks();
|
||||
|
|
@ -83,6 +82,7 @@
|
|||
_11 = const {0x1 as *const [bool; 0]};
|
||||
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||
StorageDead(_11);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
|
||||
StorageDead(_5);
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
StorageLive(_7);
|
||||
_7 = const 1_usize;
|
||||
_6 = const {0x1 as *mut [bool; 0]};
|
||||
StorageDead(_7);
|
||||
StorageLive(_11);
|
||||
StorageLive(_8);
|
||||
_8 = UbChecks();
|
||||
|
|
@ -79,6 +78,7 @@
|
|||
_11 = const {0x1 as *const [bool; 0]};
|
||||
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||
StorageDead(_11);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
|
||||
StorageDead(_5);
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
StorageLive(_7);
|
||||
_7 = const 1_usize;
|
||||
_6 = const {0x1 as *mut [bool; 0]};
|
||||
StorageDead(_7);
|
||||
StorageLive(_11);
|
||||
StorageLive(_8);
|
||||
_8 = UbChecks();
|
||||
|
|
@ -83,6 +82,7 @@
|
|||
_11 = const {0x1 as *const [bool; 0]};
|
||||
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||
StorageDead(_11);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
|
||||
StorageDead(_5);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@
|
|||
- _6 = copy _7 as *mut [bool; 0] (Transmute);
|
||||
+ _7 = const 1_usize;
|
||||
+ _6 = const {0x1 as *mut [bool; 0]};
|
||||
StorageDead(_7);
|
||||
StorageLive(_11);
|
||||
StorageLive(_8);
|
||||
_8 = UbChecks();
|
||||
|
|
@ -67,7 +66,7 @@
|
|||
|
||||
bb2: {
|
||||
StorageLive(_10);
|
||||
- _10 = copy _6 as *mut () (PtrToPtr);
|
||||
- _10 = copy _7 as *mut () (Transmute);
|
||||
- _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
|
||||
+ _10 = const {0x1 as *mut ()};
|
||||
+ _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable];
|
||||
|
|
@ -80,11 +79,12 @@
|
|||
|
||||
bb4: {
|
||||
StorageDead(_8);
|
||||
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
|
||||
- _11 = copy _7 as *const [bool; 0] (Transmute);
|
||||
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
|
||||
+ _11 = const {0x1 as *const [bool; 0]};
|
||||
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||
StorageDead(_11);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
|
||||
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@
|
|||
- _6 = copy _7 as *mut [bool; 0] (Transmute);
|
||||
+ _7 = const 1_usize;
|
||||
+ _6 = const {0x1 as *mut [bool; 0]};
|
||||
StorageDead(_7);
|
||||
StorageLive(_11);
|
||||
StorageLive(_8);
|
||||
_8 = UbChecks();
|
||||
|
|
@ -71,7 +70,7 @@
|
|||
|
||||
bb3: {
|
||||
StorageLive(_10);
|
||||
- _10 = copy _6 as *mut () (PtrToPtr);
|
||||
- _10 = copy _7 as *mut () (Transmute);
|
||||
- _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
|
||||
+ _10 = const {0x1 as *mut ()};
|
||||
+ _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable];
|
||||
|
|
@ -84,11 +83,12 @@
|
|||
|
||||
bb5: {
|
||||
StorageDead(_8);
|
||||
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
|
||||
- _11 = copy _7 as *const [bool; 0] (Transmute);
|
||||
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
|
||||
+ _11 = const {0x1 as *const [bool; 0]};
|
||||
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||
StorageDead(_11);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
|
||||
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@
|
|||
- _6 = copy _7 as *mut [bool; 0] (Transmute);
|
||||
+ _7 = const 1_usize;
|
||||
+ _6 = const {0x1 as *mut [bool; 0]};
|
||||
StorageDead(_7);
|
||||
StorageLive(_11);
|
||||
StorageLive(_8);
|
||||
_8 = UbChecks();
|
||||
|
|
@ -67,7 +66,7 @@
|
|||
|
||||
bb2: {
|
||||
StorageLive(_10);
|
||||
- _10 = copy _6 as *mut () (PtrToPtr);
|
||||
- _10 = copy _7 as *mut () (Transmute);
|
||||
- _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
|
||||
+ _10 = const {0x1 as *mut ()};
|
||||
+ _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable];
|
||||
|
|
@ -80,11 +79,12 @@
|
|||
|
||||
bb4: {
|
||||
StorageDead(_8);
|
||||
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
|
||||
- _11 = copy _7 as *const [bool; 0] (Transmute);
|
||||
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
|
||||
+ _11 = const {0x1 as *const [bool; 0]};
|
||||
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||
StorageDead(_11);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
|
||||
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@
|
|||
- _6 = copy _7 as *mut [bool; 0] (Transmute);
|
||||
+ _7 = const 1_usize;
|
||||
+ _6 = const {0x1 as *mut [bool; 0]};
|
||||
StorageDead(_7);
|
||||
StorageLive(_11);
|
||||
StorageLive(_8);
|
||||
_8 = UbChecks();
|
||||
|
|
@ -71,7 +70,7 @@
|
|||
|
||||
bb3: {
|
||||
StorageLive(_10);
|
||||
- _10 = copy _6 as *mut () (PtrToPtr);
|
||||
- _10 = copy _7 as *mut () (Transmute);
|
||||
- _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
|
||||
+ _10 = const {0x1 as *mut ()};
|
||||
+ _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable];
|
||||
|
|
@ -84,11 +83,12 @@
|
|||
|
||||
bb5: {
|
||||
StorageDead(_8);
|
||||
- _11 = copy _6 as *const [bool; 0] (PtrToPtr);
|
||||
- _11 = copy _7 as *const [bool; 0] (Transmute);
|
||||
- _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
|
||||
+ _11 = const {0x1 as *const [bool; 0]};
|
||||
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||
StorageDead(_11);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
|
||||
+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
- // MIR for `aggregate_struct_then_transmute` before GVN
|
||||
+ // MIR for `aggregate_struct_then_transmute` after GVN
|
||||
|
||||
fn aggregate_struct_then_transmute(_1: u16) -> () {
|
||||
debug id => _1;
|
||||
let mut _0: ();
|
||||
let _2: MyId;
|
||||
let mut _3: u16;
|
||||
let _4: ();
|
||||
let mut _5: u16;
|
||||
let mut _6: MyId;
|
||||
let mut _8: u16;
|
||||
let mut _9: std::marker::PhantomData<std::string::String>;
|
||||
let _10: ();
|
||||
let mut _11: u16;
|
||||
let mut _12: TypedId<std::string::String>;
|
||||
scope 1 {
|
||||
debug a => _2;
|
||||
let _7: TypedId<std::string::String>;
|
||||
scope 2 {
|
||||
debug b => _7;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_2);
|
||||
+ nop;
|
||||
StorageLive(_3);
|
||||
_3 = copy _1;
|
||||
- _2 = MyId(move _3);
|
||||
+ _2 = MyId(copy _1);
|
||||
StorageDead(_3);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
- _6 = move _2;
|
||||
- _5 = move _6 as u16 (Transmute);
|
||||
+ _6 = copy _2;
|
||||
+ _5 = copy _1;
|
||||
StorageDead(_6);
|
||||
- _4 = opaque::<u16>(move _5) -> [return: bb1, unwind unreachable];
|
||||
+ _4 = opaque::<u16>(copy _1) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
- StorageLive(_7);
|
||||
+ nop;
|
||||
StorageLive(_8);
|
||||
_8 = copy _1;
|
||||
StorageLive(_9);
|
||||
- _9 = PhantomData::<String>;
|
||||
- _7 = TypedId::<String>(move _8, move _9);
|
||||
+ _9 = const PhantomData::<String>;
|
||||
+ _7 = TypedId::<String>(copy _1, const PhantomData::<String>);
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
StorageLive(_12);
|
||||
- _12 = move _7;
|
||||
- _11 = move _12 as u16 (Transmute);
|
||||
+ _12 = copy _7;
|
||||
+ _11 = copy _7 as u16 (Transmute);
|
||||
StorageDead(_12);
|
||||
_10 = opaque::<u16>(move _11) -> [return: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
_0 = const ();
|
||||
- StorageDead(_7);
|
||||
- StorageDead(_2);
|
||||
+ nop;
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
- // MIR for `aggregate_struct_then_transmute` before GVN
|
||||
+ // MIR for `aggregate_struct_then_transmute` after GVN
|
||||
|
||||
fn aggregate_struct_then_transmute(_1: u16) -> () {
|
||||
debug id => _1;
|
||||
let mut _0: ();
|
||||
let _2: MyId;
|
||||
let mut _3: u16;
|
||||
let _4: ();
|
||||
let mut _5: u16;
|
||||
let mut _6: MyId;
|
||||
let mut _8: u16;
|
||||
let mut _9: std::marker::PhantomData<std::string::String>;
|
||||
let _10: ();
|
||||
let mut _11: u16;
|
||||
let mut _12: TypedId<std::string::String>;
|
||||
scope 1 {
|
||||
debug a => _2;
|
||||
let _7: TypedId<std::string::String>;
|
||||
scope 2 {
|
||||
debug b => _7;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_2);
|
||||
+ nop;
|
||||
StorageLive(_3);
|
||||
_3 = copy _1;
|
||||
- _2 = MyId(move _3);
|
||||
+ _2 = MyId(copy _1);
|
||||
StorageDead(_3);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
- _6 = move _2;
|
||||
- _5 = move _6 as u16 (Transmute);
|
||||
+ _6 = copy _2;
|
||||
+ _5 = copy _1;
|
||||
StorageDead(_6);
|
||||
- _4 = opaque::<u16>(move _5) -> [return: bb1, unwind continue];
|
||||
+ _4 = opaque::<u16>(copy _1) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
- StorageLive(_7);
|
||||
+ nop;
|
||||
StorageLive(_8);
|
||||
_8 = copy _1;
|
||||
StorageLive(_9);
|
||||
- _9 = PhantomData::<String>;
|
||||
- _7 = TypedId::<String>(move _8, move _9);
|
||||
+ _9 = const PhantomData::<String>;
|
||||
+ _7 = TypedId::<String>(copy _1, const PhantomData::<String>);
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
StorageLive(_12);
|
||||
- _12 = move _7;
|
||||
- _11 = move _12 as u16 (Transmute);
|
||||
+ _12 = copy _7;
|
||||
+ _11 = copy _7 as u16 (Transmute);
|
||||
StorageDead(_12);
|
||||
_10 = opaque::<u16>(move _11) -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
_0 = const ();
|
||||
- StorageDead(_7);
|
||||
- StorageDead(_2);
|
||||
+ nop;
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
#![allow(unused)]
|
||||
|
||||
use std::intrinsics::mir::*;
|
||||
use std::marker::Freeze;
|
||||
use std::marker::{Freeze, PhantomData};
|
||||
use std::mem::transmute;
|
||||
|
||||
struct S<T>(T);
|
||||
|
|
@ -933,6 +933,20 @@ fn cast_pointer_eq(p1: *mut u8, p2: *mut u32, p3: *mut u32, p4: *mut [u32]) {
|
|||
// CHECK: _0 = const ();
|
||||
}
|
||||
|
||||
unsafe fn aggregate_struct_then_transmute(id: u16) {
|
||||
// CHECK: opaque::<u16>(copy _1)
|
||||
let a = MyId(id);
|
||||
opaque(std::intrinsics::transmute::<_, u16>(a));
|
||||
|
||||
// GVN can't do this yet because it doesn't know which field is the ZST,
|
||||
// but future changes might enable it.
|
||||
// CHECK: [[AGG:_.+]] = TypedId::<String>(copy _1, const PhantomData::<String>);
|
||||
// CHECK: [[INT:_.+]] = copy [[AGG]] as u16 (Transmute);
|
||||
// CHECK: opaque::<u16>(move [[INT]])
|
||||
let b = TypedId::<String>(id, PhantomData);
|
||||
opaque(std::intrinsics::transmute::<_, u16>(b));
|
||||
}
|
||||
|
||||
// Transmuting can skip a pointer cast so long as it wasn't a fat-to-thin cast.
|
||||
unsafe fn cast_pointer_then_transmute(thin: *mut u32, fat: *mut [u8]) {
|
||||
// CHECK-LABEL: fn cast_pointer_then_transmute
|
||||
|
|
@ -946,6 +960,28 @@ unsafe fn cast_pointer_then_transmute(thin: *mut u32, fat: *mut [u8]) {
|
|||
let fat_addr: usize = std::intrinsics::transmute(fat as *const ());
|
||||
}
|
||||
|
||||
unsafe fn transmute_then_cast_pointer(addr: usize, fat: *mut [u8]) {
|
||||
// CHECK-LABEL: fn transmute_then_cast_pointer
|
||||
|
||||
// This is roughly what `NonNull::dangling` does
|
||||
// CHECK: [[CPTR:_.+]] = copy _1 as *const u8 (Transmute);
|
||||
// CHECK: takes_const_ptr::<u8>(move [[CPTR]])
|
||||
let p: *mut u8 = std::intrinsics::transmute(addr);
|
||||
takes_const_ptr(p);
|
||||
|
||||
// This cast is fat-to-thin, so can't be merged with the transmute
|
||||
// CHECK: [[FAT:_.+]] = move {{.+}} as *const [i32] (Transmute);
|
||||
// CHECK: [[THIN:_.+]] = copy [[FAT]] as *const i32 (PtrToPtr);
|
||||
// CHECK: takes_const_ptr::<i32>(move [[THIN]])
|
||||
let q = std::intrinsics::transmute::<&mut [i32], *const [i32]>(&mut [1, 2, 3]);
|
||||
takes_const_ptr(q as *const i32);
|
||||
|
||||
// CHECK: [[TPTR:_.+]] = copy _2 as *const u8 (PtrToPtr);
|
||||
// CHECK: takes_const_ptr::<u8>(move [[TPTR]])
|
||||
let w = std::intrinsics::transmute::<*mut [u8], *const [u8]>(fat);
|
||||
takes_const_ptr(w as *const u8);
|
||||
}
|
||||
|
||||
#[custom_mir(dialect = "analysis")]
|
||||
fn remove_casts_must_change_both_sides(mut_a: &*mut u8, mut_b: *mut u8) -> bool {
|
||||
// CHECK-LABEL: fn remove_casts_must_change_both_sides(
|
||||
|
|
@ -1002,6 +1038,16 @@ fn identity<T>(x: T) -> T {
|
|||
x
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn takes_const_ptr<T>(_: *const T) {}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[rustc_layout_scalar_valid_range_end(55555)]
|
||||
struct MyId(u16);
|
||||
|
||||
#[repr(transparent)]
|
||||
struct TypedId<T>(u16, PhantomData<T>);
|
||||
|
||||
// EMIT_MIR gvn.subexpression_elimination.GVN.diff
|
||||
// EMIT_MIR gvn.wrap_unwrap.GVN.diff
|
||||
// EMIT_MIR gvn.repeated_index.GVN.diff
|
||||
|
|
@ -1034,5 +1080,7 @@ fn identity<T>(x: T) -> T {
|
|||
// EMIT_MIR gvn.dedup_multiple_bounds_checks_lengths.GVN.diff
|
||||
// EMIT_MIR gvn.generic_cast_metadata.GVN.diff
|
||||
// EMIT_MIR gvn.cast_pointer_eq.GVN.diff
|
||||
// EMIT_MIR gvn.aggregate_struct_then_transmute.GVN.diff
|
||||
// EMIT_MIR gvn.cast_pointer_then_transmute.GVN.diff
|
||||
// EMIT_MIR gvn.transmute_then_cast_pointer.GVN.diff
|
||||
// EMIT_MIR gvn.remove_casts_must_change_both_sides.GVN.diff
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
- // MIR for `transmute_then_cast_pointer` before GVN
|
||||
+ // MIR for `transmute_then_cast_pointer` after GVN
|
||||
|
||||
fn transmute_then_cast_pointer(_1: usize, _2: *mut [u8]) -> () {
|
||||
debug addr => _1;
|
||||
debug fat => _2;
|
||||
let mut _0: ();
|
||||
let _3: *mut u8;
|
||||
let mut _4: usize;
|
||||
let _5: ();
|
||||
let mut _6: *const u8;
|
||||
let mut _7: *mut u8;
|
||||
let mut _9: &mut [i32];
|
||||
let mut _10: &mut [i32; 3];
|
||||
let mut _11: &mut [i32; 3];
|
||||
let mut _12: [i32; 3];
|
||||
let _13: ();
|
||||
let mut _14: *const i32;
|
||||
let mut _15: *const [i32];
|
||||
let mut _17: *mut [u8];
|
||||
let _18: ();
|
||||
let mut _19: *const u8;
|
||||
let mut _20: *const [u8];
|
||||
scope 1 {
|
||||
debug p => _3;
|
||||
let _8: *const [i32];
|
||||
scope 2 {
|
||||
debug q => _8;
|
||||
let _16: *const [u8];
|
||||
scope 3 {
|
||||
debug w => _16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_3);
|
||||
+ nop;
|
||||
StorageLive(_4);
|
||||
_4 = copy _1;
|
||||
- _3 = move _4 as *mut u8 (Transmute);
|
||||
+ _3 = copy _1 as *mut u8 (Transmute);
|
||||
StorageDead(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = copy _3;
|
||||
- _6 = move _7 as *const u8 (PtrToPtr);
|
||||
+ _6 = copy _1 as *const u8 (Transmute);
|
||||
StorageDead(_7);
|
||||
_5 = takes_const_ptr::<u8>(move _6) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
- StorageLive(_8);
|
||||
+ nop;
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
StorageLive(_12);
|
||||
_12 = [const 1_i32, const 2_i32, const 3_i32];
|
||||
_11 = &mut _12;
|
||||
_10 = &mut (*_11);
|
||||
_9 = move _10 as &mut [i32] (PointerCoercion(Unsize, Implicit));
|
||||
StorageDead(_10);
|
||||
_8 = move _9 as *const [i32] (Transmute);
|
||||
StorageDead(_9);
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
StorageLive(_15);
|
||||
_15 = copy _8;
|
||||
- _14 = move _15 as *const i32 (PtrToPtr);
|
||||
+ _14 = copy _8 as *const i32 (PtrToPtr);
|
||||
StorageDead(_15);
|
||||
_13 = takes_const_ptr::<i32>(move _14) -> [return: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_14);
|
||||
StorageDead(_13);
|
||||
- StorageLive(_16);
|
||||
+ nop;
|
||||
StorageLive(_17);
|
||||
_17 = copy _2;
|
||||
- _16 = move _17 as *const [u8] (Transmute);
|
||||
+ _16 = copy _2 as *const [u8] (PtrToPtr);
|
||||
StorageDead(_17);
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
StorageLive(_20);
|
||||
_20 = copy _16;
|
||||
- _19 = move _20 as *const u8 (PtrToPtr);
|
||||
+ _19 = copy _2 as *const u8 (PtrToPtr);
|
||||
StorageDead(_20);
|
||||
_18 = takes_const_ptr::<u8>(move _19) -> [return: bb3, unwind unreachable];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
_0 = const ();
|
||||
- StorageDead(_16);
|
||||
- StorageDead(_8);
|
||||
- StorageDead(_3);
|
||||
+ nop;
|
||||
+ nop;
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
- // MIR for `transmute_then_cast_pointer` before GVN
|
||||
+ // MIR for `transmute_then_cast_pointer` after GVN
|
||||
|
||||
fn transmute_then_cast_pointer(_1: usize, _2: *mut [u8]) -> () {
|
||||
debug addr => _1;
|
||||
debug fat => _2;
|
||||
let mut _0: ();
|
||||
let _3: *mut u8;
|
||||
let mut _4: usize;
|
||||
let _5: ();
|
||||
let mut _6: *const u8;
|
||||
let mut _7: *mut u8;
|
||||
let mut _9: &mut [i32];
|
||||
let mut _10: &mut [i32; 3];
|
||||
let mut _11: &mut [i32; 3];
|
||||
let mut _12: [i32; 3];
|
||||
let _13: ();
|
||||
let mut _14: *const i32;
|
||||
let mut _15: *const [i32];
|
||||
let mut _17: *mut [u8];
|
||||
let _18: ();
|
||||
let mut _19: *const u8;
|
||||
let mut _20: *const [u8];
|
||||
scope 1 {
|
||||
debug p => _3;
|
||||
let _8: *const [i32];
|
||||
scope 2 {
|
||||
debug q => _8;
|
||||
let _16: *const [u8];
|
||||
scope 3 {
|
||||
debug w => _16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_3);
|
||||
+ nop;
|
||||
StorageLive(_4);
|
||||
_4 = copy _1;
|
||||
- _3 = move _4 as *mut u8 (Transmute);
|
||||
+ _3 = copy _1 as *mut u8 (Transmute);
|
||||
StorageDead(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = copy _3;
|
||||
- _6 = move _7 as *const u8 (PtrToPtr);
|
||||
+ _6 = copy _1 as *const u8 (Transmute);
|
||||
StorageDead(_7);
|
||||
_5 = takes_const_ptr::<u8>(move _6) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
- StorageLive(_8);
|
||||
+ nop;
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
StorageLive(_12);
|
||||
_12 = [const 1_i32, const 2_i32, const 3_i32];
|
||||
_11 = &mut _12;
|
||||
_10 = &mut (*_11);
|
||||
_9 = move _10 as &mut [i32] (PointerCoercion(Unsize, Implicit));
|
||||
StorageDead(_10);
|
||||
_8 = move _9 as *const [i32] (Transmute);
|
||||
StorageDead(_9);
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
StorageLive(_15);
|
||||
_15 = copy _8;
|
||||
- _14 = move _15 as *const i32 (PtrToPtr);
|
||||
+ _14 = copy _8 as *const i32 (PtrToPtr);
|
||||
StorageDead(_15);
|
||||
_13 = takes_const_ptr::<i32>(move _14) -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_14);
|
||||
StorageDead(_13);
|
||||
- StorageLive(_16);
|
||||
+ nop;
|
||||
StorageLive(_17);
|
||||
_17 = copy _2;
|
||||
- _16 = move _17 as *const [u8] (Transmute);
|
||||
+ _16 = copy _2 as *const [u8] (PtrToPtr);
|
||||
StorageDead(_17);
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
StorageLive(_20);
|
||||
_20 = copy _16;
|
||||
- _19 = move _20 as *const u8 (PtrToPtr);
|
||||
+ _19 = copy _2 as *const u8 (PtrToPtr);
|
||||
StorageDead(_20);
|
||||
_18 = takes_const_ptr::<u8>(move _19) -> [return: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
_0 = const ();
|
||||
- StorageDead(_16);
|
||||
- StorageDead(_8);
|
||||
- StorageDead(_3);
|
||||
+ nop;
|
||||
+ nop;
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -11,10 +11,43 @@
|
|||
+ scope 1 (inlined std::ptr::drop_in_place::<Vec<A>> - shim(Some(Vec<A>))) {
|
||||
+ let mut _6: &mut std::vec::Vec<A>;
|
||||
+ let mut _7: ();
|
||||
+ scope 2 (inlined <Vec<A> as Drop>::drop) {
|
||||
+ let mut _8: *mut [A];
|
||||
+ let mut _9: *mut A;
|
||||
+ let mut _10: usize;
|
||||
+ scope 3 (inlined Vec::<A>::as_mut_ptr) {
|
||||
+ scope 4 (inlined alloc::raw_vec::RawVec::<A>::ptr) {
|
||||
+ scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<A>) {
|
||||
+ scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<A>) {
|
||||
+ let mut _11: std::ptr::NonNull<u8>;
|
||||
+ scope 7 (inlined Unique::<u8>::cast::<A>) {
|
||||
+ scope 8 (inlined NonNull::<u8>::cast::<A>) {
|
||||
+ scope 9 (inlined NonNull::<u8>::as_ptr) {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 10 (inlined Unique::<A>::as_non_null_ptr) {
|
||||
+ }
|
||||
+ }
|
||||
+ scope 11 (inlined NonNull::<A>::as_ptr) {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 12 (inlined slice_from_raw_parts_mut::<A>) {
|
||||
+ scope 13 (inlined std::ptr::from_raw_parts_mut::<[A], A>) {
|
||||
+ }
|
||||
+ }
|
||||
+ scope 14 (inlined std::ptr::drop_in_place::<[A]> - shim(Some([A]))) {
|
||||
+ let mut _12: usize;
|
||||
+ let mut _13: *mut A;
|
||||
+ let mut _14: bool;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 2 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
|
||||
+ let mut _8: isize;
|
||||
+ let mut _9: isize;
|
||||
+ scope 15 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
|
||||
+ let mut _15: isize;
|
||||
+ let mut _16: isize;
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
|
|
@ -25,7 +58,21 @@
|
|||
+ StorageLive(_6);
|
||||
+ StorageLive(_7);
|
||||
+ _6 = &mut (*_4);
|
||||
+ _7 = <Vec<A> as Drop>::drop(move _6) -> [return: bb2, unwind unreachable];
|
||||
+ StorageLive(_10);
|
||||
+ StorageLive(_8);
|
||||
+ StorageLive(_9);
|
||||
+ StorageLive(_11);
|
||||
+ _11 = copy (((((*_6).0: alloc::raw_vec::RawVec<A>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
|
||||
+ _9 = copy _11 as *mut A (Transmute);
|
||||
+ StorageDead(_11);
|
||||
+ _10 = copy ((*_6).1: usize);
|
||||
+ _8 = *mut [A] from (copy _9, copy _10);
|
||||
+ StorageDead(_9);
|
||||
+ StorageLive(_12);
|
||||
+ StorageLive(_13);
|
||||
+ StorageLive(_14);
|
||||
+ _12 = const 0_usize;
|
||||
+ goto -> bb4;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
@ -36,25 +83,41 @@
|
|||
StorageLive(_5);
|
||||
_5 = copy _2;
|
||||
- _0 = std::ptr::drop_in_place::<Option<B>>(move _5) -> [return: bb2, unwind unreachable];
|
||||
+ StorageLive(_8);
|
||||
+ StorageLive(_9);
|
||||
+ _8 = discriminant((*_5));
|
||||
+ switchInt(move _8) -> [0: bb3, otherwise: bb4];
|
||||
+ StorageLive(_15);
|
||||
+ StorageLive(_16);
|
||||
+ _15 = discriminant((*_5));
|
||||
+ switchInt(move _15) -> [0: bb5, otherwise: bb6];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
+ StorageDead(_14);
|
||||
+ StorageDead(_13);
|
||||
+ StorageDead(_12);
|
||||
+ StorageDead(_8);
|
||||
+ StorageDead(_10);
|
||||
+ drop(((*_4).0: alloc::raw_vec::RawVec<A>)) -> [return: bb1, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb3: {
|
||||
+ StorageDead(_9);
|
||||
+ StorageDead(_8);
|
||||
+ _13 = &raw mut (*_8)[_12];
|
||||
+ _12 = Add(move _12, const 1_usize);
|
||||
+ drop((*_13)) -> [return: bb4, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb4: {
|
||||
+ _14 = Eq(copy _12, copy _10);
|
||||
+ switchInt(move _14) -> [0: bb3, otherwise: bb2];
|
||||
+ }
|
||||
+
|
||||
+ bb5: {
|
||||
+ StorageDead(_16);
|
||||
+ StorageDead(_15);
|
||||
StorageDead(_5);
|
||||
return;
|
||||
+ }
|
||||
+
|
||||
+ bb4: {
|
||||
+ drop((((*_5) as Some).0: B)) -> [return: bb3, unwind unreachable];
|
||||
+ bb6: {
|
||||
+ drop((((*_5) as Some).0: B)) -> [return: bb5, unwind unreachable];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ fn b(_1: &mut Box<T>) -> &mut T {
|
|||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_5 = copy (*_4);
|
||||
_6 = copy (((_5.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T);
|
||||
_6 = copy ((_5.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>) as *const T (Transmute);
|
||||
_3 = &mut (*_6);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ fn d(_1: &Box<T>) -> &T {
|
|||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_4 = copy (*_3);
|
||||
_5 = copy (((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T);
|
||||
_5 = copy ((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>) as *const T (Transmute);
|
||||
_2 = &(*_5);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = move _1;
|
||||
_4 = copy (((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>).0: *const [i32]);
|
||||
_4 = copy ((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>) as *const [i32] (Transmute);
|
||||
_2 = callee(move (*_4)) -> [return: bb1, unwind: bb3];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,83 +0,0 @@
|
|||
- // MIR for `adt_transmutes` before InstSimplify-after-simplifycfg
|
||||
+ // MIR for `adt_transmutes` after InstSimplify-after-simplifycfg
|
||||
|
||||
fn adt_transmutes() -> () {
|
||||
let mut _0: ();
|
||||
let _1: u8;
|
||||
let mut _2: std::option::Option<std::num::NonZero<u8>>;
|
||||
let mut _4: std::num::Wrapping<i16>;
|
||||
let mut _6: std::num::Wrapping<i16>;
|
||||
let mut _8: Union32;
|
||||
let mut _10: Union32;
|
||||
let mut _12: std::mem::MaybeUninit<std::string::String>;
|
||||
scope 1 {
|
||||
debug _a => _1;
|
||||
let _3: i16;
|
||||
scope 2 {
|
||||
debug _a => _3;
|
||||
let _5: u16;
|
||||
scope 3 {
|
||||
debug _a => _5;
|
||||
let _7: u32;
|
||||
scope 4 {
|
||||
debug _a => _7;
|
||||
let _9: i32;
|
||||
scope 5 {
|
||||
debug _a => _9;
|
||||
let _11: std::mem::ManuallyDrop<std::string::String>;
|
||||
scope 6 {
|
||||
debug _a => _11;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
_2 = Option::<NonZero<u8>>::Some(const std::num::NonZero::<u8>::MAX);
|
||||
_1 = move _2 as u8 (Transmute);
|
||||
StorageDead(_2);
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = Wrapping::<i16>(const 0_i16);
|
||||
- _3 = move _4 as i16 (Transmute);
|
||||
+ _3 = move (_4.0: i16);
|
||||
StorageDead(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_6 = Wrapping::<i16>(const 0_i16);
|
||||
_5 = move _6 as u16 (Transmute);
|
||||
StorageDead(_6);
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
_8 = Union32 { u32: const 0_i32 };
|
||||
_7 = move _8 as u32 (Transmute);
|
||||
StorageDead(_8);
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
_10 = Union32 { u32: const 0_u32 };
|
||||
_9 = move _10 as i32 (Transmute);
|
||||
StorageDead(_10);
|
||||
StorageLive(_11);
|
||||
StorageLive(_12);
|
||||
_12 = MaybeUninit::<String>::uninit() -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _11 = move _12 as std::mem::ManuallyDrop<std::string::String> (Transmute);
|
||||
+ _11 = move (_12.1: std::mem::ManuallyDrop<std::string::String>);
|
||||
StorageDead(_12);
|
||||
_0 = const ();
|
||||
StorageDead(_11);
|
||||
StorageDead(_9);
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
StorageDead(_3);
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
- // MIR for `keep_transparent_transmute` before InstSimplify-after-simplifycfg
|
||||
+ // MIR for `keep_transparent_transmute` after InstSimplify-after-simplifycfg
|
||||
|
||||
fn keep_transparent_transmute() -> () {
|
||||
let mut _0: ();
|
||||
let _1: i16;
|
||||
let mut _3: std::num::Wrapping<i16>;
|
||||
scope 1 {
|
||||
debug _a => _1;
|
||||
let _2: i16;
|
||||
scope 2 {
|
||||
debug _a => _2;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = const keep_transparent_transmute::{constant#0} as i16 (Transmute);
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = Wrapping::<i16>(const 0_i16);
|
||||
_2 = move _3 as i16 (Transmute);
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -43,22 +43,19 @@ pub unsafe fn integer_transmutes() {
|
|||
}
|
||||
}
|
||||
|
||||
// EMIT_MIR combine_transmutes.adt_transmutes.InstSimplify-after-simplifycfg.diff
|
||||
pub unsafe fn adt_transmutes() {
|
||||
// CHECK-LABEL: fn adt_transmutes(
|
||||
// CHECK: as u8 (Transmute);
|
||||
// CHECK: ({{_.*}}.0: i16);
|
||||
// CHECK: as u16 (Transmute);
|
||||
// CHECK: as u32 (Transmute);
|
||||
// CHECK: as i32 (Transmute);
|
||||
// CHECK: ({{_.*}}.1: std::mem::ManuallyDrop<std::string::String>);
|
||||
// EMIT_MIR combine_transmutes.keep_transparent_transmute.InstSimplify-after-simplifycfg.diff
|
||||
pub unsafe fn keep_transparent_transmute() {
|
||||
// CHECK-LABEL: fn keep_transparent_transmute(
|
||||
// CHECK-NOT: .{{[0-9]+}}: i16
|
||||
// CHECK: as i16 (Transmute);
|
||||
// CHECK-NOT: .{{[0-9]+}}: i16
|
||||
// CHECK: as i16 (Transmute);
|
||||
// CHECK-NOT: .{{[0-9]+}}: i16
|
||||
|
||||
let _a: u8 = transmute(Some(std::num::NonZero::<u8>::MAX));
|
||||
// Transmutes should not be converted to field accesses, because MCP#807
|
||||
// bans projections into `[rustc_layout_scalar_valid_range_*]` types.
|
||||
let _a: i16 = transmute(const { std::num::NonZero::new(12345_i16).unwrap() });
|
||||
let _a: i16 = transmute(std::num::Wrapping(0_i16));
|
||||
let _a: u16 = transmute(std::num::Wrapping(0_i16));
|
||||
let _a: u32 = transmute(Union32 { i32: 0 });
|
||||
let _a: i32 = transmute(Union32 { u32: 0 });
|
||||
let _a: ManuallyDrop<String> = transmute(MaybeUninit::<String>::uninit());
|
||||
}
|
||||
|
||||
pub union Union32 {
|
||||
|
|
|
|||
|
|
@ -4,28 +4,28 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
debug slice => _1;
|
||||
debug f => _2;
|
||||
let mut _0: ();
|
||||
let mut _13: std::slice::Iter<'_, T>;
|
||||
let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
|
||||
let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
|
||||
let mut _23: std::option::Option<(usize, &T)>;
|
||||
let mut _26: &impl Fn(usize, &T);
|
||||
let mut _27: (usize, &T);
|
||||
let _28: ();
|
||||
let mut _11: std::slice::Iter<'_, T>;
|
||||
let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>;
|
||||
let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>;
|
||||
let mut _21: std::option::Option<(usize, &T)>;
|
||||
let mut _24: &impl Fn(usize, &T);
|
||||
let mut _25: (usize, &T);
|
||||
let _26: ();
|
||||
scope 1 {
|
||||
debug iter => _15;
|
||||
let _24: usize;
|
||||
let _25: &T;
|
||||
debug iter => _13;
|
||||
let _22: usize;
|
||||
let _23: &T;
|
||||
scope 2 {
|
||||
debug i => _24;
|
||||
debug x => _25;
|
||||
debug i => _22;
|
||||
debug x => _23;
|
||||
}
|
||||
scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
|
||||
let mut _16: &mut std::slice::Iter<'_, T>;
|
||||
let mut _17: std::option::Option<&T>;
|
||||
let mut _21: (usize, bool);
|
||||
let mut _22: (usize, &T);
|
||||
let mut _14: &mut std::slice::Iter<'_, T>;
|
||||
let mut _15: std::option::Option<&T>;
|
||||
let mut _19: (usize, bool);
|
||||
let mut _20: (usize, &T);
|
||||
scope 19 {
|
||||
let _20: usize;
|
||||
let _18: usize;
|
||||
scope 24 {
|
||||
}
|
||||
}
|
||||
|
|
@ -40,8 +40,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
}
|
||||
}
|
||||
scope 25 (inlined <Option<&T> as Try>::branch) {
|
||||
let mut _18: isize;
|
||||
let _19: &T;
|
||||
let mut _16: isize;
|
||||
let _17: &T;
|
||||
scope 26 {
|
||||
}
|
||||
}
|
||||
|
|
@ -50,14 +50,13 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
scope 3 (inlined core::slice::<impl [T]>::iter) {
|
||||
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
|
||||
let _3: usize;
|
||||
let mut _5: std::ptr::NonNull<[T]>;
|
||||
let mut _9: *mut T;
|
||||
let mut _10: *mut T;
|
||||
let mut _12: *const T;
|
||||
let mut _7: *mut T;
|
||||
let mut _8: *mut T;
|
||||
let mut _10: *const T;
|
||||
scope 5 {
|
||||
let _8: std::ptr::NonNull<T>;
|
||||
let _6: std::ptr::NonNull<T>;
|
||||
scope 6 {
|
||||
let _11: *const T;
|
||||
let _9: *const T;
|
||||
scope 7 {
|
||||
}
|
||||
scope 12 (inlined without_provenance::<T>) {
|
||||
|
|
@ -73,8 +72,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
}
|
||||
}
|
||||
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
let mut _6: *mut [T];
|
||||
let mut _7: *const T;
|
||||
let mut _5: *const T;
|
||||
scope 11 (inlined NonNull::<[T]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
|
|
@ -89,82 +87,74 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_13);
|
||||
StorageLive(_3);
|
||||
StorageLive(_8);
|
||||
_3 = PtrMetadata(copy _1);
|
||||
StorageLive(_5);
|
||||
StorageLive(_4);
|
||||
_4 = &raw const (*_1);
|
||||
_5 = NonNull::<[T]> { pointer: move _4 };
|
||||
StorageDead(_4);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_6 = copy _5 as *mut [T] (Transmute);
|
||||
_7 = copy _6 as *const T (PtrToPtr);
|
||||
_8 = NonNull::<T> { pointer: move _7 };
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageLive(_11);
|
||||
StorageLive(_3);
|
||||
StorageLive(_6);
|
||||
StorageLive(_5);
|
||||
_3 = PtrMetadata(copy _1);
|
||||
_4 = &raw const (*_1);
|
||||
_5 = copy _4 as *const T (PtrToPtr);
|
||||
_6 = NonNull::<T> { pointer: copy _5 };
|
||||
StorageLive(_9);
|
||||
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_10);
|
||||
StorageLive(_9);
|
||||
_9 = copy _8 as *mut T (Transmute);
|
||||
_10 = Offset(copy _9, copy _3);
|
||||
StorageDead(_9);
|
||||
_11 = move _10 as *const T (PtrToPtr);
|
||||
StorageDead(_10);
|
||||
StorageLive(_8);
|
||||
StorageLive(_7);
|
||||
_7 = copy _4 as *mut T (PtrToPtr);
|
||||
_8 = Offset(copy _7, copy _3);
|
||||
StorageDead(_7);
|
||||
_9 = move _8 as *const T (PtrToPtr);
|
||||
StorageDead(_8);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_11 = copy _3 as *const T (Transmute);
|
||||
_9 = copy _3 as *const T (Transmute);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageLive(_12);
|
||||
_12 = copy _11;
|
||||
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_8);
|
||||
StorageLive(_10);
|
||||
_10 = copy _9;
|
||||
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
StorageDead(_5);
|
||||
StorageDead(_6);
|
||||
StorageDead(_3);
|
||||
_14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
|
||||
StorageDead(_13);
|
||||
StorageLive(_15);
|
||||
_15 = copy _14;
|
||||
_12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
|
||||
StorageDead(_11);
|
||||
StorageLive(_13);
|
||||
_13 = copy _12;
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_23);
|
||||
StorageLive(_20);
|
||||
StorageLive(_21);
|
||||
StorageLive(_17);
|
||||
StorageLive(_16);
|
||||
_16 = &mut (_15.0: std::slice::Iter<'_, T>);
|
||||
_17 = <std::slice::Iter<'_, T> as Iterator>::next(move _16) -> [return: bb5, unwind unreachable];
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
StorageLive(_15);
|
||||
StorageLive(_14);
|
||||
_14 = &mut (_13.0: std::slice::Iter<'_, T>);
|
||||
_15 = <std::slice::Iter<'_, T> as Iterator>::next(move _14) -> [return: bb5, unwind unreachable];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_16);
|
||||
StorageLive(_18);
|
||||
_18 = discriminant(_17);
|
||||
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb11];
|
||||
StorageDead(_14);
|
||||
StorageLive(_16);
|
||||
_16 = discriminant(_15);
|
||||
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb11];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_18);
|
||||
StorageDead(_17);
|
||||
StorageDead(_21);
|
||||
StorageDead(_20);
|
||||
StorageDead(_23);
|
||||
StorageDead(_16);
|
||||
StorageDead(_15);
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageDead(_21);
|
||||
StorageDead(_13);
|
||||
drop(_2) -> [return: bb7, unwind unreachable];
|
||||
}
|
||||
|
||||
|
|
@ -173,35 +163,35 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
}
|
||||
|
||||
bb8: {
|
||||
_19 = move ((_17 as Some).0: &T);
|
||||
StorageDead(_18);
|
||||
StorageDead(_17);
|
||||
_20 = copy (_15.1: usize);
|
||||
_21 = AddWithOverflow(copy (_15.1: usize), const 1_usize);
|
||||
assert(!move (_21.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_15.1: usize), const 1_usize) -> [success: bb9, unwind unreachable];
|
||||
_17 = move ((_15 as Some).0: &T);
|
||||
StorageDead(_16);
|
||||
StorageDead(_15);
|
||||
_18 = copy (_13.1: usize);
|
||||
_19 = AddWithOverflow(copy (_13.1: usize), const 1_usize);
|
||||
assert(!move (_19.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_13.1: usize), const 1_usize) -> [success: bb9, unwind unreachable];
|
||||
}
|
||||
|
||||
bb9: {
|
||||
(_15.1: usize) = move (_21.0: usize);
|
||||
StorageLive(_22);
|
||||
_22 = (copy _20, copy _19);
|
||||
_23 = Option::<(usize, &T)>::Some(move _22);
|
||||
StorageDead(_22);
|
||||
StorageDead(_21);
|
||||
(_13.1: usize) = move (_19.0: usize);
|
||||
StorageLive(_20);
|
||||
_20 = (copy _18, copy _17);
|
||||
_21 = Option::<(usize, &T)>::Some(move _20);
|
||||
StorageDead(_20);
|
||||
_24 = copy (((_23 as Some).0: (usize, &T)).0: usize);
|
||||
_25 = copy (((_23 as Some).0: (usize, &T)).1: &T);
|
||||
StorageLive(_26);
|
||||
_26 = &_2;
|
||||
StorageLive(_27);
|
||||
_27 = (copy _24, copy _25);
|
||||
_28 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _26, move _27) -> [return: bb10, unwind unreachable];
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
_22 = copy (((_21 as Some).0: (usize, &T)).0: usize);
|
||||
_23 = copy (((_21 as Some).0: (usize, &T)).1: &T);
|
||||
StorageLive(_24);
|
||||
_24 = &_2;
|
||||
StorageLive(_25);
|
||||
_25 = (copy _22, copy _23);
|
||||
_26 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _24, move _25) -> [return: bb10, unwind unreachable];
|
||||
}
|
||||
|
||||
bb10: {
|
||||
StorageDead(_27);
|
||||
StorageDead(_26);
|
||||
StorageDead(_23);
|
||||
StorageDead(_25);
|
||||
StorageDead(_24);
|
||||
StorageDead(_21);
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,35 +4,34 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
debug slice => _1;
|
||||
debug f => _2;
|
||||
let mut _0: ();
|
||||
let mut _13: std::slice::Iter<'_, T>;
|
||||
let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
|
||||
let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
|
||||
let mut _16: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
|
||||
let mut _17: std::option::Option<(usize, &T)>;
|
||||
let mut _18: isize;
|
||||
let mut _21: &impl Fn(usize, &T);
|
||||
let mut _22: (usize, &T);
|
||||
let _23: ();
|
||||
let mut _11: std::slice::Iter<'_, T>;
|
||||
let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>;
|
||||
let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>;
|
||||
let mut _14: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
|
||||
let mut _15: std::option::Option<(usize, &T)>;
|
||||
let mut _16: isize;
|
||||
let mut _19: &impl Fn(usize, &T);
|
||||
let mut _20: (usize, &T);
|
||||
let _21: ();
|
||||
scope 1 {
|
||||
debug iter => _15;
|
||||
let _19: usize;
|
||||
let _20: &T;
|
||||
debug iter => _13;
|
||||
let _17: usize;
|
||||
let _18: &T;
|
||||
scope 2 {
|
||||
debug i => _19;
|
||||
debug x => _20;
|
||||
debug i => _17;
|
||||
debug x => _18;
|
||||
}
|
||||
}
|
||||
scope 3 (inlined core::slice::<impl [T]>::iter) {
|
||||
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
|
||||
let _3: usize;
|
||||
let mut _5: std::ptr::NonNull<[T]>;
|
||||
let mut _9: *mut T;
|
||||
let mut _10: *mut T;
|
||||
let mut _12: *const T;
|
||||
let mut _7: *mut T;
|
||||
let mut _8: *mut T;
|
||||
let mut _10: *const T;
|
||||
scope 5 {
|
||||
let _8: std::ptr::NonNull<T>;
|
||||
let _6: std::ptr::NonNull<T>;
|
||||
scope 6 {
|
||||
let _11: *const T;
|
||||
let _9: *const T;
|
||||
scope 7 {
|
||||
}
|
||||
scope 12 (inlined without_provenance::<T>) {
|
||||
|
|
@ -48,8 +47,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
}
|
||||
}
|
||||
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
let mut _6: *mut [T];
|
||||
let mut _7: *const T;
|
||||
let mut _5: *const T;
|
||||
scope 11 (inlined NonNull::<[T]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
|
|
@ -64,72 +62,64 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_13);
|
||||
StorageLive(_3);
|
||||
StorageLive(_8);
|
||||
_3 = PtrMetadata(copy _1);
|
||||
StorageLive(_5);
|
||||
StorageLive(_4);
|
||||
_4 = &raw const (*_1);
|
||||
_5 = NonNull::<[T]> { pointer: move _4 };
|
||||
StorageDead(_4);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_6 = copy _5 as *mut [T] (Transmute);
|
||||
_7 = copy _6 as *const T (PtrToPtr);
|
||||
_8 = NonNull::<T> { pointer: move _7 };
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageLive(_11);
|
||||
StorageLive(_3);
|
||||
StorageLive(_6);
|
||||
StorageLive(_5);
|
||||
_3 = PtrMetadata(copy _1);
|
||||
_4 = &raw const (*_1);
|
||||
_5 = copy _4 as *const T (PtrToPtr);
|
||||
_6 = NonNull::<T> { pointer: copy _5 };
|
||||
StorageLive(_9);
|
||||
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_10);
|
||||
StorageLive(_9);
|
||||
_9 = copy _8 as *mut T (Transmute);
|
||||
_10 = Offset(copy _9, copy _3);
|
||||
StorageDead(_9);
|
||||
_11 = move _10 as *const T (PtrToPtr);
|
||||
StorageDead(_10);
|
||||
StorageLive(_8);
|
||||
StorageLive(_7);
|
||||
_7 = copy _4 as *mut T (PtrToPtr);
|
||||
_8 = Offset(copy _7, copy _3);
|
||||
StorageDead(_7);
|
||||
_9 = move _8 as *const T (PtrToPtr);
|
||||
StorageDead(_8);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_11 = copy _3 as *const T (Transmute);
|
||||
_9 = copy _3 as *const T (Transmute);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageLive(_12);
|
||||
_12 = copy _11;
|
||||
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_8);
|
||||
StorageLive(_10);
|
||||
_10 = copy _9;
|
||||
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
StorageDead(_5);
|
||||
StorageDead(_6);
|
||||
StorageDead(_3);
|
||||
_14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
|
||||
StorageDead(_13);
|
||||
StorageLive(_15);
|
||||
_15 = copy _14;
|
||||
_12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
|
||||
StorageDead(_11);
|
||||
StorageLive(_13);
|
||||
_13 = copy _12;
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_17);
|
||||
_16 = &mut _15;
|
||||
_17 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _16) -> [return: bb5, unwind: bb11];
|
||||
StorageLive(_15);
|
||||
_14 = &mut _13;
|
||||
_15 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _14) -> [return: bb5, unwind: bb11];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
_18 = discriminant(_17);
|
||||
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
|
||||
_16 = discriminant(_15);
|
||||
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_17);
|
||||
StorageDead(_15);
|
||||
StorageDead(_13);
|
||||
drop(_2) -> [return: bb7, unwind continue];
|
||||
}
|
||||
|
||||
|
|
@ -138,19 +128,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
}
|
||||
|
||||
bb8: {
|
||||
_19 = copy (((_17 as Some).0: (usize, &T)).0: usize);
|
||||
_20 = copy (((_17 as Some).0: (usize, &T)).1: &T);
|
||||
StorageLive(_21);
|
||||
_21 = &_2;
|
||||
StorageLive(_22);
|
||||
_22 = (copy _19, copy _20);
|
||||
_23 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _21, move _22) -> [return: bb9, unwind: bb11];
|
||||
_17 = copy (((_15 as Some).0: (usize, &T)).0: usize);
|
||||
_18 = copy (((_15 as Some).0: (usize, &T)).1: &T);
|
||||
StorageLive(_19);
|
||||
_19 = &_2;
|
||||
StorageLive(_20);
|
||||
_20 = (copy _17, copy _18);
|
||||
_21 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_22);
|
||||
StorageDead(_21);
|
||||
StorageDead(_17);
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageDead(_15);
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,32 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
debug slice => _1;
|
||||
debug f => _2;
|
||||
let mut _0: ();
|
||||
let mut _13: std::slice::Iter<'_, T>;
|
||||
let mut _14: std::slice::Iter<'_, T>;
|
||||
let mut _15: &mut std::slice::Iter<'_, T>;
|
||||
let mut _16: std::option::Option<&T>;
|
||||
let mut _17: isize;
|
||||
let mut _19: &impl Fn(&T);
|
||||
let mut _20: (&T,);
|
||||
let _21: ();
|
||||
let mut _11: std::slice::Iter<'_, T>;
|
||||
let mut _12: std::slice::Iter<'_, T>;
|
||||
let mut _13: &mut std::slice::Iter<'_, T>;
|
||||
let mut _14: std::option::Option<&T>;
|
||||
let mut _15: isize;
|
||||
let mut _17: &impl Fn(&T);
|
||||
let mut _18: (&T,);
|
||||
let _19: ();
|
||||
scope 1 {
|
||||
debug iter => _14;
|
||||
let _18: &T;
|
||||
debug iter => _12;
|
||||
let _16: &T;
|
||||
scope 2 {
|
||||
debug x => _18;
|
||||
debug x => _16;
|
||||
}
|
||||
}
|
||||
scope 3 (inlined core::slice::<impl [T]>::iter) {
|
||||
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
|
||||
let _3: usize;
|
||||
let mut _5: std::ptr::NonNull<[T]>;
|
||||
let mut _9: *mut T;
|
||||
let mut _10: *mut T;
|
||||
let mut _12: *const T;
|
||||
let mut _7: *mut T;
|
||||
let mut _8: *mut T;
|
||||
let mut _10: *const T;
|
||||
scope 5 {
|
||||
let _8: std::ptr::NonNull<T>;
|
||||
let _6: std::ptr::NonNull<T>;
|
||||
scope 6 {
|
||||
let _11: *const T;
|
||||
let _9: *const T;
|
||||
scope 7 {
|
||||
}
|
||||
scope 12 (inlined without_provenance::<T>) {
|
||||
|
|
@ -45,8 +44,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
}
|
||||
}
|
||||
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
let mut _6: *mut [T];
|
||||
let mut _7: *const T;
|
||||
let mut _5: *const T;
|
||||
scope 11 (inlined NonNull::<[T]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
|
|
@ -58,68 +56,60 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
StorageLive(_8);
|
||||
_3 = PtrMetadata(copy _1);
|
||||
StorageLive(_5);
|
||||
StorageLive(_4);
|
||||
_4 = &raw const (*_1);
|
||||
_5 = NonNull::<[T]> { pointer: move _4 };
|
||||
StorageDead(_4);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_6 = copy _5 as *mut [T] (Transmute);
|
||||
_7 = copy _6 as *const T (PtrToPtr);
|
||||
_8 = NonNull::<T> { pointer: move _7 };
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageLive(_11);
|
||||
StorageLive(_5);
|
||||
_3 = PtrMetadata(copy _1);
|
||||
_4 = &raw const (*_1);
|
||||
_5 = copy _4 as *const T (PtrToPtr);
|
||||
_6 = NonNull::<T> { pointer: copy _5 };
|
||||
StorageLive(_9);
|
||||
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_10);
|
||||
StorageLive(_9);
|
||||
_9 = copy _8 as *mut T (Transmute);
|
||||
_10 = Offset(copy _9, copy _3);
|
||||
StorageDead(_9);
|
||||
_11 = move _10 as *const T (PtrToPtr);
|
||||
StorageDead(_10);
|
||||
StorageLive(_8);
|
||||
StorageLive(_7);
|
||||
_7 = copy _4 as *mut T (PtrToPtr);
|
||||
_8 = Offset(copy _7, copy _3);
|
||||
StorageDead(_7);
|
||||
_9 = move _8 as *const T (PtrToPtr);
|
||||
StorageDead(_8);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_11 = copy _3 as *const T (Transmute);
|
||||
_9 = copy _3 as *const T (Transmute);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageLive(_10);
|
||||
_10 = copy _9;
|
||||
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
StorageDead(_5);
|
||||
StorageDead(_6);
|
||||
StorageDead(_3);
|
||||
StorageLive(_12);
|
||||
_12 = copy _11;
|
||||
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_8);
|
||||
StorageDead(_3);
|
||||
StorageLive(_14);
|
||||
_14 = copy _13;
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_16);
|
||||
_15 = &mut _14;
|
||||
_16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind unreachable];
|
||||
StorageLive(_14);
|
||||
_13 = &mut _12;
|
||||
_14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind unreachable];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
_17 = discriminant(_16);
|
||||
switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
|
||||
_15 = discriminant(_14);
|
||||
switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_16);
|
||||
StorageDead(_14);
|
||||
StorageDead(_12);
|
||||
drop(_2) -> [return: bb7, unwind unreachable];
|
||||
}
|
||||
|
||||
|
|
@ -128,18 +118,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
}
|
||||
|
||||
bb8: {
|
||||
_18 = copy ((_16 as Some).0: &T);
|
||||
StorageLive(_19);
|
||||
_19 = &_2;
|
||||
StorageLive(_20);
|
||||
_20 = (copy _18,);
|
||||
_21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind unreachable];
|
||||
_16 = copy ((_14 as Some).0: &T);
|
||||
StorageLive(_17);
|
||||
_17 = &_2;
|
||||
StorageLive(_18);
|
||||
_18 = (copy _16,);
|
||||
_19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind unreachable];
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageDead(_16);
|
||||
StorageDead(_18);
|
||||
StorageDead(_17);
|
||||
StorageDead(_14);
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,32 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
debug slice => _1;
|
||||
debug f => _2;
|
||||
let mut _0: ();
|
||||
let mut _13: std::slice::Iter<'_, T>;
|
||||
let mut _14: std::slice::Iter<'_, T>;
|
||||
let mut _15: &mut std::slice::Iter<'_, T>;
|
||||
let mut _16: std::option::Option<&T>;
|
||||
let mut _17: isize;
|
||||
let mut _19: &impl Fn(&T);
|
||||
let mut _20: (&T,);
|
||||
let _21: ();
|
||||
let mut _11: std::slice::Iter<'_, T>;
|
||||
let mut _12: std::slice::Iter<'_, T>;
|
||||
let mut _13: &mut std::slice::Iter<'_, T>;
|
||||
let mut _14: std::option::Option<&T>;
|
||||
let mut _15: isize;
|
||||
let mut _17: &impl Fn(&T);
|
||||
let mut _18: (&T,);
|
||||
let _19: ();
|
||||
scope 1 {
|
||||
debug iter => _14;
|
||||
let _18: &T;
|
||||
debug iter => _12;
|
||||
let _16: &T;
|
||||
scope 2 {
|
||||
debug x => _18;
|
||||
debug x => _16;
|
||||
}
|
||||
}
|
||||
scope 3 (inlined core::slice::<impl [T]>::iter) {
|
||||
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
|
||||
let _3: usize;
|
||||
let mut _5: std::ptr::NonNull<[T]>;
|
||||
let mut _9: *mut T;
|
||||
let mut _10: *mut T;
|
||||
let mut _12: *const T;
|
||||
let mut _7: *mut T;
|
||||
let mut _8: *mut T;
|
||||
let mut _10: *const T;
|
||||
scope 5 {
|
||||
let _8: std::ptr::NonNull<T>;
|
||||
let _6: std::ptr::NonNull<T>;
|
||||
scope 6 {
|
||||
let _11: *const T;
|
||||
let _9: *const T;
|
||||
scope 7 {
|
||||
}
|
||||
scope 12 (inlined without_provenance::<T>) {
|
||||
|
|
@ -45,8 +44,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
}
|
||||
}
|
||||
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
let mut _6: *mut [T];
|
||||
let mut _7: *const T;
|
||||
let mut _5: *const T;
|
||||
scope 11 (inlined NonNull::<[T]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
|
|
@ -58,68 +56,60 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
StorageLive(_8);
|
||||
_3 = PtrMetadata(copy _1);
|
||||
StorageLive(_5);
|
||||
StorageLive(_4);
|
||||
_4 = &raw const (*_1);
|
||||
_5 = NonNull::<[T]> { pointer: move _4 };
|
||||
StorageDead(_4);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_6 = copy _5 as *mut [T] (Transmute);
|
||||
_7 = copy _6 as *const T (PtrToPtr);
|
||||
_8 = NonNull::<T> { pointer: move _7 };
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageLive(_11);
|
||||
StorageLive(_5);
|
||||
_3 = PtrMetadata(copy _1);
|
||||
_4 = &raw const (*_1);
|
||||
_5 = copy _4 as *const T (PtrToPtr);
|
||||
_6 = NonNull::<T> { pointer: copy _5 };
|
||||
StorageLive(_9);
|
||||
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_10);
|
||||
StorageLive(_9);
|
||||
_9 = copy _8 as *mut T (Transmute);
|
||||
_10 = Offset(copy _9, copy _3);
|
||||
StorageDead(_9);
|
||||
_11 = move _10 as *const T (PtrToPtr);
|
||||
StorageDead(_10);
|
||||
StorageLive(_8);
|
||||
StorageLive(_7);
|
||||
_7 = copy _4 as *mut T (PtrToPtr);
|
||||
_8 = Offset(copy _7, copy _3);
|
||||
StorageDead(_7);
|
||||
_9 = move _8 as *const T (PtrToPtr);
|
||||
StorageDead(_8);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_11 = copy _3 as *const T (Transmute);
|
||||
_9 = copy _3 as *const T (Transmute);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageLive(_10);
|
||||
_10 = copy _9;
|
||||
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
StorageDead(_5);
|
||||
StorageDead(_6);
|
||||
StorageDead(_3);
|
||||
StorageLive(_12);
|
||||
_12 = copy _11;
|
||||
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_8);
|
||||
StorageDead(_3);
|
||||
StorageLive(_14);
|
||||
_14 = copy _13;
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_16);
|
||||
_15 = &mut _14;
|
||||
_16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind: bb11];
|
||||
StorageLive(_14);
|
||||
_13 = &mut _12;
|
||||
_14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind: bb11];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
_17 = discriminant(_16);
|
||||
switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
|
||||
_15 = discriminant(_14);
|
||||
switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_16);
|
||||
StorageDead(_14);
|
||||
StorageDead(_12);
|
||||
drop(_2) -> [return: bb7, unwind continue];
|
||||
}
|
||||
|
||||
|
|
@ -128,18 +118,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
}
|
||||
|
||||
bb8: {
|
||||
_18 = copy ((_16 as Some).0: &T);
|
||||
StorageLive(_19);
|
||||
_19 = &_2;
|
||||
StorageLive(_20);
|
||||
_20 = (copy _18,);
|
||||
_21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
|
||||
_16 = copy ((_14 as Some).0: &T);
|
||||
StorageLive(_17);
|
||||
_17 = &_2;
|
||||
StorageLive(_18);
|
||||
_18 = (copy _16,);
|
||||
_19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind: bb11];
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageDead(_16);
|
||||
StorageDead(_18);
|
||||
StorageDead(_17);
|
||||
StorageDead(_14);
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,35 +4,34 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
debug slice => _1;
|
||||
debug f => _2;
|
||||
let mut _0: ();
|
||||
let mut _13: std::slice::Iter<'_, T>;
|
||||
let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
|
||||
let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
|
||||
let mut _17: std::option::Option<&T>;
|
||||
let mut _18: isize;
|
||||
let mut _20: &impl Fn(&T);
|
||||
let mut _21: (&T,);
|
||||
let _22: ();
|
||||
let mut _11: std::slice::Iter<'_, T>;
|
||||
let mut _12: std::iter::Rev<std::slice::Iter<'_, T>>;
|
||||
let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>;
|
||||
let mut _15: std::option::Option<&T>;
|
||||
let mut _16: isize;
|
||||
let mut _18: &impl Fn(&T);
|
||||
let mut _19: (&T,);
|
||||
let _20: ();
|
||||
scope 1 {
|
||||
debug iter => _15;
|
||||
let _19: &T;
|
||||
debug iter => _13;
|
||||
let _17: &T;
|
||||
scope 2 {
|
||||
debug x => _19;
|
||||
debug x => _17;
|
||||
}
|
||||
scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
|
||||
let mut _16: &mut std::slice::Iter<'_, T>;
|
||||
let mut _14: &mut std::slice::Iter<'_, T>;
|
||||
}
|
||||
}
|
||||
scope 3 (inlined core::slice::<impl [T]>::iter) {
|
||||
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
|
||||
let _3: usize;
|
||||
let mut _5: std::ptr::NonNull<[T]>;
|
||||
let mut _9: *mut T;
|
||||
let mut _10: *mut T;
|
||||
let mut _12: *const T;
|
||||
let mut _7: *mut T;
|
||||
let mut _8: *mut T;
|
||||
let mut _10: *const T;
|
||||
scope 5 {
|
||||
let _8: std::ptr::NonNull<T>;
|
||||
let _6: std::ptr::NonNull<T>;
|
||||
scope 6 {
|
||||
let _11: *const T;
|
||||
let _9: *const T;
|
||||
scope 7 {
|
||||
}
|
||||
scope 12 (inlined without_provenance::<T>) {
|
||||
|
|
@ -48,8 +47,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
}
|
||||
}
|
||||
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
let mut _6: *mut [T];
|
||||
let mut _7: *const T;
|
||||
let mut _5: *const T;
|
||||
scope 11 (inlined NonNull::<[T]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
|
|
@ -64,74 +62,66 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_13);
|
||||
StorageLive(_3);
|
||||
StorageLive(_8);
|
||||
_3 = PtrMetadata(copy _1);
|
||||
StorageLive(_5);
|
||||
StorageLive(_4);
|
||||
_4 = &raw const (*_1);
|
||||
_5 = NonNull::<[T]> { pointer: move _4 };
|
||||
StorageDead(_4);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_6 = copy _5 as *mut [T] (Transmute);
|
||||
_7 = copy _6 as *const T (PtrToPtr);
|
||||
_8 = NonNull::<T> { pointer: move _7 };
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageLive(_11);
|
||||
StorageLive(_3);
|
||||
StorageLive(_6);
|
||||
StorageLive(_5);
|
||||
_3 = PtrMetadata(copy _1);
|
||||
_4 = &raw const (*_1);
|
||||
_5 = copy _4 as *const T (PtrToPtr);
|
||||
_6 = NonNull::<T> { pointer: copy _5 };
|
||||
StorageLive(_9);
|
||||
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_10);
|
||||
StorageLive(_9);
|
||||
_9 = copy _8 as *mut T (Transmute);
|
||||
_10 = Offset(copy _9, copy _3);
|
||||
StorageDead(_9);
|
||||
_11 = move _10 as *const T (PtrToPtr);
|
||||
StorageDead(_10);
|
||||
StorageLive(_8);
|
||||
StorageLive(_7);
|
||||
_7 = copy _4 as *mut T (PtrToPtr);
|
||||
_8 = Offset(copy _7, copy _3);
|
||||
StorageDead(_7);
|
||||
_9 = move _8 as *const T (PtrToPtr);
|
||||
StorageDead(_8);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_11 = copy _3 as *const T (Transmute);
|
||||
_9 = copy _3 as *const T (Transmute);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageLive(_12);
|
||||
_12 = copy _11;
|
||||
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_8);
|
||||
StorageLive(_10);
|
||||
_10 = copy _9;
|
||||
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
StorageDead(_5);
|
||||
StorageDead(_6);
|
||||
StorageDead(_3);
|
||||
_14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 };
|
||||
StorageDead(_13);
|
||||
StorageLive(_15);
|
||||
_15 = copy _14;
|
||||
_12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 };
|
||||
StorageDead(_11);
|
||||
StorageLive(_13);
|
||||
_13 = copy _12;
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_17);
|
||||
StorageLive(_16);
|
||||
_16 = &mut (_15.0: std::slice::Iter<'_, T>);
|
||||
_17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind unreachable];
|
||||
StorageLive(_15);
|
||||
StorageLive(_14);
|
||||
_14 = &mut (_13.0: std::slice::Iter<'_, T>);
|
||||
_15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_16);
|
||||
_18 = discriminant(_17);
|
||||
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
|
||||
StorageDead(_14);
|
||||
_16 = discriminant(_15);
|
||||
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_17);
|
||||
StorageDead(_15);
|
||||
StorageDead(_13);
|
||||
drop(_2) -> [return: bb7, unwind unreachable];
|
||||
}
|
||||
|
||||
|
|
@ -140,18 +130,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
}
|
||||
|
||||
bb8: {
|
||||
_19 = copy ((_17 as Some).0: &T);
|
||||
StorageLive(_20);
|
||||
_20 = &_2;
|
||||
StorageLive(_21);
|
||||
_21 = (copy _19,);
|
||||
_22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind unreachable];
|
||||
_17 = copy ((_15 as Some).0: &T);
|
||||
StorageLive(_18);
|
||||
_18 = &_2;
|
||||
StorageLive(_19);
|
||||
_19 = (copy _17,);
|
||||
_20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind unreachable];
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_21);
|
||||
StorageDead(_20);
|
||||
StorageDead(_17);
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageDead(_15);
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,35 +4,34 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
debug slice => _1;
|
||||
debug f => _2;
|
||||
let mut _0: ();
|
||||
let mut _13: std::slice::Iter<'_, T>;
|
||||
let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
|
||||
let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
|
||||
let mut _17: std::option::Option<&T>;
|
||||
let mut _18: isize;
|
||||
let mut _20: &impl Fn(&T);
|
||||
let mut _21: (&T,);
|
||||
let _22: ();
|
||||
let mut _11: std::slice::Iter<'_, T>;
|
||||
let mut _12: std::iter::Rev<std::slice::Iter<'_, T>>;
|
||||
let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>;
|
||||
let mut _15: std::option::Option<&T>;
|
||||
let mut _16: isize;
|
||||
let mut _18: &impl Fn(&T);
|
||||
let mut _19: (&T,);
|
||||
let _20: ();
|
||||
scope 1 {
|
||||
debug iter => _15;
|
||||
let _19: &T;
|
||||
debug iter => _13;
|
||||
let _17: &T;
|
||||
scope 2 {
|
||||
debug x => _19;
|
||||
debug x => _17;
|
||||
}
|
||||
scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
|
||||
let mut _16: &mut std::slice::Iter<'_, T>;
|
||||
let mut _14: &mut std::slice::Iter<'_, T>;
|
||||
}
|
||||
}
|
||||
scope 3 (inlined core::slice::<impl [T]>::iter) {
|
||||
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
|
||||
let _3: usize;
|
||||
let mut _5: std::ptr::NonNull<[T]>;
|
||||
let mut _9: *mut T;
|
||||
let mut _10: *mut T;
|
||||
let mut _12: *const T;
|
||||
let mut _7: *mut T;
|
||||
let mut _8: *mut T;
|
||||
let mut _10: *const T;
|
||||
scope 5 {
|
||||
let _8: std::ptr::NonNull<T>;
|
||||
let _6: std::ptr::NonNull<T>;
|
||||
scope 6 {
|
||||
let _11: *const T;
|
||||
let _9: *const T;
|
||||
scope 7 {
|
||||
}
|
||||
scope 12 (inlined without_provenance::<T>) {
|
||||
|
|
@ -48,8 +47,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
}
|
||||
}
|
||||
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
let mut _6: *mut [T];
|
||||
let mut _7: *const T;
|
||||
let mut _5: *const T;
|
||||
scope 11 (inlined NonNull::<[T]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
|
|
@ -64,74 +62,66 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_13);
|
||||
StorageLive(_3);
|
||||
StorageLive(_8);
|
||||
_3 = PtrMetadata(copy _1);
|
||||
StorageLive(_5);
|
||||
StorageLive(_4);
|
||||
_4 = &raw const (*_1);
|
||||
_5 = NonNull::<[T]> { pointer: move _4 };
|
||||
StorageDead(_4);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_6 = copy _5 as *mut [T] (Transmute);
|
||||
_7 = copy _6 as *const T (PtrToPtr);
|
||||
_8 = NonNull::<T> { pointer: move _7 };
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageLive(_11);
|
||||
StorageLive(_3);
|
||||
StorageLive(_6);
|
||||
StorageLive(_5);
|
||||
_3 = PtrMetadata(copy _1);
|
||||
_4 = &raw const (*_1);
|
||||
_5 = copy _4 as *const T (PtrToPtr);
|
||||
_6 = NonNull::<T> { pointer: copy _5 };
|
||||
StorageLive(_9);
|
||||
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_10);
|
||||
StorageLive(_9);
|
||||
_9 = copy _8 as *mut T (Transmute);
|
||||
_10 = Offset(copy _9, copy _3);
|
||||
StorageDead(_9);
|
||||
_11 = move _10 as *const T (PtrToPtr);
|
||||
StorageDead(_10);
|
||||
StorageLive(_8);
|
||||
StorageLive(_7);
|
||||
_7 = copy _4 as *mut T (PtrToPtr);
|
||||
_8 = Offset(copy _7, copy _3);
|
||||
StorageDead(_7);
|
||||
_9 = move _8 as *const T (PtrToPtr);
|
||||
StorageDead(_8);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_11 = copy _3 as *const T (Transmute);
|
||||
_9 = copy _3 as *const T (Transmute);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageLive(_12);
|
||||
_12 = copy _11;
|
||||
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_8);
|
||||
StorageLive(_10);
|
||||
_10 = copy _9;
|
||||
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
StorageDead(_5);
|
||||
StorageDead(_6);
|
||||
StorageDead(_3);
|
||||
_14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 };
|
||||
StorageDead(_13);
|
||||
StorageLive(_15);
|
||||
_15 = copy _14;
|
||||
_12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 };
|
||||
StorageDead(_11);
|
||||
StorageLive(_13);
|
||||
_13 = copy _12;
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_17);
|
||||
StorageLive(_16);
|
||||
_16 = &mut (_15.0: std::slice::Iter<'_, T>);
|
||||
_17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind: bb11];
|
||||
StorageLive(_15);
|
||||
StorageLive(_14);
|
||||
_14 = &mut (_13.0: std::slice::Iter<'_, T>);
|
||||
_15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_16);
|
||||
_18 = discriminant(_17);
|
||||
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
|
||||
StorageDead(_14);
|
||||
_16 = discriminant(_15);
|
||||
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_17);
|
||||
StorageDead(_15);
|
||||
StorageDead(_13);
|
||||
drop(_2) -> [return: bb7, unwind continue];
|
||||
}
|
||||
|
||||
|
|
@ -140,18 +130,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||
}
|
||||
|
||||
bb8: {
|
||||
_19 = copy ((_17 as Some).0: &T);
|
||||
StorageLive(_20);
|
||||
_20 = &_2;
|
||||
StorageLive(_21);
|
||||
_21 = (copy _19,);
|
||||
_22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind: bb11];
|
||||
_17 = copy ((_15 as Some).0: &T);
|
||||
StorageLive(_18);
|
||||
_18 = &_2;
|
||||
StorageLive(_19);
|
||||
_19 = (copy _17,);
|
||||
_20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind: bb11];
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_21);
|
||||
StorageDead(_20);
|
||||
StorageDead(_17);
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageDead(_15);
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,20 +7,16 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
|||
debug self => _1;
|
||||
scope 2 (inlined Vec::<u8>::as_slice) {
|
||||
debug self => _1;
|
||||
let mut _7: *const u8;
|
||||
let mut _8: usize;
|
||||
let mut _3: *const u8;
|
||||
let mut _4: usize;
|
||||
scope 3 (inlined Vec::<u8>::as_ptr) {
|
||||
debug self => _1;
|
||||
let mut _6: *mut u8;
|
||||
scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
|
||||
scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
|
||||
let mut _5: std::ptr::NonNull<u8>;
|
||||
scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
|
||||
let mut _2: std::ptr::NonNull<u8>;
|
||||
scope 7 (inlined Unique::<u8>::cast::<u8>) {
|
||||
scope 8 (inlined NonNull::<u8>::cast::<u8>) {
|
||||
let mut _3: *mut u8;
|
||||
let mut _4: *const u8;
|
||||
scope 9 (inlined NonNull::<u8>::as_ptr) {
|
||||
}
|
||||
}
|
||||
|
|
@ -34,9 +30,9 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
|||
}
|
||||
}
|
||||
scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
|
||||
debug data => _7;
|
||||
debug len => _8;
|
||||
let _9: *const [u8];
|
||||
debug data => _3;
|
||||
debug len => _4;
|
||||
let _5: *const [u8];
|
||||
scope 13 (inlined core::ub_checks::check_language_ub) {
|
||||
scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
}
|
||||
|
|
@ -46,10 +42,10 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
|||
scope 16 (inlined align_of::<u8>) {
|
||||
}
|
||||
scope 17 (inlined slice_from_raw_parts::<u8>) {
|
||||
debug data => _7;
|
||||
debug len => _8;
|
||||
debug data => _3;
|
||||
debug len => _4;
|
||||
scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
|
||||
debug data_pointer => _7;
|
||||
debug data_pointer => _3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -57,31 +53,19 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
|||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
StorageLive(_5);
|
||||
StorageLive(_2);
|
||||
_2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
|
||||
StorageLive(_3);
|
||||
_2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
|
||||
_3 = copy _2 as *const u8 (Transmute);
|
||||
StorageLive(_4);
|
||||
_3 = copy _2 as *mut u8 (Transmute);
|
||||
_4 = copy _3 as *const u8 (PtrToPtr);
|
||||
_5 = NonNull::<u8> { pointer: move _4 };
|
||||
_4 = copy ((*_1).1: usize);
|
||||
StorageLive(_5);
|
||||
_5 = *const [u8] from (copy _3, copy _4);
|
||||
_0 = &(*_5);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
StorageDead(_2);
|
||||
_6 = copy _5 as *mut u8 (Transmute);
|
||||
StorageDead(_5);
|
||||
_7 = copy _6 as *const u8 (PtrToPtr);
|
||||
StorageLive(_8);
|
||||
_8 = copy ((*_1).1: usize);
|
||||
StorageLive(_9);
|
||||
_9 = *const [u8] from (copy _7, copy _8);
|
||||
_0 = &(*_9);
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,16 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
|||
debug self => _1;
|
||||
scope 2 (inlined Vec::<u8>::as_slice) {
|
||||
debug self => _1;
|
||||
let mut _7: *const u8;
|
||||
let mut _8: usize;
|
||||
let mut _3: *const u8;
|
||||
let mut _4: usize;
|
||||
scope 3 (inlined Vec::<u8>::as_ptr) {
|
||||
debug self => _1;
|
||||
let mut _6: *mut u8;
|
||||
scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
|
||||
scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
|
||||
let mut _5: std::ptr::NonNull<u8>;
|
||||
scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
|
||||
let mut _2: std::ptr::NonNull<u8>;
|
||||
scope 7 (inlined Unique::<u8>::cast::<u8>) {
|
||||
scope 8 (inlined NonNull::<u8>::cast::<u8>) {
|
||||
let mut _3: *mut u8;
|
||||
let mut _4: *const u8;
|
||||
scope 9 (inlined NonNull::<u8>::as_ptr) {
|
||||
}
|
||||
}
|
||||
|
|
@ -34,9 +30,9 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
|||
}
|
||||
}
|
||||
scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
|
||||
debug data => _7;
|
||||
debug len => _8;
|
||||
let _9: *const [u8];
|
||||
debug data => _3;
|
||||
debug len => _4;
|
||||
let _5: *const [u8];
|
||||
scope 13 (inlined core::ub_checks::check_language_ub) {
|
||||
scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
}
|
||||
|
|
@ -46,10 +42,10 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
|||
scope 16 (inlined align_of::<u8>) {
|
||||
}
|
||||
scope 17 (inlined slice_from_raw_parts::<u8>) {
|
||||
debug data => _7;
|
||||
debug len => _8;
|
||||
debug data => _3;
|
||||
debug len => _4;
|
||||
scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
|
||||
debug data_pointer => _7;
|
||||
debug data_pointer => _3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -57,31 +53,19 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
|||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
StorageLive(_5);
|
||||
StorageLive(_2);
|
||||
_2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
|
||||
StorageLive(_3);
|
||||
_2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
|
||||
_3 = copy _2 as *const u8 (Transmute);
|
||||
StorageLive(_4);
|
||||
_3 = copy _2 as *mut u8 (Transmute);
|
||||
_4 = copy _3 as *const u8 (PtrToPtr);
|
||||
_5 = NonNull::<u8> { pointer: move _4 };
|
||||
_4 = copy ((*_1).1: usize);
|
||||
StorageLive(_5);
|
||||
_5 = *const [u8] from (copy _3, copy _4);
|
||||
_0 = &(*_5);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
StorageDead(_2);
|
||||
_6 = copy _5 as *mut u8 (Transmute);
|
||||
StorageDead(_5);
|
||||
_7 = copy _6 as *const u8 (PtrToPtr);
|
||||
StorageLive(_8);
|
||||
_8 = copy ((*_1).1: usize);
|
||||
StorageLive(_9);
|
||||
_9 = *const [u8] from (copy _7, copy _8);
|
||||
_0 = &(*_9);
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue