mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Fix insertion of statements to be executed along return edge in inlining
Inlining creates additional statements to be executed along the return edge: an assignment to the destination, storage end for temporaries. Previously those statements where inserted directly into a call target, but this is incorrect when the target has other predecessors. Avoid the issue by creating a new dedicated block for those statements. When the block happens to be redundant it will be removed by CFG simplification that follows inlining. Fixes #117355
This commit is contained in:
parent
525a64fa81
commit
1be1c2ebcf
@ -32,7 +32,6 @@ struct CallSite<'tcx> {
|
||||
callee: Instance<'tcx>,
|
||||
fn_sig: ty::PolyFnSig<'tcx>,
|
||||
block: BasicBlock,
|
||||
target: Option<BasicBlock>,
|
||||
source_info: SourceInfo,
|
||||
}
|
||||
|
||||
@ -367,7 +366,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||
) -> Option<CallSite<'tcx>> {
|
||||
// Only consider direct calls to functions
|
||||
let terminator = bb_data.terminator();
|
||||
if let TerminatorKind::Call { ref func, target, fn_span, .. } = terminator.kind {
|
||||
if let TerminatorKind::Call { ref func, fn_span, .. } = terminator.kind {
|
||||
let func_ty = func.ty(caller_body, self.tcx);
|
||||
if let ty::FnDef(def_id, args) = *func_ty.kind() {
|
||||
// To resolve an instance its args have to be fully normalized.
|
||||
@ -386,7 +385,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||
let fn_sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args);
|
||||
let source_info = SourceInfo { span: fn_span, ..terminator.source_info };
|
||||
|
||||
return Some(CallSite { callee, fn_sig, block: bb, target, source_info });
|
||||
return Some(CallSite { callee, fn_sig, block: bb, source_info });
|
||||
}
|
||||
}
|
||||
|
||||
@ -541,10 +540,23 @@ impl<'tcx> Inliner<'tcx> {
|
||||
mut callee_body: Body<'tcx>,
|
||||
) {
|
||||
let terminator = caller_body[callsite.block].terminator.take().unwrap();
|
||||
let TerminatorKind::Call { args, destination, unwind, .. } = terminator.kind else {
|
||||
let TerminatorKind::Call { args, destination, unwind, target, .. } = terminator.kind else {
|
||||
bug!("unexpected terminator kind {:?}", terminator.kind);
|
||||
};
|
||||
|
||||
let return_block = if let Some(block) = target {
|
||||
// Prepare a new block for code that should execute when call returns. We don't use
|
||||
// target block directly since it might have other predecessors.
|
||||
let mut data = BasicBlockData::new(Some(Terminator {
|
||||
source_info: terminator.source_info,
|
||||
kind: TerminatorKind::Goto { target: block },
|
||||
}));
|
||||
data.is_cleanup = caller_body[block].is_cleanup;
|
||||
Some(caller_body.basic_blocks_mut().push(data))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// If the call is something like `a[*i] = f(i)`, where
|
||||
// `i : &mut usize`, then just duplicating the `a[*i]`
|
||||
// Place could result in two different locations if `f`
|
||||
@ -569,7 +581,8 @@ impl<'tcx> Inliner<'tcx> {
|
||||
destination,
|
||||
);
|
||||
let dest_ty = dest.ty(caller_body, self.tcx);
|
||||
let temp = Place::from(self.new_call_temp(caller_body, &callsite, dest_ty));
|
||||
let temp =
|
||||
Place::from(self.new_call_temp(caller_body, &callsite, dest_ty, return_block));
|
||||
caller_body[callsite.block].statements.push(Statement {
|
||||
source_info: callsite.source_info,
|
||||
kind: StatementKind::Assign(Box::new((temp, dest))),
|
||||
@ -590,12 +603,14 @@ impl<'tcx> Inliner<'tcx> {
|
||||
caller_body,
|
||||
&callsite,
|
||||
destination.ty(caller_body, self.tcx).ty,
|
||||
return_block,
|
||||
),
|
||||
)
|
||||
};
|
||||
|
||||
// Copy the arguments if needed.
|
||||
let args: Vec<_> = self.make_call_args(args, &callsite, caller_body, &callee_body);
|
||||
let args: Vec<_> =
|
||||
self.make_call_args(args, &callsite, caller_body, &callee_body, return_block);
|
||||
|
||||
let mut integrator = Integrator {
|
||||
args: &args,
|
||||
@ -607,6 +622,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||
callsite,
|
||||
cleanup_block: unwind,
|
||||
in_cleanup_block: false,
|
||||
return_block,
|
||||
tcx: self.tcx,
|
||||
always_live_locals: BitSet::new_filled(callee_body.local_decls.len()),
|
||||
};
|
||||
@ -626,7 +642,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||
});
|
||||
}
|
||||
}
|
||||
if let Some(block) = callsite.target {
|
||||
if let Some(block) = return_block {
|
||||
// To avoid repeated O(n) insert, push any new statements to the end and rotate
|
||||
// the slice once.
|
||||
let mut n = 0;
|
||||
@ -684,6 +700,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||
callsite: &CallSite<'tcx>,
|
||||
caller_body: &mut Body<'tcx>,
|
||||
callee_body: &Body<'tcx>,
|
||||
return_block: Option<BasicBlock>,
|
||||
) -> Vec<Local> {
|
||||
let tcx = self.tcx;
|
||||
|
||||
@ -712,8 +729,18 @@ impl<'tcx> Inliner<'tcx> {
|
||||
// and the vector is `[closure_ref, tmp0, tmp1, tmp2]`.
|
||||
if callsite.fn_sig.abi() == Abi::RustCall && callee_body.spread_arg.is_none() {
|
||||
let mut args = args.into_iter();
|
||||
let self_ = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body);
|
||||
let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body);
|
||||
let self_ = self.create_temp_if_necessary(
|
||||
args.next().unwrap(),
|
||||
callsite,
|
||||
caller_body,
|
||||
return_block,
|
||||
);
|
||||
let tuple = self.create_temp_if_necessary(
|
||||
args.next().unwrap(),
|
||||
callsite,
|
||||
caller_body,
|
||||
return_block,
|
||||
);
|
||||
assert!(args.next().is_none());
|
||||
|
||||
let tuple = Place::from(tuple);
|
||||
@ -730,13 +757,13 @@ impl<'tcx> Inliner<'tcx> {
|
||||
let tuple_field = Operand::Move(tcx.mk_place_field(tuple, FieldIdx::new(i), ty));
|
||||
|
||||
// Spill to a local to make e.g., `tmp0`.
|
||||
self.create_temp_if_necessary(tuple_field, callsite, caller_body)
|
||||
self.create_temp_if_necessary(tuple_field, callsite, caller_body, return_block)
|
||||
});
|
||||
|
||||
closure_ref_arg.chain(tuple_tmp_args).collect()
|
||||
} else {
|
||||
args.into_iter()
|
||||
.map(|a| self.create_temp_if_necessary(a, callsite, caller_body))
|
||||
.map(|a| self.create_temp_if_necessary(a, callsite, caller_body, return_block))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
@ -748,6 +775,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||
arg: Operand<'tcx>,
|
||||
callsite: &CallSite<'tcx>,
|
||||
caller_body: &mut Body<'tcx>,
|
||||
return_block: Option<BasicBlock>,
|
||||
) -> Local {
|
||||
// Reuse the operand if it is a moved temporary.
|
||||
if let Operand::Move(place) = &arg
|
||||
@ -760,7 +788,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||
// Otherwise, create a temporary for the argument.
|
||||
trace!("creating temp for argument {:?}", arg);
|
||||
let arg_ty = arg.ty(caller_body, self.tcx);
|
||||
let local = self.new_call_temp(caller_body, callsite, arg_ty);
|
||||
let local = self.new_call_temp(caller_body, callsite, arg_ty, return_block);
|
||||
caller_body[callsite.block].statements.push(Statement {
|
||||
source_info: callsite.source_info,
|
||||
kind: StatementKind::Assign(Box::new((Place::from(local), Rvalue::Use(arg)))),
|
||||
@ -774,6 +802,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||
caller_body: &mut Body<'tcx>,
|
||||
callsite: &CallSite<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
return_block: Option<BasicBlock>,
|
||||
) -> Local {
|
||||
let local = caller_body.local_decls.push(LocalDecl::new(ty, callsite.source_info.span));
|
||||
|
||||
@ -782,7 +811,7 @@ impl<'tcx> Inliner<'tcx> {
|
||||
kind: StatementKind::StorageLive(local),
|
||||
});
|
||||
|
||||
if let Some(block) = callsite.target {
|
||||
if let Some(block) = return_block {
|
||||
caller_body[block].statements.insert(
|
||||
0,
|
||||
Statement {
|
||||
@ -813,6 +842,7 @@ struct Integrator<'a, 'tcx> {
|
||||
callsite: &'a CallSite<'tcx>,
|
||||
cleanup_block: UnwindAction,
|
||||
in_cleanup_block: bool,
|
||||
return_block: Option<BasicBlock>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
always_live_locals: BitSet<Local>,
|
||||
}
|
||||
@ -956,7 +986,7 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
|
||||
*unwind = self.map_unwind(*unwind);
|
||||
}
|
||||
TerminatorKind::Return => {
|
||||
terminator.kind = if let Some(tgt) = self.callsite.target {
|
||||
terminator.kind = if let Some(tgt) = self.return_block {
|
||||
TerminatorKind::Goto { target: tgt }
|
||||
} else {
|
||||
TerminatorKind::Unreachable
|
||||
|
@ -69,58 +69,58 @@
|
||||
+ }
|
||||
+
|
||||
+ bb2: {
|
||||
+ StorageDead(_7);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
+ _3 = <() as F>::call() -> [return: bb3, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb3: {
|
||||
+ _4 = <() as F>::call() -> [return: bb1, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb3: {
|
||||
+ StorageDead(_7);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
+ _3 = <() as F>::call() -> [return: bb2, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb4: {
|
||||
+ StorageDead(_10);
|
||||
+ StorageDead(_9);
|
||||
+ StorageDead(_8);
|
||||
+ _6 = <() as E>::call() -> [return: bb5, unwind unreachable];
|
||||
+ _7 = <() as E>::call() -> [return: bb3, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb5: {
|
||||
+ _7 = <() as E>::call() -> [return: bb2, unwind unreachable];
|
||||
+ StorageDead(_10);
|
||||
+ StorageDead(_9);
|
||||
+ StorageDead(_8);
|
||||
+ _6 = <() as E>::call() -> [return: bb4, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb6: {
|
||||
+ StorageDead(_13);
|
||||
+ StorageDead(_12);
|
||||
+ StorageDead(_11);
|
||||
+ _9 = <() as D>::call() -> [return: bb7, unwind unreachable];
|
||||
+ _10 = <() as D>::call() -> [return: bb5, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb7: {
|
||||
+ _10 = <() as D>::call() -> [return: bb4, unwind unreachable];
|
||||
+ StorageDead(_13);
|
||||
+ StorageDead(_12);
|
||||
+ StorageDead(_11);
|
||||
+ _9 = <() as D>::call() -> [return: bb6, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb8: {
|
||||
+ StorageDead(_16);
|
||||
+ StorageDead(_15);
|
||||
+ StorageDead(_14);
|
||||
+ _12 = <() as C>::call() -> [return: bb9, unwind unreachable];
|
||||
+ _13 = <() as C>::call() -> [return: bb7, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb9: {
|
||||
+ _13 = <() as C>::call() -> [return: bb6, unwind unreachable];
|
||||
+ StorageDead(_16);
|
||||
+ StorageDead(_15);
|
||||
+ StorageDead(_14);
|
||||
+ _12 = <() as C>::call() -> [return: bb8, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb10: {
|
||||
+ StorageDead(_19);
|
||||
+ StorageDead(_18);
|
||||
+ StorageDead(_17);
|
||||
+ _15 = <() as B>::call() -> [return: bb11, unwind unreachable];
|
||||
+ _16 = <() as B>::call() -> [return: bb9, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb11: {
|
||||
+ _16 = <() as B>::call() -> [return: bb8, unwind unreachable];
|
||||
+ StorageDead(_19);
|
||||
+ StorageDead(_18);
|
||||
+ StorageDead(_17);
|
||||
+ _15 = <() as B>::call() -> [return: bb10, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb12: {
|
||||
@ -128,7 +128,7 @@
|
||||
+ }
|
||||
+
|
||||
+ bb13: {
|
||||
+ _19 = <() as A>::call() -> [return: bb10, unwind unreachable];
|
||||
+ _19 = <() as A>::call() -> [return: bb11, unwind unreachable];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,58 +69,58 @@
|
||||
+ }
|
||||
+
|
||||
+ bb2: {
|
||||
+ StorageDead(_7);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
+ _3 = <() as F>::call() -> [return: bb3, unwind continue];
|
||||
+ }
|
||||
+
|
||||
+ bb3: {
|
||||
+ _4 = <() as F>::call() -> [return: bb1, unwind continue];
|
||||
+ }
|
||||
+
|
||||
+ bb3: {
|
||||
+ StorageDead(_7);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
+ _3 = <() as F>::call() -> [return: bb2, unwind continue];
|
||||
+ }
|
||||
+
|
||||
+ bb4: {
|
||||
+ StorageDead(_10);
|
||||
+ StorageDead(_9);
|
||||
+ StorageDead(_8);
|
||||
+ _6 = <() as E>::call() -> [return: bb5, unwind continue];
|
||||
+ _7 = <() as E>::call() -> [return: bb3, unwind continue];
|
||||
+ }
|
||||
+
|
||||
+ bb5: {
|
||||
+ _7 = <() as E>::call() -> [return: bb2, unwind continue];
|
||||
+ StorageDead(_10);
|
||||
+ StorageDead(_9);
|
||||
+ StorageDead(_8);
|
||||
+ _6 = <() as E>::call() -> [return: bb4, unwind continue];
|
||||
+ }
|
||||
+
|
||||
+ bb6: {
|
||||
+ StorageDead(_13);
|
||||
+ StorageDead(_12);
|
||||
+ StorageDead(_11);
|
||||
+ _9 = <() as D>::call() -> [return: bb7, unwind continue];
|
||||
+ _10 = <() as D>::call() -> [return: bb5, unwind continue];
|
||||
+ }
|
||||
+
|
||||
+ bb7: {
|
||||
+ _10 = <() as D>::call() -> [return: bb4, unwind continue];
|
||||
+ StorageDead(_13);
|
||||
+ StorageDead(_12);
|
||||
+ StorageDead(_11);
|
||||
+ _9 = <() as D>::call() -> [return: bb6, unwind continue];
|
||||
+ }
|
||||
+
|
||||
+ bb8: {
|
||||
+ StorageDead(_16);
|
||||
+ StorageDead(_15);
|
||||
+ StorageDead(_14);
|
||||
+ _12 = <() as C>::call() -> [return: bb9, unwind continue];
|
||||
+ _13 = <() as C>::call() -> [return: bb7, unwind continue];
|
||||
+ }
|
||||
+
|
||||
+ bb9: {
|
||||
+ _13 = <() as C>::call() -> [return: bb6, unwind continue];
|
||||
+ StorageDead(_16);
|
||||
+ StorageDead(_15);
|
||||
+ StorageDead(_14);
|
||||
+ _12 = <() as C>::call() -> [return: bb8, unwind continue];
|
||||
+ }
|
||||
+
|
||||
+ bb10: {
|
||||
+ StorageDead(_19);
|
||||
+ StorageDead(_18);
|
||||
+ StorageDead(_17);
|
||||
+ _15 = <() as B>::call() -> [return: bb11, unwind continue];
|
||||
+ _16 = <() as B>::call() -> [return: bb9, unwind continue];
|
||||
+ }
|
||||
+
|
||||
+ bb11: {
|
||||
+ _16 = <() as B>::call() -> [return: bb8, unwind continue];
|
||||
+ StorageDead(_19);
|
||||
+ StorageDead(_18);
|
||||
+ StorageDead(_17);
|
||||
+ _15 = <() as B>::call() -> [return: bb10, unwind continue];
|
||||
+ }
|
||||
+
|
||||
+ bb12: {
|
||||
@ -128,7 +128,7 @@
|
||||
+ }
|
||||
+
|
||||
+ bb13: {
|
||||
+ _19 = <() as A>::call() -> [return: bb10, unwind continue];
|
||||
+ _19 = <() as A>::call() -> [return: bb11, unwind continue];
|
||||
}
|
||||
}
|
||||
|
||||
|
42
tests/mir-opt/inline/indirect_destination.rs
Normal file
42
tests/mir-opt/inline/indirect_destination.rs
Normal file
@ -0,0 +1,42 @@
|
||||
// Test for inlining with an indirect destination place.
|
||||
//
|
||||
// unit-test: Inline
|
||||
// edition: 2021
|
||||
// needs-unwind
|
||||
#![crate_type = "lib"]
|
||||
#![feature(custom_mir, core_intrinsics)]
|
||||
use core::intrinsics::mir::*;
|
||||
|
||||
#[custom_mir(dialect = "runtime", phase = "initial")]
|
||||
// CHECK-LABEL: fn f(
|
||||
// CHECK: bb1: {
|
||||
// CHECK-NEXT: StorageLive([[A:.*]]);
|
||||
// CHECK-NEXT: [[A]] = &mut (*_1);
|
||||
// CHECK-NEXT: StorageLive([[B:.*]]);
|
||||
// CHECK-NEXT: [[B]] = const 42_u8;
|
||||
// CHECK-NEXT: (*[[A]]) = move [[B]];
|
||||
// CHECK-NEXT: StorageDead([[B]]);
|
||||
// CHECK-NEXT: StorageDead([[A]]);
|
||||
// CHECK-NEXT: goto -> bb1;
|
||||
// CHECK-NEXT: }
|
||||
pub fn f(a: *mut u8) {
|
||||
mir! {
|
||||
{
|
||||
Goto(bb1)
|
||||
}
|
||||
bb1 = {
|
||||
Call(*a = g(), bb1, UnwindUnreachable())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[custom_mir(dialect = "runtime", phase = "initial")]
|
||||
#[inline(always)]
|
||||
fn g() -> u8 {
|
||||
mir! {
|
||||
{
|
||||
RET = 42;
|
||||
Return()
|
||||
}
|
||||
}
|
||||
}
|
@ -50,20 +50,20 @@
|
||||
bb1: {
|
||||
- _3 = &mut _4;
|
||||
- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind unreachable];
|
||||
+ StorageDead(_7);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
+ StorageDead(_2);
|
||||
+ drop(_4) -> [return: bb2, unwind unreachable];
|
||||
+ StorageDead(_4);
|
||||
+ _0 = const ();
|
||||
+ StorageDead(_1);
|
||||
+ return;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- StorageDead(_3);
|
||||
- _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine<bool>>::resume(move _2, const false) -> [return: bb3, unwind unreachable];
|
||||
+ StorageDead(_4);
|
||||
+ _0 = const ();
|
||||
+ StorageDead(_1);
|
||||
+ return;
|
||||
+ StorageDead(_7);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
+ StorageDead(_2);
|
||||
+ drop(_4) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
@ -90,7 +90,7 @@
|
||||
+ bb6: {
|
||||
+ _1 = CoroutineState::<i32, bool>::Yielded(move _8);
|
||||
+ discriminant((*_6)) = 3;
|
||||
+ goto -> bb1;
|
||||
+ goto -> bb2;
|
||||
+ }
|
||||
+
|
||||
+ bb7: {
|
||||
@ -102,7 +102,7 @@
|
||||
+ StorageDead(_8);
|
||||
+ _1 = CoroutineState::<i32, bool>::Complete(_5);
|
||||
+ discriminant((*_6)) = 1;
|
||||
+ goto -> bb1;
|
||||
+ goto -> bb2;
|
||||
+ }
|
||||
+
|
||||
+ bb9: {
|
||||
|
@ -34,18 +34,10 @@
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
- _4 = g() -> [return: bb1, unwind continue];
|
||||
- }
|
||||
-
|
||||
- bb1: {
|
||||
+ _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)};
|
||||
_3 = &mut _4;
|
||||
- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind: bb5];
|
||||
- }
|
||||
-
|
||||
- bb2: {
|
||||
+ _3 = &mut _4;
|
||||
+ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { pointer: move _3 };
|
||||
StorageDead(_3);
|
||||
- _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb5];
|
||||
+ StorageDead(_3);
|
||||
+ StorageLive(_5);
|
||||
+ _5 = const false;
|
||||
+ StorageLive(_6);
|
||||
@ -55,40 +47,50 @@
|
||||
+ switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _3 = &mut _4;
|
||||
- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind: bb5];
|
||||
+ StorageDead(_4);
|
||||
+ _0 = const ();
|
||||
+ StorageDead(_1);
|
||||
+ return;
|
||||
}
|
||||
|
||||
- bb2: {
|
||||
- StorageDead(_3);
|
||||
- _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb5];
|
||||
+ bb2 (cleanup): {
|
||||
+ drop(_4) -> [return: bb3, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
- bb3: {
|
||||
+ bb1: {
|
||||
- StorageDead(_2);
|
||||
- drop(_4) -> [return: bb4, unwind: bb6];
|
||||
+ bb3 (cleanup): {
|
||||
+ resume;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
- StorageDead(_4);
|
||||
- _0 = const ();
|
||||
- StorageDead(_1);
|
||||
- return;
|
||||
+ StorageDead(_7);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
StorageDead(_2);
|
||||
- drop(_4) -> [return: bb4, unwind: bb6];
|
||||
+ drop(_4) -> [return: bb2, unwind: bb4];
|
||||
}
|
||||
|
||||
- bb4: {
|
||||
+ bb2: {
|
||||
StorageDead(_4);
|
||||
_0 = const ();
|
||||
StorageDead(_1);
|
||||
return;
|
||||
+ StorageDead(_2);
|
||||
+ drop(_4) -> [return: bb1, unwind: bb3];
|
||||
}
|
||||
|
||||
- bb5 (cleanup): {
|
||||
- drop(_4) -> [return: bb6, unwind terminate(cleanup)];
|
||||
+ bb3 (cleanup): {
|
||||
+ drop(_4) -> [return: bb4, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
- bb6 (cleanup): {
|
||||
+ bb4 (cleanup): {
|
||||
resume;
|
||||
+ }
|
||||
+
|
||||
+ bb5: {
|
||||
+ StorageLive(_8);
|
||||
+ switchInt(_5) -> [0: bb6, otherwise: bb7];
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
- bb6 (cleanup): {
|
||||
- resume;
|
||||
+ bb6: {
|
||||
+ _8 = const 13_i32;
|
||||
+ goto -> bb8;
|
||||
@ -102,11 +104,11 @@
|
||||
+ bb8: {
|
||||
+ _1 = CoroutineState::<i32, bool>::Yielded(move _8);
|
||||
+ discriminant((*_6)) = 3;
|
||||
+ goto -> bb1;
|
||||
+ goto -> bb4;
|
||||
+ }
|
||||
+
|
||||
+ bb9: {
|
||||
+ assert(const false, "coroutine resumed after completion") -> [success: bb9, unwind: bb3];
|
||||
+ assert(const false, "coroutine resumed after completion") -> [success: bb9, unwind: bb2];
|
||||
+ }
|
||||
+
|
||||
+ bb10: {
|
||||
@ -114,7 +116,7 @@
|
||||
+ StorageDead(_8);
|
||||
+ _1 = CoroutineState::<i32, bool>::Complete(_5);
|
||||
+ discriminant((*_6)) = 1;
|
||||
+ goto -> bb1;
|
||||
+ goto -> bb4;
|
||||
+ }
|
||||
+
|
||||
+ bb11: {
|
||||
|
@ -1,209 +0,0 @@
|
||||
- // MIR for `main` before Inline
|
||||
+ // MIR for `main` after Inline
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let _1: std::boxed::Box<std::vec::Vec<u32>>;
|
||||
let mut _2: std::vec::Vec<u32>;
|
||||
scope 1 {
|
||||
debug _x => _1;
|
||||
}
|
||||
+ scope 2 (inlined Vec::<u32>::new) {
|
||||
+ let mut _3: alloc::raw_vec::RawVec<u32>;
|
||||
+ }
|
||||
+ scope 3 (inlined Box::<Vec<u32>>::new) {
|
||||
+ debug x => _2;
|
||||
+ let mut _4: usize;
|
||||
+ let mut _5: usize;
|
||||
+ let mut _6: *mut u8;
|
||||
+ let mut _7: *const std::vec::Vec<u32>;
|
||||
+ scope 4 {
|
||||
+ scope 5 (inlined alloc::alloc::exchange_malloc) {
|
||||
+ debug size => _4;
|
||||
+ debug align => _5;
|
||||
+ let _8: std::alloc::Layout;
|
||||
+ let mut _9: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
||||
+ let mut _10: isize;
|
||||
+ let mut _12: !;
|
||||
+ scope 6 {
|
||||
+ debug layout => _8;
|
||||
+ let _11: std::ptr::NonNull<[u8]>;
|
||||
+ let mut _13: &std::alloc::Global;
|
||||
+ scope 8 {
|
||||
+ debug ptr => _11;
|
||||
+ scope 18 (inlined NonNull::<[u8]>::as_mut_ptr) {
|
||||
+ debug self => _11;
|
||||
+ let mut _15: std::ptr::NonNull<u8>;
|
||||
+ scope 19 (inlined NonNull::<[u8]>::as_non_null_ptr) {
|
||||
+ debug self => _11;
|
||||
+ let mut _16: *mut u8;
|
||||
+ let mut _17: *mut [u8];
|
||||
+ scope 20 {
|
||||
+ scope 21 (inlined NonNull::<[u8]>::as_ptr) {
|
||||
+ debug self => _11;
|
||||
+ let mut _18: *const [u8];
|
||||
+ }
|
||||
+ scope 22 (inlined ptr::mut_ptr::<impl *mut [u8]>::as_mut_ptr) {
|
||||
+ debug self => _17;
|
||||
+ }
|
||||
+ scope 23 (inlined NonNull::<u8>::new_unchecked) {
|
||||
+ debug ptr => _16;
|
||||
+ let mut _19: *const u8;
|
||||
+ scope 24 {
|
||||
+ scope 25 (inlined NonNull::<T>::new_unchecked::runtime::<u8>) {
|
||||
+ debug ptr => _16;
|
||||
+ scope 26 (inlined ptr::mut_ptr::<impl *mut u8>::is_null) {
|
||||
+ debug self => _16;
|
||||
+ let mut _20: *mut u8;
|
||||
+ scope 27 {
|
||||
+ scope 28 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
|
||||
+ debug ptr => _20;
|
||||
+ scope 29 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
|
||||
+ debug self => _20;
|
||||
+ scope 30 {
|
||||
+ scope 31 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
|
||||
+ debug self => _20;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 32 (inlined NonNull::<u8>::as_ptr) {
|
||||
+ debug self => _15;
|
||||
+ let mut _21: *const u8;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 17 (inlined <std::alloc::Global as Allocator>::allocate) {
|
||||
+ debug self => const _;
|
||||
+ debug layout => _8;
|
||||
+ }
|
||||
+ }
|
||||
+ scope 7 {
|
||||
+ scope 9 (inlined Layout::from_size_align_unchecked) {
|
||||
+ debug size => _4;
|
||||
+ debug align => _5;
|
||||
+ let mut _14: std::ptr::Alignment;
|
||||
+ scope 10 {
|
||||
+ scope 11 (inlined std::ptr::Alignment::new_unchecked) {
|
||||
+ debug align => _5;
|
||||
+ scope 12 {
|
||||
+ scope 14 (inlined std::ptr::Alignment::new_unchecked::runtime) {
|
||||
+ debug align => _5;
|
||||
+ scope 15 (inlined core::num::<impl usize>::is_power_of_two) {
|
||||
+ debug self => _5;
|
||||
+ scope 16 (inlined core::num::<impl usize>::count_ones) {
|
||||
+ debug self => _5;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 13 {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
- _2 = Vec::<u32>::new() -> [return: bb1, unwind unreachable];
|
||||
+ StorageLive(_3);
|
||||
+ _3 = const _;
|
||||
+ _2 = Vec::<u32> { buf: move _3, len: const 0_usize };
|
||||
+ StorageDead(_3);
|
||||
+ StorageLive(_4);
|
||||
+ StorageLive(_5);
|
||||
+ StorageLive(_6);
|
||||
+ StorageLive(_7);
|
||||
+ _4 = SizeOf(std::vec::Vec<u32>);
|
||||
+ _5 = AlignOf(std::vec::Vec<u32>);
|
||||
+ StorageLive(_8);
|
||||
+ StorageLive(_10);
|
||||
+ StorageLive(_11);
|
||||
+ StorageLive(_12);
|
||||
+ StorageLive(_13);
|
||||
+ StorageLive(_14);
|
||||
+ _14 = _5 as std::ptr::Alignment (Transmute);
|
||||
+ _8 = Layout { size: _4, align: move _14 };
|
||||
+ StorageDead(_14);
|
||||
+ StorageLive(_9);
|
||||
+ _13 = const _;
|
||||
+ _9 = std::alloc::Global::alloc_impl(move _13, _8, const false) -> [return: bb5, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _1 = Box::<Vec<u32>>::new(move _2) -> [return: bb2, unwind unreachable];
|
||||
+ StorageDead(_1);
|
||||
+ return;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
+ _12 = handle_alloc_error(move _8) -> unwind unreachable;
|
||||
+ }
|
||||
+
|
||||
+ bb3: {
|
||||
+ unreachable;
|
||||
+ }
|
||||
+
|
||||
+ bb4: {
|
||||
+ _11 = ((_9 as Ok).0: std::ptr::NonNull<[u8]>);
|
||||
+ StorageLive(_15);
|
||||
+ StorageLive(_16);
|
||||
+ StorageLive(_17);
|
||||
+ StorageLive(_18);
|
||||
+ _18 = (_11.0: *const [u8]);
|
||||
+ _17 = move _18 as *mut [u8] (PtrToPtr);
|
||||
+ StorageDead(_18);
|
||||
+ _16 = _17 as *mut u8 (PtrToPtr);
|
||||
+ StorageDead(_17);
|
||||
+ StorageLive(_19);
|
||||
+ StorageLive(_20);
|
||||
+ _19 = _16 as *const u8 (PointerCoercion(MutToConstPointer));
|
||||
+ _15 = NonNull::<u8> { pointer: _19 };
|
||||
+ StorageDead(_20);
|
||||
+ StorageDead(_19);
|
||||
+ StorageDead(_16);
|
||||
+ StorageLive(_21);
|
||||
+ _21 = (_15.0: *const u8);
|
||||
+ _6 = move _21 as *mut u8 (PtrToPtr);
|
||||
+ StorageDead(_21);
|
||||
+ StorageDead(_15);
|
||||
+ StorageDead(_9);
|
||||
+ StorageDead(_13);
|
||||
+ StorageDead(_12);
|
||||
+ StorageDead(_11);
|
||||
+ StorageDead(_10);
|
||||
+ StorageDead(_8);
|
||||
+ _1 = ShallowInitBox(move _6, std::vec::Vec<u32>);
|
||||
+ _7 = (((_1.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>);
|
||||
+ (*_7) = move _2;
|
||||
+ StorageDead(_7);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
+ StorageDead(_4);
|
||||
StorageDead(_2);
|
||||
_0 = const ();
|
||||
- drop(_1) -> [return: bb3, unwind unreachable];
|
||||
+ drop(_1) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
- bb3: {
|
||||
- StorageDead(_1);
|
||||
- return;
|
||||
+ bb5: {
|
||||
+ _10 = discriminant(_9);
|
||||
+ switchInt(move _10) -> [0: bb4, 1: bb2, otherwise: bb3];
|
||||
}
|
||||
}
|
||||
|
@ -1,222 +0,0 @@
|
||||
- // MIR for `main` before Inline
|
||||
+ // MIR for `main` after Inline
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let _1: std::boxed::Box<std::vec::Vec<u32>>;
|
||||
let mut _2: std::vec::Vec<u32>;
|
||||
scope 1 {
|
||||
debug _x => _1;
|
||||
}
|
||||
+ scope 2 (inlined Vec::<u32>::new) {
|
||||
+ let mut _3: alloc::raw_vec::RawVec<u32>;
|
||||
+ }
|
||||
+ scope 3 (inlined Box::<Vec<u32>>::new) {
|
||||
+ debug x => _2;
|
||||
+ let mut _4: usize;
|
||||
+ let mut _5: usize;
|
||||
+ let mut _6: *mut u8;
|
||||
+ let mut _7: *const std::vec::Vec<u32>;
|
||||
+ scope 4 {
|
||||
+ scope 5 (inlined alloc::alloc::exchange_malloc) {
|
||||
+ debug size => _4;
|
||||
+ debug align => _5;
|
||||
+ let _8: std::alloc::Layout;
|
||||
+ let mut _9: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
||||
+ let mut _10: isize;
|
||||
+ let mut _12: !;
|
||||
+ scope 6 {
|
||||
+ debug layout => _8;
|
||||
+ let _11: std::ptr::NonNull<[u8]>;
|
||||
+ let mut _13: &std::alloc::Global;
|
||||
+ scope 8 {
|
||||
+ debug ptr => _11;
|
||||
+ scope 18 (inlined NonNull::<[u8]>::as_mut_ptr) {
|
||||
+ debug self => _11;
|
||||
+ let mut _15: std::ptr::NonNull<u8>;
|
||||
+ scope 19 (inlined NonNull::<[u8]>::as_non_null_ptr) {
|
||||
+ debug self => _11;
|
||||
+ let mut _16: *mut u8;
|
||||
+ let mut _17: *mut [u8];
|
||||
+ scope 20 {
|
||||
+ scope 21 (inlined NonNull::<[u8]>::as_ptr) {
|
||||
+ debug self => _11;
|
||||
+ let mut _18: *const [u8];
|
||||
+ }
|
||||
+ scope 22 (inlined ptr::mut_ptr::<impl *mut [u8]>::as_mut_ptr) {
|
||||
+ debug self => _17;
|
||||
+ }
|
||||
+ scope 23 (inlined NonNull::<u8>::new_unchecked) {
|
||||
+ debug ptr => _16;
|
||||
+ let mut _19: *const u8;
|
||||
+ scope 24 {
|
||||
+ scope 25 (inlined NonNull::<T>::new_unchecked::runtime::<u8>) {
|
||||
+ debug ptr => _16;
|
||||
+ scope 26 (inlined ptr::mut_ptr::<impl *mut u8>::is_null) {
|
||||
+ debug self => _16;
|
||||
+ let mut _20: *mut u8;
|
||||
+ scope 27 {
|
||||
+ scope 28 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
|
||||
+ debug ptr => _20;
|
||||
+ scope 29 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
|
||||
+ debug self => _20;
|
||||
+ scope 30 {
|
||||
+ scope 31 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
|
||||
+ debug self => _20;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 32 (inlined NonNull::<u8>::as_ptr) {
|
||||
+ debug self => _15;
|
||||
+ let mut _21: *const u8;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 17 (inlined <std::alloc::Global as Allocator>::allocate) {
|
||||
+ debug self => const _;
|
||||
+ debug layout => _8;
|
||||
+ }
|
||||
+ }
|
||||
+ scope 7 {
|
||||
+ scope 9 (inlined Layout::from_size_align_unchecked) {
|
||||
+ debug size => _4;
|
||||
+ debug align => _5;
|
||||
+ let mut _14: std::ptr::Alignment;
|
||||
+ scope 10 {
|
||||
+ scope 11 (inlined std::ptr::Alignment::new_unchecked) {
|
||||
+ debug align => _5;
|
||||
+ scope 12 {
|
||||
+ scope 14 (inlined std::ptr::Alignment::new_unchecked::runtime) {
|
||||
+ debug align => _5;
|
||||
+ scope 15 (inlined core::num::<impl usize>::is_power_of_two) {
|
||||
+ debug self => _5;
|
||||
+ scope 16 (inlined core::num::<impl usize>::count_ones) {
|
||||
+ debug self => _5;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 13 {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
- _2 = Vec::<u32>::new() -> [return: bb1, unwind continue];
|
||||
+ StorageLive(_3);
|
||||
+ _3 = const _;
|
||||
+ _2 = Vec::<u32> { buf: move _3, len: const 0_usize };
|
||||
+ StorageDead(_3);
|
||||
+ StorageLive(_4);
|
||||
+ StorageLive(_5);
|
||||
+ StorageLive(_6);
|
||||
+ StorageLive(_7);
|
||||
+ _4 = SizeOf(std::vec::Vec<u32>);
|
||||
+ _5 = AlignOf(std::vec::Vec<u32>);
|
||||
+ StorageLive(_8);
|
||||
+ StorageLive(_10);
|
||||
+ StorageLive(_11);
|
||||
+ StorageLive(_12);
|
||||
+ StorageLive(_13);
|
||||
+ StorageLive(_14);
|
||||
+ _14 = _5 as std::ptr::Alignment (Transmute);
|
||||
+ _8 = Layout { size: _4, align: move _14 };
|
||||
+ StorageDead(_14);
|
||||
+ StorageLive(_9);
|
||||
+ _13 = const _;
|
||||
+ _9 = std::alloc::Global::alloc_impl(move _13, _8, const false) -> [return: bb7, unwind: bb3];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _1 = Box::<Vec<u32>>::new(move _2) -> [return: bb2, unwind: bb4];
|
||||
+ StorageDead(_1);
|
||||
+ return;
|
||||
}
|
||||
|
||||
- bb2: {
|
||||
- StorageDead(_2);
|
||||
- _0 = const ();
|
||||
- drop(_1) -> [return: bb3, unwind: bb4];
|
||||
+ bb2 (cleanup): {
|
||||
+ resume;
|
||||
}
|
||||
|
||||
- bb3: {
|
||||
- StorageDead(_1);
|
||||
- return;
|
||||
+ bb3 (cleanup): {
|
||||
+ drop(_2) -> [return: bb2, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
- bb4 (cleanup): {
|
||||
- resume;
|
||||
+ bb4: {
|
||||
+ _12 = handle_alloc_error(move _8) -> bb3;
|
||||
+ }
|
||||
+
|
||||
+ bb5: {
|
||||
+ unreachable;
|
||||
+ }
|
||||
+
|
||||
+ bb6: {
|
||||
+ _11 = ((_9 as Ok).0: std::ptr::NonNull<[u8]>);
|
||||
+ StorageLive(_15);
|
||||
+ StorageLive(_16);
|
||||
+ StorageLive(_17);
|
||||
+ StorageLive(_18);
|
||||
+ _18 = (_11.0: *const [u8]);
|
||||
+ _17 = move _18 as *mut [u8] (PtrToPtr);
|
||||
+ StorageDead(_18);
|
||||
+ _16 = _17 as *mut u8 (PtrToPtr);
|
||||
+ StorageDead(_17);
|
||||
+ StorageLive(_19);
|
||||
+ StorageLive(_20);
|
||||
+ _19 = _16 as *const u8 (PointerCoercion(MutToConstPointer));
|
||||
+ _15 = NonNull::<u8> { pointer: _19 };
|
||||
+ StorageDead(_20);
|
||||
+ StorageDead(_19);
|
||||
+ StorageDead(_16);
|
||||
+ StorageLive(_21);
|
||||
+ _21 = (_15.0: *const u8);
|
||||
+ _6 = move _21 as *mut u8 (PtrToPtr);
|
||||
+ StorageDead(_21);
|
||||
+ StorageDead(_15);
|
||||
+ StorageDead(_9);
|
||||
+ StorageDead(_13);
|
||||
+ StorageDead(_12);
|
||||
+ StorageDead(_11);
|
||||
+ StorageDead(_10);
|
||||
+ StorageDead(_8);
|
||||
+ _1 = ShallowInitBox(move _6, std::vec::Vec<u32>);
|
||||
+ _7 = (((_1.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>);
|
||||
+ (*_7) = move _2;
|
||||
+ StorageDead(_7);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
+ StorageDead(_4);
|
||||
+ StorageDead(_2);
|
||||
+ _0 = const ();
|
||||
+ drop(_1) -> [return: bb1, unwind: bb2];
|
||||
+ }
|
||||
+
|
||||
+ bb7: {
|
||||
+ _10 = discriminant(_9);
|
||||
+ switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5];
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
// ignore-endian-big
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// ignore-debug MIR alignment checks in std alter the diff, breaking the test
|
||||
// compile-flags: -Zmir-opt-level=4 -Zinline-mir-hint-threshold=200
|
||||
|
||||
// EMIT_MIR inline_into_box_place.main.Inline.diff
|
||||
fn main() {
|
||||
// CHECK-LABEL: fn main(
|
||||
// CHECK: (inlined Box::<Vec<u32>>::new)
|
||||
let _x: Box<Vec<u32>> = Box::new(Vec::new());
|
||||
}
|
@ -60,16 +60,6 @@
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
StorageDead(_4);
|
||||
_5 = discriminant(_3);
|
||||
- switchInt(move _5) -> [0: bb2, 1: bb4, otherwise: bb3];
|
||||
+ goto -> bb2;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageLive(_9);
|
||||
_9 = ((_3 as Continue).0: i32);
|
||||
_2 = _9;
|
||||
@ -77,14 +67,14 @@
|
||||
_0 = Result::<i32, i32>::Ok(move _2);
|
||||
StorageDead(_2);
|
||||
StorageDead(_3);
|
||||
goto -> bb5;
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
bb2: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
bb3: {
|
||||
StorageLive(_6);
|
||||
_6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>);
|
||||
StorageLive(_8);
|
||||
@ -100,11 +90,21 @@
|
||||
StorageDead(_6);
|
||||
StorageDead(_2);
|
||||
StorageDead(_3);
|
||||
goto -> bb5;
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
return;
|
||||
}
|
||||
|
||||
bb5: {
|
||||
return;
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
StorageDead(_4);
|
||||
_5 = discriminant(_3);
|
||||
- switchInt(move _5) -> [0: bb1, 1: bb3, otherwise: bb2];
|
||||
+ goto -> bb1;
|
||||
}
|
||||
|
||||
bb6: {
|
||||
@ -113,7 +113,7 @@
|
||||
_13 = Result::<Infallible, i32>::Err(move _12);
|
||||
_3 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _13);
|
||||
StorageDead(_13);
|
||||
- goto -> bb1;
|
||||
- goto -> bb5;
|
||||
+ goto -> bb9;
|
||||
}
|
||||
|
||||
@ -124,7 +124,7 @@
|
||||
bb8: {
|
||||
_11 = move ((_4 as Ok).0: i32);
|
||||
_3 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(move _11);
|
||||
goto -> bb1;
|
||||
goto -> bb5;
|
||||
+ }
|
||||
+
|
||||
+ bb9: {
|
||||
@ -133,7 +133,7 @@
|
||||
+ StorageDead(_10);
|
||||
+ StorageDead(_4);
|
||||
+ _5 = discriminant(_3);
|
||||
+ goto -> bb4;
|
||||
+ goto -> bb3;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,16 +60,6 @@
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
StorageDead(_4);
|
||||
_5 = discriminant(_3);
|
||||
- switchInt(move _5) -> [0: bb2, 1: bb4, otherwise: bb3];
|
||||
+ goto -> bb2;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageLive(_9);
|
||||
_9 = ((_3 as Continue).0: i32);
|
||||
_2 = _9;
|
||||
@ -77,14 +67,14 @@
|
||||
_0 = Result::<i32, i32>::Ok(move _2);
|
||||
StorageDead(_2);
|
||||
StorageDead(_3);
|
||||
goto -> bb5;
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
bb2: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
bb3: {
|
||||
StorageLive(_6);
|
||||
_6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>);
|
||||
StorageLive(_8);
|
||||
@ -100,11 +90,21 @@
|
||||
StorageDead(_6);
|
||||
StorageDead(_2);
|
||||
StorageDead(_3);
|
||||
goto -> bb5;
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
return;
|
||||
}
|
||||
|
||||
bb5: {
|
||||
return;
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
StorageDead(_4);
|
||||
_5 = discriminant(_3);
|
||||
- switchInt(move _5) -> [0: bb1, 1: bb3, otherwise: bb2];
|
||||
+ goto -> bb1;
|
||||
}
|
||||
|
||||
bb6: {
|
||||
@ -113,7 +113,7 @@
|
||||
_13 = Result::<Infallible, i32>::Err(move _12);
|
||||
_3 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _13);
|
||||
StorageDead(_13);
|
||||
- goto -> bb1;
|
||||
- goto -> bb5;
|
||||
+ goto -> bb9;
|
||||
}
|
||||
|
||||
@ -124,7 +124,7 @@
|
||||
bb8: {
|
||||
_11 = move ((_4 as Ok).0: i32);
|
||||
_3 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(move _11);
|
||||
goto -> bb1;
|
||||
goto -> bb5;
|
||||
+ }
|
||||
+
|
||||
+ bb9: {
|
||||
@ -133,7 +133,7 @@
|
||||
+ StorageDead(_10);
|
||||
+ StorageDead(_4);
|
||||
+ _5 = discriminant(_3);
|
||||
+ goto -> bb4;
|
||||
+ goto -> bb3;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,19 +52,19 @@ fn identity(x: Result<i32, i32>) -> Result<i32, i32> {
|
||||
// CHECK: [[x:_.*]] = _1;
|
||||
// CHECK: switchInt(move {{_.*}}) -> [0: bb8, 1: bb6, otherwise: bb7];
|
||||
// CHECK: bb1: {
|
||||
// CHECK: goto -> bb2;
|
||||
// CHECK: bb2: {
|
||||
// CHECK: {{_.*}} = (([[controlflow:_.*]] as Continue).0: i32);
|
||||
// CHECK: _0 = Result::<i32, i32>::Ok(
|
||||
// CHECK: goto -> bb5;
|
||||
// CHECK: bb3: {
|
||||
// CHECK: goto -> bb4;
|
||||
// CHECK: bb2: {
|
||||
// CHECK: unreachable;
|
||||
// CHECK: bb4: {
|
||||
// CHECK: bb3: {
|
||||
// CHECK: {{_.*}} = (([[controlflow]] as Break).0: std::result::Result<std::convert::Infallible, i32>);
|
||||
// CHECK: _0 = Result::<i32, i32>::Err(
|
||||
// CHECK: goto -> bb5;
|
||||
// CHECK: bb5: {
|
||||
// CHECK: goto -> bb4;
|
||||
// CHECK: bb4: {
|
||||
// CHECK: return;
|
||||
// CHECK: bb5: {
|
||||
// CHECK: goto -> bb1;
|
||||
// CHECK: bb6: {
|
||||
// CHECK: {{_.*}} = move (([[x]] as Err).0: i32);
|
||||
// CHECK: [[controlflow]] = ControlFlow::<Result<Infallible, i32>, i32>::Break(
|
||||
@ -74,9 +74,9 @@ fn identity(x: Result<i32, i32>) -> Result<i32, i32> {
|
||||
// CHECK: bb8: {
|
||||
// CHECK: {{_.*}} = move (([[x]] as Ok).0: i32);
|
||||
// CHECK: [[controlflow]] = ControlFlow::<Result<Infallible, i32>, i32>::Continue(
|
||||
// CHECK: goto -> bb1;
|
||||
// CHECK: goto -> bb5;
|
||||
// CHECK: bb9: {
|
||||
// CHECK: goto -> bb4;
|
||||
// CHECK: goto -> bb3;
|
||||
Ok(x?)
|
||||
}
|
||||
|
||||
|
@ -52,29 +52,21 @@
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
_9 = discriminant(_1);
|
||||
switchInt(move _9) -> [0: bb6, 1: bb5, otherwise: bb3];
|
||||
switchInt(move _9) -> [0: bb6, 1: bb5, otherwise: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
_5 = discriminant(_3);
|
||||
switchInt(move _5) -> [0: bb2, 1: bb4, otherwise: bb3];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_8 = ((_3 as Continue).0: i32);
|
||||
_0 = Result::<i32, i32>::Ok(_8);
|
||||
StorageDead(_3);
|
||||
return;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
bb2: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
bb3: {
|
||||
_6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>);
|
||||
_13 = ((_6 as Err).0: i32);
|
||||
_0 = Result::<i32, i32>::Err(move _13);
|
||||
@ -82,19 +74,27 @@
|
||||
return;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
_5 = discriminant(_3);
|
||||
switchInt(move _5) -> [0: bb1, 1: bb3, otherwise: bb2];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
_11 = ((_1 as Err).0: i32);
|
||||
StorageLive(_12);
|
||||
_12 = Result::<Infallible, i32>::Err(move _11);
|
||||
_3 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _12);
|
||||
StorageDead(_12);
|
||||
goto -> bb1;
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb6: {
|
||||
_10 = ((_1 as Ok).0: i32);
|
||||
_3 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(move _10);
|
||||
goto -> bb1;
|
||||
goto -> bb4;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user