mir-opt: Simplify trivial constants in SimplifyConstCondition
This commit is contained in:
parent
f5242367f4
commit
a673575b24
20 changed files with 687 additions and 319 deletions
|
|
@ -189,6 +189,7 @@ declare_passes! {
|
|||
Final
|
||||
};
|
||||
mod simplify_branches : SimplifyConstCondition {
|
||||
AfterInstSimplify,
|
||||
AfterConstProp,
|
||||
Final
|
||||
};
|
||||
|
|
@ -708,6 +709,15 @@ pub(crate) fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'
|
|||
// optimizations. This invalidates CFG caches, so avoid putting between
|
||||
// `ReferencePropagation` and `GVN` which both use the dominator tree.
|
||||
&instsimplify::InstSimplify::AfterSimplifyCfg,
|
||||
// After `InstSimplify-after-simplifycfg` with `-Zub_checks=false`, simplify
|
||||
// ```
|
||||
// _13 = const false;
|
||||
// assume(copy _13);
|
||||
// Call(precondition_check);
|
||||
// ```
|
||||
// to unreachable to eliminate the call to help later passes.
|
||||
// This invalidates CFG caches also.
|
||||
&o1(simplify_branches::SimplifyConstCondition::AfterInstSimplify),
|
||||
&ref_prop::ReferencePropagation,
|
||||
&sroa::ScalarReplacementOfAggregates,
|
||||
&simplify::SimplifyLocals::BeforeConstProp,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use tracing::trace;
|
|||
use crate::patch::MirPatch;
|
||||
|
||||
pub(super) enum SimplifyConstCondition {
|
||||
AfterInstSimplify,
|
||||
AfterConstProp,
|
||||
Final,
|
||||
}
|
||||
|
|
@ -13,6 +14,9 @@ pub(super) enum SimplifyConstCondition {
|
|||
impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
|
||||
fn name(&self) -> &'static str {
|
||||
match self {
|
||||
SimplifyConstCondition::AfterInstSimplify => {
|
||||
"SimplifyConstCondition-after-inst-simplify"
|
||||
}
|
||||
SimplifyConstCondition::AfterConstProp => "SimplifyConstCondition-after-const-prop",
|
||||
SimplifyConstCondition::Final => "SimplifyConstCondition-final",
|
||||
}
|
||||
|
|
@ -23,12 +27,33 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
|
|||
let typing_env = body.typing_env(tcx);
|
||||
let mut patch = MirPatch::new(body);
|
||||
|
||||
fn try_get_const<'tcx, 'a>(
|
||||
operand: &'a Operand<'tcx>,
|
||||
has_place_const: Option<(Place<'tcx>, &'a ConstOperand<'tcx>)>,
|
||||
) -> Option<&'a ConstOperand<'tcx>> {
|
||||
match operand {
|
||||
Operand::Constant(const_operand) => Some(const_operand),
|
||||
// `has_place_const` must be the LHS of the previous statement.
|
||||
// Soundness: There is nothing can modify the place, as there are no statements between the two statements.
|
||||
Operand::Copy(place) | Operand::Move(place)
|
||||
if let Some((place_const, const_operand)) = has_place_const
|
||||
&& place_const == *place =>
|
||||
{
|
||||
Some(const_operand)
|
||||
}
|
||||
Operand::Copy(_) | Operand::Move(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
'blocks: for (bb, block) in body.basic_blocks.iter_enumerated() {
|
||||
let mut pre_place_const: Option<(Place<'tcx>, &ConstOperand<'tcx>)> = None;
|
||||
|
||||
for (statement_index, stmt) in block.statements.iter().enumerate() {
|
||||
let has_place_const = pre_place_const.take();
|
||||
// Simplify `assume` of a known value: either a NOP or unreachable.
|
||||
if let StatementKind::Intrinsic(box ref intrinsic) = stmt.kind
|
||||
&& let NonDivergingIntrinsic::Assume(discr) = intrinsic
|
||||
&& let Operand::Constant(c) = discr
|
||||
&& let Some(c) = try_get_const(discr, has_place_const)
|
||||
&& let Some(constant) = c.const_.try_eval_bool(tcx, typing_env)
|
||||
{
|
||||
if constant {
|
||||
|
|
@ -37,28 +62,29 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
|
|||
patch.patch_terminator(bb, TerminatorKind::Unreachable);
|
||||
continue 'blocks;
|
||||
}
|
||||
} else if let StatementKind::Assign(box (lhs, ref rvalue)) = stmt.kind
|
||||
&& let Rvalue::Use(Operand::Constant(c)) = rvalue
|
||||
{
|
||||
pre_place_const = Some((lhs, c));
|
||||
}
|
||||
}
|
||||
|
||||
let terminator = block.terminator();
|
||||
let terminator = match terminator.kind {
|
||||
TerminatorKind::SwitchInt {
|
||||
discr: Operand::Constant(ref c), ref targets, ..
|
||||
} => {
|
||||
let constant = c.const_.try_eval_bits(tcx, typing_env);
|
||||
if let Some(constant) = constant {
|
||||
let target = targets.target_for_value(constant);
|
||||
TerminatorKind::Goto { target }
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
TerminatorKind::SwitchInt { ref discr, ref targets, .. }
|
||||
if let Some(c) = try_get_const(discr, pre_place_const.take())
|
||||
&& let Some(constant) = c.const_.try_eval_bits(tcx, typing_env) =>
|
||||
{
|
||||
let target = targets.target_for_value(constant);
|
||||
TerminatorKind::Goto { target }
|
||||
}
|
||||
TerminatorKind::Assert { target, ref cond, expected, .. }
|
||||
if let Some(c) = try_get_const(&cond, pre_place_const.take())
|
||||
&& let Some(constant) = c.const_.try_eval_bool(tcx, typing_env)
|
||||
&& constant == expected =>
|
||||
{
|
||||
TerminatorKind::Goto { target }
|
||||
}
|
||||
TerminatorKind::Assert {
|
||||
target, cond: Operand::Constant(ref c), expected, ..
|
||||
} => match c.const_.try_eval_bool(tcx, typing_env) {
|
||||
Some(v) if v == expected => TerminatorKind::Goto { target },
|
||||
_ => continue,
|
||||
},
|
||||
_ => continue,
|
||||
};
|
||||
patch.patch_terminator(bb, terminator);
|
||||
|
|
|
|||
|
|
@ -3,23 +3,17 @@
|
|||
|
||||
fn hello() -> () {
|
||||
let mut _0: ();
|
||||
let mut _1: bool;
|
||||
let mut _2: !;
|
||||
let mut _1: !;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _1 = const <bool as NeedsDrop>::NEEDS;
|
||||
- switchInt(move _1) -> [0: bb2, otherwise: bb1];
|
||||
+ _1 = const false;
|
||||
+ switchInt(const false) -> [0: bb2, otherwise: bb1];
|
||||
goto -> bb2;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_2 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable;
|
||||
_1 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,23 +3,17 @@
|
|||
|
||||
fn hello() -> () {
|
||||
let mut _0: ();
|
||||
let mut _1: bool;
|
||||
let mut _2: !;
|
||||
let mut _1: !;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _1 = const <bool as NeedsDrop>::NEEDS;
|
||||
- switchInt(move _1) -> [0: bb2, otherwise: bb1];
|
||||
+ _1 = const false;
|
||||
+ switchInt(const false) -> [0: bb2, otherwise: bb1];
|
||||
goto -> bb2;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_2 = begin_panic::<&str>(const "explicit panic") -> unwind continue;
|
||||
_1 = begin_panic::<&str>(const "explicit panic") -> unwind continue;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// skip-filecheck
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
//@ test-mir-pass: GVN
|
||||
//@ compile-flags: -Zmir-opt-level=1
|
||||
|
|
@ -12,6 +11,9 @@ impl<This> NeedsDrop for This {}
|
|||
// EMIT_MIR control_flow_simplification.hello.GVN.diff
|
||||
// EMIT_MIR control_flow_simplification.hello.PreCodegen.before.mir
|
||||
fn hello<T>() {
|
||||
// CHECK-LABEL: fn hello(
|
||||
// CHECK: bb0:
|
||||
// CHECK-NEXT: return;
|
||||
if <bool>::NEEDS {
|
||||
panic!()
|
||||
}
|
||||
|
|
|
|||
15
tests/mir-opt/const_prop/trivial_const.rs
Normal file
15
tests/mir-opt/const_prop/trivial_const.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
//@ test-mir-pass: SimplifyConstCondition-after-inst-simplify
|
||||
//@ compile-flags: -Zmir-enable-passes=+InstSimplify-after-simplifycfg -Zub_checks=false -Zinline-mir
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// EMIT_MIR trivial_const.unwrap_unchecked.SimplifyConstCondition-after-inst-simplify.diff
|
||||
pub fn unwrap_unchecked(v: &Option<i32>) -> i32 {
|
||||
// CHECK-LABEL: fn unwrap_unchecked(
|
||||
// CHECK: bb0: {
|
||||
// CHECK: switchInt({{.*}}) -> [0: [[AssumeFalseBB:bb.*]], 1:
|
||||
// CHECK: [[AssumeFalseBB]]: {
|
||||
// CHECK-NEXT: unreachable;
|
||||
let v = unsafe { v.unwrap_unchecked() };
|
||||
v
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
- // MIR for `unwrap_unchecked` before SimplifyConstCondition-after-inst-simplify
|
||||
+ // MIR for `unwrap_unchecked` after SimplifyConstCondition-after-inst-simplify
|
||||
|
||||
fn unwrap_unchecked(_1: &Option<i32>) -> i32 {
|
||||
debug v => _1;
|
||||
let mut _0: i32;
|
||||
let _2: i32;
|
||||
let mut _3: std::option::Option<i32>;
|
||||
scope 1 {
|
||||
debug v => _2;
|
||||
}
|
||||
scope 2 (inlined #[track_caller] Option::<i32>::unwrap_unchecked) {
|
||||
let mut _4: isize;
|
||||
scope 3 {
|
||||
}
|
||||
scope 4 (inlined #[track_caller] unreachable_unchecked) {
|
||||
let _5: ();
|
||||
scope 5 (inlined core::ub_checks::check_language_ub) {
|
||||
let mut _6: bool;
|
||||
scope 6 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = copy (*_1);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_4 = discriminant(_3);
|
||||
switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb1];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- StorageLive(_6);
|
||||
- _6 = const false;
|
||||
- assume(copy _6);
|
||||
- _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
|
||||
+ unreachable;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
_2 = move ((_3 as Some).0: i32);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
_0 = copy _2;
|
||||
StorageDead(_2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,10 +1,14 @@
|
|||
// skip-filecheck
|
||||
//@ compile-flags: -Zmir-enable-passes=+Inline,+GVN --crate-type lib
|
||||
//@ test-mir-pass: GVN
|
||||
//@ compile-flags: -Zinline-mir --crate-type lib
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// EMIT_MIR dont_reset_cast_kind_without_updating_operand.test.GVN.diff
|
||||
|
||||
fn test() {
|
||||
// CHECK-LABEL: fn test(
|
||||
// CHECK: debug slf => [[SLF:_.*]];
|
||||
// CHECK: debug _x => [[X:_.*]];
|
||||
// CHECK: [[X]] = copy [[SLF]] as *mut () (PtrToPtr);
|
||||
let vp_ctx: &Box<()> = &Box::new(());
|
||||
let slf: *const () = &raw const **vp_ctx;
|
||||
let bytes = std::ptr::slice_from_raw_parts(slf, 1);
|
||||
|
|
|
|||
|
|
@ -6,24 +6,26 @@
|
|||
let _1: &std::boxed::Box<()>;
|
||||
let _2: &std::boxed::Box<()>;
|
||||
let _3: std::boxed::Box<()>;
|
||||
let mut _6: *const ();
|
||||
let mut _8: *const [()];
|
||||
let mut _9: *const ();
|
||||
let mut _22: usize;
|
||||
let mut _23: std::ptr::NonNull<()>;
|
||||
let mut _4: ();
|
||||
let mut _7: *const ();
|
||||
let mut _9: *const [()];
|
||||
let mut _10: std::boxed::Box<()>;
|
||||
let mut _11: *const ();
|
||||
let mut _25: usize;
|
||||
scope 1 {
|
||||
debug vp_ctx => _1;
|
||||
let _4: *const ();
|
||||
let _5: *const ();
|
||||
scope 2 {
|
||||
debug slf => _9;
|
||||
let _5: *const [()];
|
||||
debug slf => _5;
|
||||
let _6: *const [()];
|
||||
scope 3 {
|
||||
debug bytes => _5;
|
||||
let _7: *mut ();
|
||||
debug bytes => _6;
|
||||
let _8: *mut ();
|
||||
scope 4 {
|
||||
debug _x => _7;
|
||||
debug _x => _8;
|
||||
}
|
||||
scope 18 (inlined foo) {
|
||||
let mut _26: *const [()];
|
||||
}
|
||||
}
|
||||
scope 16 (inlined slice_from_raw_parts::<()>) {
|
||||
|
|
@ -33,21 +35,22 @@
|
|||
}
|
||||
}
|
||||
scope 5 (inlined Box::<()>::new) {
|
||||
let mut _10: usize;
|
||||
let mut _11: usize;
|
||||
let mut _12: *mut u8;
|
||||
let mut _12: usize;
|
||||
let mut _13: usize;
|
||||
let mut _14: *mut u8;
|
||||
let mut _15: *const ();
|
||||
scope 6 (inlined alloc::alloc::exchange_malloc) {
|
||||
let _13: std::alloc::Layout;
|
||||
let mut _14: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
||||
let mut _15: isize;
|
||||
let mut _17: !;
|
||||
let _16: std::alloc::Layout;
|
||||
let mut _17: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
||||
let mut _18: isize;
|
||||
let mut _20: !;
|
||||
scope 7 {
|
||||
let _16: std::ptr::NonNull<[u8]>;
|
||||
let _19: std::ptr::NonNull<[u8]>;
|
||||
scope 8 {
|
||||
scope 11 (inlined NonNull::<[u8]>::as_mut_ptr) {
|
||||
scope 12 (inlined NonNull::<[u8]>::as_non_null_ptr) {
|
||||
scope 13 (inlined NonNull::<[u8]>::cast::<u8>) {
|
||||
let mut _21: *mut [u8];
|
||||
let mut _24: *mut [u8];
|
||||
scope 14 (inlined NonNull::<[u8]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
|
|
@ -60,31 +63,37 @@
|
|||
}
|
||||
}
|
||||
scope 9 (inlined #[track_caller] Layout::from_size_align_unchecked) {
|
||||
let mut _18: bool;
|
||||
let _19: ();
|
||||
let mut _20: std::ptr::Alignment;
|
||||
let mut _21: bool;
|
||||
let _22: ();
|
||||
let mut _23: std::ptr::Alignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
- StorageLive(_2);
|
||||
+ nop;
|
||||
StorageLive(_3);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
StorageLive(_4);
|
||||
- _4 = ();
|
||||
+ _4 = const ();
|
||||
StorageLive(_12);
|
||||
- _10 = SizeOf(());
|
||||
- _11 = AlignOf(());
|
||||
+ _10 = const 0_usize;
|
||||
+ _11 = const 1_usize;
|
||||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
StorageLive(_15);
|
||||
- _12 = SizeOf(());
|
||||
- _13 = AlignOf(());
|
||||
+ _12 = const 0_usize;
|
||||
+ _13 = const 1_usize;
|
||||
StorageLive(_16);
|
||||
StorageLive(_18);
|
||||
_18 = const false;
|
||||
- switchInt(move _18) -> [0: bb6, otherwise: bb5];
|
||||
+ switchInt(const false) -> [0: bb6, otherwise: bb5];
|
||||
StorageLive(_19);
|
||||
StorageLive(_20);
|
||||
StorageLive(_22);
|
||||
StorageLive(_21);
|
||||
_21 = UbChecks();
|
||||
switchInt(move _21) -> [0: bb6, otherwise: bb5];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
@ -98,76 +107,91 @@
|
|||
}
|
||||
|
||||
bb3: {
|
||||
- _17 = handle_alloc_error(move _13) -> unwind unreachable;
|
||||
+ _17 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}) -> unwind unreachable;
|
||||
- _20 = handle_alloc_error(move _16) -> unwind unreachable;
|
||||
+ _20 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}) -> unwind unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
_16 = copy ((_14 as Ok).0: std::ptr::NonNull<[u8]>);
|
||||
StorageLive(_21);
|
||||
_21 = copy _16 as *mut [u8] (Transmute);
|
||||
_12 = copy _21 as *mut u8 (PtrToPtr);
|
||||
StorageDead(_21);
|
||||
StorageDead(_14);
|
||||
StorageDead(_16);
|
||||
StorageDead(_15);
|
||||
StorageDead(_13);
|
||||
_3 = ShallowInitBox(copy _12, ());
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
_2 = &_3;
|
||||
_1 = copy _2;
|
||||
StorageDead(_2);
|
||||
StorageLive(_4);
|
||||
_23 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>);
|
||||
_9 = copy _23 as *const () (Transmute);
|
||||
_4 = copy _9;
|
||||
- StorageLive(_5);
|
||||
+ nop;
|
||||
StorageLive(_6);
|
||||
- _6 = copy _4;
|
||||
+ _6 = copy _9;
|
||||
StorageLive(_22);
|
||||
_22 = const 1_usize;
|
||||
- _5 = *const [()] from (copy _6, copy _22);
|
||||
+ _5 = *const [()] from (copy _9, const 1_usize);
|
||||
_19 = copy ((_17 as Ok).0: std::ptr::NonNull<[u8]>);
|
||||
StorageLive(_24);
|
||||
_24 = copy _19 as *mut [u8] (Transmute);
|
||||
_14 = copy _24 as *mut u8 (PtrToPtr);
|
||||
StorageDead(_24);
|
||||
StorageDead(_17);
|
||||
StorageDead(_22);
|
||||
StorageDead(_6);
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageDead(_16);
|
||||
_3 = ShallowInitBox(copy _14, ());
|
||||
_15 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
|
||||
- (*_15) = move _4;
|
||||
+ (*_15) = const ();
|
||||
StorageDead(_15);
|
||||
StorageDead(_14);
|
||||
StorageDead(_13);
|
||||
StorageDead(_12);
|
||||
StorageDead(_4);
|
||||
_2 = &_3;
|
||||
_1 = &(*_2);
|
||||
- StorageDead(_2);
|
||||
- StorageLive(_5);
|
||||
- _10 = copy (*_1);
|
||||
+ nop;
|
||||
+ nop;
|
||||
+ _10 = copy (*_2);
|
||||
_11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
|
||||
_5 = &raw const (*_11);
|
||||
- StorageLive(_6);
|
||||
+ nop;
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
_8 = copy _5;
|
||||
- _7 = copy _8 as *mut () (PtrToPtr);
|
||||
+ _7 = copy _23 as *mut () (Transmute);
|
||||
StorageDead(_8);
|
||||
_7 = copy _5;
|
||||
StorageLive(_25);
|
||||
_25 = const 1_usize;
|
||||
- _6 = *const [()] from (copy _7, copy _25);
|
||||
+ _6 = *const [()] from (copy _5, const 1_usize);
|
||||
StorageDead(_25);
|
||||
StorageDead(_7);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
_9 = copy _6;
|
||||
StorageLive(_26);
|
||||
- _26 = copy _9;
|
||||
- _8 = copy _9 as *mut () (PtrToPtr);
|
||||
+ _26 = copy _6;
|
||||
+ _8 = copy _5 as *mut () (PtrToPtr);
|
||||
StorageDead(_26);
|
||||
StorageDead(_9);
|
||||
_0 = const ();
|
||||
StorageDead(_8);
|
||||
- StorageDead(_6);
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
StorageDead(_4);
|
||||
+ nop;
|
||||
drop(_3) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
- _19 = Layout::from_size_align_unchecked::precondition_check(copy _10, copy _11) -> [return: bb6, unwind unreachable];
|
||||
+ _19 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
|
||||
- _22 = Layout::from_size_align_unchecked::precondition_check(copy _12, copy _13) -> [return: bb6, unwind unreachable];
|
||||
+ _22 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_18);
|
||||
StorageLive(_20);
|
||||
- _20 = copy _11 as std::ptr::Alignment (Transmute);
|
||||
- _13 = Layout { size: copy _10, align: move _20 };
|
||||
+ _20 = const std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0);
|
||||
+ _13 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }};
|
||||
StorageDead(_20);
|
||||
StorageLive(_14);
|
||||
- _14 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _13, const false) -> [return: bb7, unwind unreachable];
|
||||
+ _14 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable];
|
||||
StorageDead(_21);
|
||||
StorageLive(_23);
|
||||
- _23 = copy _13 as std::ptr::Alignment (Transmute);
|
||||
- _16 = Layout { size: copy _12, align: move _23 };
|
||||
+ _23 = const std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0);
|
||||
+ _16 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }};
|
||||
StorageDead(_23);
|
||||
StorageLive(_17);
|
||||
- _17 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _16, const false) -> [return: bb7, unwind unreachable];
|
||||
+ _17 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
_15 = discriminant(_14);
|
||||
switchInt(move _15) -> [0: bb4, 1: bb3, otherwise: bb2];
|
||||
_18 = discriminant(_17);
|
||||
switchInt(move _18) -> [0: bb4, 1: bb3, otherwise: bb2];
|
||||
}
|
||||
+ }
|
||||
+
|
||||
|
|
|
|||
|
|
@ -6,24 +6,26 @@
|
|||
let _1: &std::boxed::Box<()>;
|
||||
let _2: &std::boxed::Box<()>;
|
||||
let _3: std::boxed::Box<()>;
|
||||
let mut _6: *const ();
|
||||
let mut _8: *const [()];
|
||||
let mut _9: *const ();
|
||||
let mut _10: usize;
|
||||
let mut _11: std::ptr::NonNull<()>;
|
||||
let mut _4: ();
|
||||
let mut _7: *const ();
|
||||
let mut _9: *const [()];
|
||||
let mut _10: std::boxed::Box<()>;
|
||||
let mut _11: *const ();
|
||||
let mut _12: usize;
|
||||
scope 1 {
|
||||
debug vp_ctx => _1;
|
||||
let _4: *const ();
|
||||
let _5: *const ();
|
||||
scope 2 {
|
||||
debug slf => _9;
|
||||
let _5: *const [()];
|
||||
debug slf => _5;
|
||||
let _6: *const [()];
|
||||
scope 3 {
|
||||
debug bytes => _5;
|
||||
let _7: *mut ();
|
||||
debug bytes => _6;
|
||||
let _8: *mut ();
|
||||
scope 4 {
|
||||
debug _x => _7;
|
||||
debug _x => _8;
|
||||
}
|
||||
scope 7 (inlined foo) {
|
||||
let mut _13: *const [()];
|
||||
}
|
||||
}
|
||||
scope 5 (inlined slice_from_raw_parts::<()>) {
|
||||
|
|
@ -35,40 +37,54 @@
|
|||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
- StorageLive(_2);
|
||||
+ nop;
|
||||
StorageLive(_3);
|
||||
_3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue];
|
||||
StorageLive(_4);
|
||||
- _4 = ();
|
||||
- _3 = Box::<()>::new(move _4) -> [return: bb1, unwind continue];
|
||||
+ _4 = const ();
|
||||
+ _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_4);
|
||||
_2 = &_3;
|
||||
_1 = copy _2;
|
||||
StorageDead(_2);
|
||||
StorageLive(_4);
|
||||
_11 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>);
|
||||
_9 = copy _11 as *const () (Transmute);
|
||||
_4 = copy _9;
|
||||
_1 = &(*_2);
|
||||
- StorageDead(_2);
|
||||
- StorageLive(_5);
|
||||
- _10 = copy (*_1);
|
||||
+ nop;
|
||||
+ nop;
|
||||
+ _10 = copy (*_2);
|
||||
_11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
|
||||
_5 = &raw const (*_11);
|
||||
- StorageLive(_6);
|
||||
+ nop;
|
||||
StorageLive(_6);
|
||||
- _6 = copy _4;
|
||||
+ _6 = copy _9;
|
||||
StorageLive(_10);
|
||||
_10 = const 1_usize;
|
||||
- _5 = *const [()] from (copy _6, copy _10);
|
||||
+ _5 = *const [()] from (copy _9, const 1_usize);
|
||||
StorageDead(_10);
|
||||
StorageDead(_6);
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
_8 = copy _5;
|
||||
- _7 = copy _8 as *mut () (PtrToPtr);
|
||||
+ _7 = copy _11 as *mut () (Transmute);
|
||||
StorageDead(_8);
|
||||
_7 = copy _5;
|
||||
StorageLive(_12);
|
||||
_12 = const 1_usize;
|
||||
- _6 = *const [()] from (copy _7, copy _12);
|
||||
+ _6 = *const [()] from (copy _5, const 1_usize);
|
||||
StorageDead(_12);
|
||||
StorageDead(_7);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
_9 = copy _6;
|
||||
StorageLive(_13);
|
||||
- _13 = copy _9;
|
||||
- _8 = copy _9 as *mut () (PtrToPtr);
|
||||
+ _13 = copy _6;
|
||||
+ _8 = copy _5 as *mut () (PtrToPtr);
|
||||
StorageDead(_13);
|
||||
StorageDead(_9);
|
||||
_0 = const ();
|
||||
StorageDead(_8);
|
||||
- StorageDead(_6);
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
StorageDead(_4);
|
||||
+ nop;
|
||||
drop(_3) -> [return: bb2, unwind: bb3];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,24 +6,26 @@
|
|||
let _1: &std::boxed::Box<()>;
|
||||
let _2: &std::boxed::Box<()>;
|
||||
let _3: std::boxed::Box<()>;
|
||||
let mut _6: *const ();
|
||||
let mut _8: *const [()];
|
||||
let mut _9: *const ();
|
||||
let mut _22: usize;
|
||||
let mut _23: std::ptr::NonNull<()>;
|
||||
let mut _4: ();
|
||||
let mut _7: *const ();
|
||||
let mut _9: *const [()];
|
||||
let mut _10: std::boxed::Box<()>;
|
||||
let mut _11: *const ();
|
||||
let mut _25: usize;
|
||||
scope 1 {
|
||||
debug vp_ctx => _1;
|
||||
let _4: *const ();
|
||||
let _5: *const ();
|
||||
scope 2 {
|
||||
debug slf => _9;
|
||||
let _5: *const [()];
|
||||
debug slf => _5;
|
||||
let _6: *const [()];
|
||||
scope 3 {
|
||||
debug bytes => _5;
|
||||
let _7: *mut ();
|
||||
debug bytes => _6;
|
||||
let _8: *mut ();
|
||||
scope 4 {
|
||||
debug _x => _7;
|
||||
debug _x => _8;
|
||||
}
|
||||
scope 18 (inlined foo) {
|
||||
let mut _26: *const [()];
|
||||
}
|
||||
}
|
||||
scope 16 (inlined slice_from_raw_parts::<()>) {
|
||||
|
|
@ -33,21 +35,22 @@
|
|||
}
|
||||
}
|
||||
scope 5 (inlined Box::<()>::new) {
|
||||
let mut _10: usize;
|
||||
let mut _11: usize;
|
||||
let mut _12: *mut u8;
|
||||
let mut _12: usize;
|
||||
let mut _13: usize;
|
||||
let mut _14: *mut u8;
|
||||
let mut _15: *const ();
|
||||
scope 6 (inlined alloc::alloc::exchange_malloc) {
|
||||
let _13: std::alloc::Layout;
|
||||
let mut _14: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
||||
let mut _15: isize;
|
||||
let mut _17: !;
|
||||
let _16: std::alloc::Layout;
|
||||
let mut _17: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
||||
let mut _18: isize;
|
||||
let mut _20: !;
|
||||
scope 7 {
|
||||
let _16: std::ptr::NonNull<[u8]>;
|
||||
let _19: std::ptr::NonNull<[u8]>;
|
||||
scope 8 {
|
||||
scope 11 (inlined NonNull::<[u8]>::as_mut_ptr) {
|
||||
scope 12 (inlined NonNull::<[u8]>::as_non_null_ptr) {
|
||||
scope 13 (inlined NonNull::<[u8]>::cast::<u8>) {
|
||||
let mut _21: *mut [u8];
|
||||
let mut _24: *mut [u8];
|
||||
scope 14 (inlined NonNull::<[u8]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
|
|
@ -60,31 +63,37 @@
|
|||
}
|
||||
}
|
||||
scope 9 (inlined #[track_caller] Layout::from_size_align_unchecked) {
|
||||
let mut _18: bool;
|
||||
let _19: ();
|
||||
let mut _20: std::ptr::Alignment;
|
||||
let mut _21: bool;
|
||||
let _22: ();
|
||||
let mut _23: std::ptr::Alignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
- StorageLive(_2);
|
||||
+ nop;
|
||||
StorageLive(_3);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
StorageLive(_4);
|
||||
- _4 = ();
|
||||
+ _4 = const ();
|
||||
StorageLive(_12);
|
||||
- _10 = SizeOf(());
|
||||
- _11 = AlignOf(());
|
||||
+ _10 = const 0_usize;
|
||||
+ _11 = const 1_usize;
|
||||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
StorageLive(_15);
|
||||
- _12 = SizeOf(());
|
||||
- _13 = AlignOf(());
|
||||
+ _12 = const 0_usize;
|
||||
+ _13 = const 1_usize;
|
||||
StorageLive(_16);
|
||||
StorageLive(_18);
|
||||
_18 = const false;
|
||||
- switchInt(move _18) -> [0: bb6, otherwise: bb5];
|
||||
+ switchInt(const false) -> [0: bb6, otherwise: bb5];
|
||||
StorageLive(_19);
|
||||
StorageLive(_20);
|
||||
StorageLive(_22);
|
||||
StorageLive(_21);
|
||||
_21 = UbChecks();
|
||||
switchInt(move _21) -> [0: bb6, otherwise: bb5];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
@ -98,76 +107,91 @@
|
|||
}
|
||||
|
||||
bb3: {
|
||||
- _17 = handle_alloc_error(move _13) -> unwind unreachable;
|
||||
+ _17 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}) -> unwind unreachable;
|
||||
- _20 = handle_alloc_error(move _16) -> unwind unreachable;
|
||||
+ _20 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}) -> unwind unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
_16 = copy ((_14 as Ok).0: std::ptr::NonNull<[u8]>);
|
||||
StorageLive(_21);
|
||||
_21 = copy _16 as *mut [u8] (Transmute);
|
||||
_12 = copy _21 as *mut u8 (PtrToPtr);
|
||||
StorageDead(_21);
|
||||
StorageDead(_14);
|
||||
StorageDead(_16);
|
||||
StorageDead(_15);
|
||||
StorageDead(_13);
|
||||
_3 = ShallowInitBox(copy _12, ());
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
_2 = &_3;
|
||||
_1 = copy _2;
|
||||
StorageDead(_2);
|
||||
StorageLive(_4);
|
||||
_23 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>);
|
||||
_9 = copy _23 as *const () (Transmute);
|
||||
_4 = copy _9;
|
||||
- StorageLive(_5);
|
||||
+ nop;
|
||||
StorageLive(_6);
|
||||
- _6 = copy _4;
|
||||
+ _6 = copy _9;
|
||||
StorageLive(_22);
|
||||
_22 = const 1_usize;
|
||||
- _5 = *const [()] from (copy _6, copy _22);
|
||||
+ _5 = *const [()] from (copy _9, const 1_usize);
|
||||
_19 = copy ((_17 as Ok).0: std::ptr::NonNull<[u8]>);
|
||||
StorageLive(_24);
|
||||
_24 = copy _19 as *mut [u8] (Transmute);
|
||||
_14 = copy _24 as *mut u8 (PtrToPtr);
|
||||
StorageDead(_24);
|
||||
StorageDead(_17);
|
||||
StorageDead(_22);
|
||||
StorageDead(_6);
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageDead(_16);
|
||||
_3 = ShallowInitBox(copy _14, ());
|
||||
_15 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
|
||||
- (*_15) = move _4;
|
||||
+ (*_15) = const ();
|
||||
StorageDead(_15);
|
||||
StorageDead(_14);
|
||||
StorageDead(_13);
|
||||
StorageDead(_12);
|
||||
StorageDead(_4);
|
||||
_2 = &_3;
|
||||
_1 = &(*_2);
|
||||
- StorageDead(_2);
|
||||
- StorageLive(_5);
|
||||
- _10 = copy (*_1);
|
||||
+ nop;
|
||||
+ nop;
|
||||
+ _10 = copy (*_2);
|
||||
_11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
|
||||
_5 = &raw const (*_11);
|
||||
- StorageLive(_6);
|
||||
+ nop;
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
_8 = copy _5;
|
||||
- _7 = copy _8 as *mut () (PtrToPtr);
|
||||
+ _7 = copy _23 as *mut () (Transmute);
|
||||
StorageDead(_8);
|
||||
_7 = copy _5;
|
||||
StorageLive(_25);
|
||||
_25 = const 1_usize;
|
||||
- _6 = *const [()] from (copy _7, copy _25);
|
||||
+ _6 = *const [()] from (copy _5, const 1_usize);
|
||||
StorageDead(_25);
|
||||
StorageDead(_7);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
_9 = copy _6;
|
||||
StorageLive(_26);
|
||||
- _26 = copy _9;
|
||||
- _8 = copy _9 as *mut () (PtrToPtr);
|
||||
+ _26 = copy _6;
|
||||
+ _8 = copy _5 as *mut () (PtrToPtr);
|
||||
StorageDead(_26);
|
||||
StorageDead(_9);
|
||||
_0 = const ();
|
||||
StorageDead(_8);
|
||||
- StorageDead(_6);
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
StorageDead(_4);
|
||||
+ nop;
|
||||
drop(_3) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
- _19 = Layout::from_size_align_unchecked::precondition_check(copy _10, copy _11) -> [return: bb6, unwind unreachable];
|
||||
+ _19 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
|
||||
- _22 = Layout::from_size_align_unchecked::precondition_check(copy _12, copy _13) -> [return: bb6, unwind unreachable];
|
||||
+ _22 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_18);
|
||||
StorageLive(_20);
|
||||
- _20 = copy _11 as std::ptr::Alignment (Transmute);
|
||||
- _13 = Layout { size: copy _10, align: move _20 };
|
||||
+ _20 = const std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0);
|
||||
+ _13 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }};
|
||||
StorageDead(_20);
|
||||
StorageLive(_14);
|
||||
- _14 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _13, const false) -> [return: bb7, unwind unreachable];
|
||||
+ _14 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable];
|
||||
StorageDead(_21);
|
||||
StorageLive(_23);
|
||||
- _23 = copy _13 as std::ptr::Alignment (Transmute);
|
||||
- _16 = Layout { size: copy _12, align: move _23 };
|
||||
+ _23 = const std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0);
|
||||
+ _16 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }};
|
||||
StorageDead(_23);
|
||||
StorageLive(_17);
|
||||
- _17 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _16, const false) -> [return: bb7, unwind unreachable];
|
||||
+ _17 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
_15 = discriminant(_14);
|
||||
switchInt(move _15) -> [0: bb4, 1: bb3, otherwise: bb2];
|
||||
_18 = discriminant(_17);
|
||||
switchInt(move _18) -> [0: bb4, 1: bb3, otherwise: bb2];
|
||||
}
|
||||
+ }
|
||||
+
|
||||
|
|
|
|||
|
|
@ -6,24 +6,26 @@
|
|||
let _1: &std::boxed::Box<()>;
|
||||
let _2: &std::boxed::Box<()>;
|
||||
let _3: std::boxed::Box<()>;
|
||||
let mut _6: *const ();
|
||||
let mut _8: *const [()];
|
||||
let mut _9: *const ();
|
||||
let mut _10: usize;
|
||||
let mut _11: std::ptr::NonNull<()>;
|
||||
let mut _4: ();
|
||||
let mut _7: *const ();
|
||||
let mut _9: *const [()];
|
||||
let mut _10: std::boxed::Box<()>;
|
||||
let mut _11: *const ();
|
||||
let mut _12: usize;
|
||||
scope 1 {
|
||||
debug vp_ctx => _1;
|
||||
let _4: *const ();
|
||||
let _5: *const ();
|
||||
scope 2 {
|
||||
debug slf => _9;
|
||||
let _5: *const [()];
|
||||
debug slf => _5;
|
||||
let _6: *const [()];
|
||||
scope 3 {
|
||||
debug bytes => _5;
|
||||
let _7: *mut ();
|
||||
debug bytes => _6;
|
||||
let _8: *mut ();
|
||||
scope 4 {
|
||||
debug _x => _7;
|
||||
debug _x => _8;
|
||||
}
|
||||
scope 7 (inlined foo) {
|
||||
let mut _13: *const [()];
|
||||
}
|
||||
}
|
||||
scope 5 (inlined slice_from_raw_parts::<()>) {
|
||||
|
|
@ -35,40 +37,54 @@
|
|||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
- StorageLive(_2);
|
||||
+ nop;
|
||||
StorageLive(_3);
|
||||
_3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue];
|
||||
StorageLive(_4);
|
||||
- _4 = ();
|
||||
- _3 = Box::<()>::new(move _4) -> [return: bb1, unwind continue];
|
||||
+ _4 = const ();
|
||||
+ _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_4);
|
||||
_2 = &_3;
|
||||
_1 = copy _2;
|
||||
StorageDead(_2);
|
||||
StorageLive(_4);
|
||||
_11 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>);
|
||||
_9 = copy _11 as *const () (Transmute);
|
||||
_4 = copy _9;
|
||||
_1 = &(*_2);
|
||||
- StorageDead(_2);
|
||||
- StorageLive(_5);
|
||||
- _10 = copy (*_1);
|
||||
+ nop;
|
||||
+ nop;
|
||||
+ _10 = copy (*_2);
|
||||
_11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute);
|
||||
_5 = &raw const (*_11);
|
||||
- StorageLive(_6);
|
||||
+ nop;
|
||||
StorageLive(_6);
|
||||
- _6 = copy _4;
|
||||
+ _6 = copy _9;
|
||||
StorageLive(_10);
|
||||
_10 = const 1_usize;
|
||||
- _5 = *const [()] from (copy _6, copy _10);
|
||||
+ _5 = *const [()] from (copy _9, const 1_usize);
|
||||
StorageDead(_10);
|
||||
StorageDead(_6);
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
_8 = copy _5;
|
||||
- _7 = copy _8 as *mut () (PtrToPtr);
|
||||
+ _7 = copy _11 as *mut () (Transmute);
|
||||
StorageDead(_8);
|
||||
_7 = copy _5;
|
||||
StorageLive(_12);
|
||||
_12 = const 1_usize;
|
||||
- _6 = *const [()] from (copy _7, copy _12);
|
||||
+ _6 = *const [()] from (copy _5, const 1_usize);
|
||||
StorageDead(_12);
|
||||
StorageDead(_7);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
_9 = copy _6;
|
||||
StorageLive(_13);
|
||||
- _13 = copy _9;
|
||||
- _8 = copy _9 as *mut () (PtrToPtr);
|
||||
+ _13 = copy _6;
|
||||
+ _8 = copy _5 as *mut () (PtrToPtr);
|
||||
StorageDead(_13);
|
||||
StorageDead(_9);
|
||||
_0 = const ();
|
||||
StorageDead(_8);
|
||||
- StorageDead(_6);
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
StorageDead(_4);
|
||||
+ nop;
|
||||
drop(_3) -> [return: bb2, unwind: bb3];
|
||||
}
|
||||
|
||||
|
|
|
|||
12
tests/mir-opt/pre-codegen/two_unwrap_unchecked.rs
Normal file
12
tests/mir-opt/pre-codegen/two_unwrap_unchecked.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// skip-filecheck
|
||||
//@ compile-flags: -O
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// EMIT_MIR two_unwrap_unchecked.two_unwrap_unchecked.GVN.diff
|
||||
// EMIT_MIR two_unwrap_unchecked.two_unwrap_unchecked.PreCodegen.after.mir
|
||||
pub fn two_unwrap_unchecked(v: &Option<i32>) -> i32 {
|
||||
let v1 = unsafe { v.unwrap_unchecked() };
|
||||
let v2 = unsafe { v.unwrap_unchecked() };
|
||||
v1 + v2
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
- // MIR for `two_unwrap_unchecked` before GVN
|
||||
+ // MIR for `two_unwrap_unchecked` after GVN
|
||||
|
||||
fn two_unwrap_unchecked(_1: &Option<i32>) -> i32 {
|
||||
debug v => _1;
|
||||
let mut _0: i32;
|
||||
let _2: i32;
|
||||
let mut _3: std::option::Option<i32>;
|
||||
let mut _5: std::option::Option<i32>;
|
||||
let mut _6: i32;
|
||||
let mut _7: i32;
|
||||
scope 1 {
|
||||
debug v1 => _2;
|
||||
let _4: i32;
|
||||
scope 2 {
|
||||
debug v2 => _4;
|
||||
}
|
||||
scope 8 (inlined #[track_caller] Option::<i32>::unwrap_unchecked) {
|
||||
let mut _9: isize;
|
||||
scope 9 {
|
||||
}
|
||||
scope 10 (inlined #[track_caller] unreachable_unchecked) {
|
||||
scope 11 (inlined core::ub_checks::check_language_ub) {
|
||||
scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 3 (inlined #[track_caller] Option::<i32>::unwrap_unchecked) {
|
||||
let mut _8: isize;
|
||||
scope 4 {
|
||||
}
|
||||
scope 5 (inlined #[track_caller] unreachable_unchecked) {
|
||||
scope 6 (inlined core::ub_checks::check_language_ub) {
|
||||
scope 7 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_2);
|
||||
+ nop;
|
||||
StorageLive(_3);
|
||||
_3 = copy (*_1);
|
||||
StorageLive(_8);
|
||||
_8 = discriminant(_3);
|
||||
switchInt(move _8) -> [0: bb2, 1: bb3, otherwise: bb1];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
_2 = move ((_3 as Some).0: i32);
|
||||
StorageDead(_8);
|
||||
StorageDead(_3);
|
||||
- StorageLive(_4);
|
||||
+ nop;
|
||||
StorageLive(_5);
|
||||
_5 = copy (*_1);
|
||||
StorageLive(_9);
|
||||
_9 = discriminant(_5);
|
||||
switchInt(move _9) -> [0: bb4, 1: bb5, otherwise: bb1];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb5: {
|
||||
_4 = move ((_5 as Some).0: i32);
|
||||
StorageDead(_9);
|
||||
StorageDead(_5);
|
||||
StorageLive(_6);
|
||||
_6 = copy _2;
|
||||
StorageLive(_7);
|
||||
_7 = copy _4;
|
||||
- _0 = Add(move _6, move _7);
|
||||
+ _0 = Add(copy _2, copy _4);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
- StorageDead(_4);
|
||||
- StorageDead(_2);
|
||||
+ nop;
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
// MIR for `two_unwrap_unchecked` after PreCodegen
|
||||
|
||||
fn two_unwrap_unchecked(_1: &Option<i32>) -> i32 {
|
||||
debug v => _1;
|
||||
let mut _0: i32;
|
||||
let mut _2: std::option::Option<i32>;
|
||||
let _4: i32;
|
||||
let mut _5: std::option::Option<i32>;
|
||||
scope 1 {
|
||||
debug v1 => _4;
|
||||
let _7: i32;
|
||||
scope 2 {
|
||||
debug v2 => _7;
|
||||
}
|
||||
scope 8 (inlined #[track_caller] Option::<i32>::unwrap_unchecked) {
|
||||
let mut _6: isize;
|
||||
scope 9 {
|
||||
}
|
||||
scope 10 (inlined #[track_caller] unreachable_unchecked) {
|
||||
scope 11 (inlined core::ub_checks::check_language_ub) {
|
||||
scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 3 (inlined #[track_caller] Option::<i32>::unwrap_unchecked) {
|
||||
let mut _3: isize;
|
||||
scope 4 {
|
||||
}
|
||||
scope 5 (inlined #[track_caller] unreachable_unchecked) {
|
||||
scope 6 (inlined core::ub_checks::check_language_ub) {
|
||||
scope 7 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
_2 = copy (*_1);
|
||||
StorageLive(_3);
|
||||
_3 = discriminant(_2);
|
||||
switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb3];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_4 = move ((_2 as Some).0: i32);
|
||||
StorageDead(_3);
|
||||
StorageDead(_2);
|
||||
StorageLive(_5);
|
||||
_5 = copy (*_1);
|
||||
StorageLive(_6);
|
||||
_6 = discriminant(_5);
|
||||
switchInt(move _6) -> [0: bb3, 1: bb2, otherwise: bb3];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_7 = move ((_5 as Some).0: i32);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
_0 = Add(copy _4, copy _7);
|
||||
return;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
- // MIR for `main` before SimplifyConstCondition-after-const-prop
|
||||
+ // MIR for `main` after SimplifyConstCondition-after-const-prop
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
|
||||
bb0: {
|
||||
- switchInt(const false) -> [0: bb2, otherwise: bb1];
|
||||
+ goto -> bb2;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_1 = noop() -> [return: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
- // MIR for `main` before SimplifyConstCondition-after-const-prop
|
||||
+ // MIR for `main` after SimplifyConstCondition-after-const-prop
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
|
||||
bb0: {
|
||||
- switchInt(const false) -> [0: bb2, otherwise: bb1];
|
||||
+ goto -> bb2;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_1 = noop() -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
- // MIR for `main` before SimplifyConstCondition-after-inst-simplify
|
||||
+ // MIR for `main` after SimplifyConstCondition-after-inst-simplify
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let mut _1: bool;
|
||||
let _2: ();
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = const false;
|
||||
- switchInt(move _1) -> [0: bb2, otherwise: bb1];
|
||||
+ goto -> bb2;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_2 = noop() -> [return: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
- // MIR for `main` before SimplifyConstCondition-after-inst-simplify
|
||||
+ // MIR for `main` after SimplifyConstCondition-after-inst-simplify
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let mut _1: bool;
|
||||
let _2: ();
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = const false;
|
||||
- switchInt(move _1) -> [0: bb2, otherwise: bb1];
|
||||
+ goto -> bb2;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_2 = noop() -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
#[inline(never)]
|
||||
fn noop() {}
|
||||
|
||||
// EMIT_MIR simplify_if.main.SimplifyConstCondition-after-const-prop.diff
|
||||
// EMIT_MIR simplify_if.main.SimplifyConstCondition-after-inst-simplify.diff
|
||||
fn main() {
|
||||
// CHECK-LABEL: fn main(
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue