[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:
Scott McMurray 2024-11-21 17:59:43 -08:00
parent e26ff2f908
commit 8dcc676c92
30 changed files with 1045 additions and 659 deletions

View file

@ -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;
}

View file

@ -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;
}
}
}
}
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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]> }};

View file

@ -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]> }};

View file

@ -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]> }};

View file

@ -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]> }};

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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];
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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];
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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 {

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;
}
}