mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Auto merge of #113858 - cjgillot:const-prop-pairs, r=oli-obk
Always const-prop scalars and scalar pairs This removes some complexity from the pass. The limitation to propagate ScalarPairs only for tuple comes from https://github.com/rust-lang/rust/pull/67015, when ScalarPair constant were modeled using `Rvalue::Aggregate`. Nowadays, we use `ConstValue::ByRef`, which does not care about the underlying type. The justification for not propagating in all cases was perf. This seems not to be a clear cut any more: https://github.com/rust-lang/rust/pull/113858#issuecomment-1642396746
This commit is contained in:
commit
e2a7ba2771
@ -14,8 +14,7 @@ use rustc_middle::mir::visit::{
|
||||
};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
|
||||
use rustc_middle::ty::GenericArgs;
|
||||
use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{self, GenericArgs, Instance, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::{def_id::DefId, Span, DUMMY_SP};
|
||||
use rustc_target::abi::{self, Align, HasDataLayout, Size, TargetDataLayout};
|
||||
use rustc_target::spec::abi::Abi as CallAbi;
|
||||
@ -407,51 +406,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
ecx.machine.written_only_inside_own_block_locals.remove(&local);
|
||||
}
|
||||
|
||||
/// Returns the value, if any, of evaluating `c`.
|
||||
fn eval_constant(&mut self, c: &Constant<'tcx>) -> Option<OpTy<'tcx>> {
|
||||
// FIXME we need to revisit this for #67176
|
||||
if c.has_param() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// No span, we don't want errors to be shown.
|
||||
self.ecx.eval_mir_constant(&c.literal, None, None).ok()
|
||||
}
|
||||
|
||||
/// Returns the value, if any, of evaluating `place`.
|
||||
fn eval_place(&mut self, place: Place<'tcx>) -> Option<OpTy<'tcx>> {
|
||||
trace!("eval_place(place={:?})", place);
|
||||
self.ecx.eval_place_to_op(place, None).ok()
|
||||
}
|
||||
|
||||
/// Returns the value, if any, of evaluating `op`. Calls upon `eval_constant`
|
||||
/// or `eval_place`, depending on the variant of `Operand` used.
|
||||
fn eval_operand(&mut self, op: &Operand<'tcx>) -> Option<OpTy<'tcx>> {
|
||||
match *op {
|
||||
Operand::Constant(ref c) => self.eval_constant(c),
|
||||
Operand::Move(place) | Operand::Copy(place) => self.eval_place(place),
|
||||
}
|
||||
}
|
||||
|
||||
fn propagate_operand(&mut self, operand: &mut Operand<'tcx>) {
|
||||
match *operand {
|
||||
Operand::Copy(l) | Operand::Move(l) => {
|
||||
if let Some(value) = self.get_const(l) && self.should_const_prop(&value) {
|
||||
// FIXME(felix91gr): this code only handles `Scalar` cases.
|
||||
// For now, we're not handling `ScalarPair` cases because
|
||||
// doing so here would require a lot of code duplication.
|
||||
// We should hopefully generalize `Operand` handling into a fn,
|
||||
// and use it to do const-prop here and everywhere else
|
||||
// where it makes sense.
|
||||
if let interpret::Operand::Immediate(interpret::Immediate::Scalar(
|
||||
scalar,
|
||||
)) = *value
|
||||
{
|
||||
*operand = self.operand_from_scalar(scalar, value.layout.ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
Operand::Constant(_) => (),
|
||||
if let Some(place) = operand.place() && let Some(op) = self.replace_with_const(place) {
|
||||
*operand = op;
|
||||
}
|
||||
}
|
||||
|
||||
@ -579,93 +536,45 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
}))
|
||||
}
|
||||
|
||||
fn replace_with_const(&mut self, place: Place<'tcx>, rval: &mut Rvalue<'tcx>) {
|
||||
fn replace_with_const(&mut self, place: Place<'tcx>) -> Option<Operand<'tcx>> {
|
||||
// This will return None if the above `const_prop` invocation only "wrote" a
|
||||
// type whose creation requires no write. E.g. a generator whose initial state
|
||||
// consists solely of uninitialized memory (so it doesn't capture any locals).
|
||||
let Some(ref value) = self.get_const(place) else { return };
|
||||
if !self.should_const_prop(value) {
|
||||
return;
|
||||
let value = self.get_const(place)?;
|
||||
if !self.tcx.consider_optimizing(|| format!("ConstantPropagation - {value:?}")) {
|
||||
return None;
|
||||
}
|
||||
trace!("replacing {:?}={:?} with {:?}", place, rval, value);
|
||||
trace!("replacing {:?} with {:?}", place, value);
|
||||
|
||||
if let Rvalue::Use(Operand::Constant(c)) = rval {
|
||||
match c.literal {
|
||||
ConstantKind::Ty(c) if matches!(c.kind(), ConstKind::Unevaluated(..)) => {}
|
||||
_ => {
|
||||
trace!("skipping replace of Rvalue::Use({:?} because it is already a const", c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trace!("attempting to replace {:?} with {:?}", rval, value);
|
||||
// FIXME> figure out what to do when read_immediate_raw fails
|
||||
let imm = self.ecx.read_immediate_raw(value).ok();
|
||||
let imm = self.ecx.read_immediate_raw(&value).ok()?;
|
||||
|
||||
if let Some(Right(imm)) = imm {
|
||||
match *imm {
|
||||
interpret::Immediate::Scalar(scalar) => {
|
||||
*rval = Rvalue::Use(self.operand_from_scalar(scalar, value.layout.ty));
|
||||
}
|
||||
Immediate::ScalarPair(..) => {
|
||||
// Found a value represented as a pair. For now only do const-prop if the type
|
||||
// of `rvalue` is also a tuple with two scalars.
|
||||
// FIXME: enable the general case stated above ^.
|
||||
let ty = value.layout.ty;
|
||||
// Only do it for tuples
|
||||
if let ty::Tuple(types) = ty.kind() {
|
||||
// Only do it if tuple is also a pair with two scalars
|
||||
if let [ty1, ty2] = types[..] {
|
||||
let ty_is_scalar = |ty| {
|
||||
self.ecx.layout_of(ty).ok().map(|layout| layout.abi.is_scalar())
|
||||
== Some(true)
|
||||
};
|
||||
let alloc = if ty_is_scalar(ty1) && ty_is_scalar(ty2) {
|
||||
let alloc = self
|
||||
.ecx
|
||||
.intern_with_temp_alloc(value.layout, |ecx, dest| {
|
||||
ecx.write_immediate(*imm, dest)
|
||||
})
|
||||
.unwrap();
|
||||
Some(alloc)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(alloc) = alloc {
|
||||
// Assign entire constant in a single statement.
|
||||
// We can't use aggregates, as we run after the aggregate-lowering `MirPhase`.
|
||||
let const_val = ConstValue::ByRef { alloc, offset: Size::ZERO };
|
||||
let literal = ConstantKind::Val(const_val, ty);
|
||||
*rval = Rvalue::Use(Operand::Constant(Box::new(Constant {
|
||||
span: DUMMY_SP,
|
||||
user_ty: None,
|
||||
literal,
|
||||
})));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Scalars or scalar pairs that contain undef values are assumed to not have
|
||||
// successfully evaluated and are thus not propagated.
|
||||
_ => {}
|
||||
let Right(imm) = imm else { return None };
|
||||
match *imm {
|
||||
Immediate::Scalar(scalar) if scalar.try_to_int().is_ok() => {
|
||||
Some(self.operand_from_scalar(scalar, value.layout.ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
Immediate::ScalarPair(l, r) if l.try_to_int().is_ok() && r.try_to_int().is_ok() => {
|
||||
let alloc = self
|
||||
.ecx
|
||||
.intern_with_temp_alloc(value.layout, |ecx, dest| {
|
||||
ecx.write_immediate(*imm, dest)
|
||||
})
|
||||
.ok()?;
|
||||
|
||||
/// Returns `true` if and only if this `op` should be const-propagated into.
|
||||
fn should_const_prop(&mut self, op: &OpTy<'tcx>) -> bool {
|
||||
if !self.tcx.consider_optimizing(|| format!("ConstantPropagation - OpTy: {:?}", op)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
match **op {
|
||||
interpret::Operand::Immediate(Immediate::Scalar(s)) => s.try_to_int().is_ok(),
|
||||
interpret::Operand::Immediate(Immediate::ScalarPair(l, r)) => {
|
||||
l.try_to_int().is_ok() && r.try_to_int().is_ok()
|
||||
let literal = ConstantKind::Val(
|
||||
ConstValue::ByRef { alloc, offset: Size::ZERO },
|
||||
value.layout.ty,
|
||||
);
|
||||
Some(Operand::Constant(Box::new(Constant {
|
||||
span: DUMMY_SP,
|
||||
user_ty: None,
|
||||
literal,
|
||||
})))
|
||||
}
|
||||
_ => false,
|
||||
// Scalars or scalar pairs that contain undef values are assumed to not have
|
||||
// successfully evaluated and are thus not propagated.
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -810,12 +719,7 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
|
||||
|
||||
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) {
|
||||
self.super_operand(operand, location);
|
||||
|
||||
// Only const prop copies and moves on `mir_opt_level=3` as doing so
|
||||
// currently slightly increases compile time in some cases.
|
||||
if self.tcx.sess.mir_opt_level() >= 3 {
|
||||
self.propagate_operand(operand)
|
||||
}
|
||||
self.propagate_operand(operand)
|
||||
}
|
||||
|
||||
fn process_projection_elem(
|
||||
@ -825,8 +729,7 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
|
||||
) -> Option<PlaceElem<'tcx>> {
|
||||
if let PlaceElem::Index(local) = elem
|
||||
&& let Some(value) = self.get_const(local.into())
|
||||
&& self.should_const_prop(&value)
|
||||
&& let interpret::Operand::Immediate(interpret::Immediate::Scalar(scalar)) = *value
|
||||
&& let interpret::Operand::Immediate(Immediate::Scalar(scalar)) = *value
|
||||
&& let Ok(offset) = scalar.to_target_usize(&self.tcx)
|
||||
&& let Some(min_length) = offset.checked_add(1)
|
||||
{
|
||||
@ -852,7 +755,14 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
|
||||
ConstPropMode::NoPropagation => self.ensure_not_propagated(place.local),
|
||||
ConstPropMode::OnlyInsideOwnBlock | ConstPropMode::FullConstProp => {
|
||||
if let Some(()) = self.eval_rvalue_with_identities(rvalue, *place) {
|
||||
self.replace_with_const(*place, rvalue);
|
||||
// If this was already an evaluated constant, keep it.
|
||||
if let Rvalue::Use(Operand::Constant(c)) = rvalue
|
||||
&& let ConstantKind::Val(..) = c.literal
|
||||
{
|
||||
trace!("skipping replace of Rvalue::Use({:?} because it is already a const", c);
|
||||
} else if let Some(operand) = self.replace_with_const(*place) {
|
||||
*rvalue = Rvalue::Use(operand);
|
||||
}
|
||||
} else {
|
||||
// Const prop failed, so erase the destination, ensuring that whatever happens
|
||||
// from here on, does not know about the previous value.
|
||||
@ -919,45 +829,6 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) {
|
||||
self.super_terminator(terminator, location);
|
||||
|
||||
match &mut terminator.kind {
|
||||
TerminatorKind::Assert { expected, ref mut cond, .. } => {
|
||||
if let Some(ref value) = self.eval_operand(&cond)
|
||||
&& let Ok(value_const) = self.ecx.read_scalar(&value)
|
||||
&& self.should_const_prop(value)
|
||||
{
|
||||
trace!("assertion on {:?} should be {:?}", value, expected);
|
||||
*cond = self.operand_from_scalar(value_const, self.tcx.types.bool);
|
||||
}
|
||||
}
|
||||
TerminatorKind::SwitchInt { ref mut discr, .. } => {
|
||||
// FIXME: This is currently redundant with `visit_operand`, but sadly
|
||||
// always visiting operands currently causes a perf regression in LLVM codegen, so
|
||||
// `visit_operand` currently only runs for propagates places for `mir_opt_level=4`.
|
||||
self.propagate_operand(discr)
|
||||
}
|
||||
// None of these have Operands to const-propagate.
|
||||
TerminatorKind::Goto { .. }
|
||||
| TerminatorKind::Resume
|
||||
| TerminatorKind::Terminate
|
||||
| TerminatorKind::Return
|
||||
| TerminatorKind::Unreachable
|
||||
| TerminatorKind::Drop { .. }
|
||||
| TerminatorKind::Yield { .. }
|
||||
| TerminatorKind::GeneratorDrop
|
||||
| TerminatorKind::FalseEdge { .. }
|
||||
| TerminatorKind::FalseUnwind { .. }
|
||||
| TerminatorKind::InlineAsm { .. } => {}
|
||||
// Every argument in our function calls have already been propagated in `visit_operand`.
|
||||
//
|
||||
// NOTE: because LLVM codegen gives slight performance regressions with it, so this is
|
||||
// gated on `mir_opt_level=3`.
|
||||
TerminatorKind::Call { .. } => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) {
|
||||
self.super_basic_block_data(block, data);
|
||||
|
||||
|
@ -26,8 +26,9 @@
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
- _5 = _1;
|
||||
- _4 = foo(move _5) -> [return: bb1, unwind unreachable];
|
||||
+ _5 = const 1_u8;
|
||||
_4 = foo(move _5) -> [return: bb1, unwind unreachable];
|
||||
+ _4 = foo(const 1_u8) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -26,8 +26,9 @@
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
- _5 = _1;
|
||||
- _4 = foo(move _5) -> [return: bb1, unwind continue];
|
||||
+ _5 = const 1_u8;
|
||||
_4 = foo(move _5) -> [return: bb1, unwind continue];
|
||||
+ _4 = foo(const 1_u8) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -23,7 +23,7 @@ fn main() -> () {
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = const 1_u8;
|
||||
_4 = foo(move _5) -> [return: bb1, unwind unreachable];
|
||||
_4 = foo(const 1_u8) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -23,7 +23,7 @@ fn main() -> () {
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = const 1_u8;
|
||||
_4 = foo(move _5) -> [return: bb1, unwind continue];
|
||||
_4 = foo(const 1_u8) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -23,7 +23,7 @@
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -23,7 +23,7 @@
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -23,7 +23,7 @@
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -23,7 +23,7 @@
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -38,11 +38,12 @@
|
||||
+ _5 = const false;
|
||||
+ _6 = const false;
|
||||
+ _7 = const false;
|
||||
+ assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind unreachable];
|
||||
+ assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, const 0_i32) -> [success: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_2 = Div(const 1_i32, move _3);
|
||||
- _2 = Div(const 1_i32, move _3);
|
||||
+ _2 = Div(const 1_i32, const 0_i32);
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
StorageDead(_2);
|
||||
|
@ -38,11 +38,12 @@
|
||||
+ _5 = const false;
|
||||
+ _6 = const false;
|
||||
+ _7 = const false;
|
||||
+ assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind continue];
|
||||
+ assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, const 0_i32) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_2 = Div(const 1_i32, move _3);
|
||||
- _2 = Div(const 1_i32, move _3);
|
||||
+ _2 = Div(const 1_i32, const 0_i32);
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
StorageDead(_2);
|
||||
|
@ -38,11 +38,12 @@
|
||||
+ _5 = const false;
|
||||
+ _6 = const false;
|
||||
+ _7 = const false;
|
||||
+ assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind unreachable];
|
||||
+ assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, const 0_i32) -> [success: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_2 = Rem(const 1_i32, move _3);
|
||||
- _2 = Rem(const 1_i32, move _3);
|
||||
+ _2 = Rem(const 1_i32, const 0_i32);
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
StorageDead(_2);
|
||||
|
@ -38,11 +38,12 @@
|
||||
+ _5 = const false;
|
||||
+ _6 = const false;
|
||||
+ _7 = const false;
|
||||
+ assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> [success: bb2, unwind continue];
|
||||
+ assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, const 0_i32) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_2 = Rem(const 1_i32, move _3);
|
||||
- _2 = Rem(const 1_i32, move _3);
|
||||
+ _2 = Rem(const 1_i32, const 0_i32);
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
StorageDead(_2);
|
||||
|
@ -38,7 +38,7 @@
|
||||
- _8 = Lt(_6, _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable];
|
||||
+ _8 = const false;
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable];
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -38,7 +38,7 @@
|
||||
- _8 = Lt(_6, _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
+ _8 = const false;
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -38,7 +38,7 @@
|
||||
- _8 = Lt(_6, _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable];
|
||||
+ _8 = const false;
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable];
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -38,7 +38,7 @@
|
||||
- _8 = Lt(_6, _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
+ _8 = const false;
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -24,9 +24,10 @@
|
||||
StorageLive(_3);
|
||||
- _4 = SizeOf(i32);
|
||||
- _5 = AlignOf(i32);
|
||||
- _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind unreachable];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const 4_usize;
|
||||
_6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind unreachable];
|
||||
+ _6 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -24,9 +24,10 @@
|
||||
StorageLive(_3);
|
||||
- _4 = SizeOf(i32);
|
||||
- _5 = AlignOf(i32);
|
||||
- _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind continue];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const 4_usize;
|
||||
_6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind continue];
|
||||
+ _6 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -8,8 +8,9 @@
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = const _;
|
||||
- _1 = const _;
|
||||
- switchInt(move _1) -> [0: bb2, otherwise: bb1];
|
||||
+ _1 = const false;
|
||||
+ switchInt(const false) -> [0: bb2, otherwise: bb1];
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,9 @@
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = const _;
|
||||
- _1 = const _;
|
||||
- switchInt(move _1) -> [0: bb2, otherwise: bb1];
|
||||
+ _1 = const false;
|
||||
+ switchInt(const false) -> [0: bb2, otherwise: bb1];
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
- assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> [success: bb1, unwind unreachable];
|
||||
+ _2 = const 2_u8;
|
||||
+ _3 = const (3_u8, false);
|
||||
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> [success: bb1, unwind unreachable];
|
||||
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u8, const 1_u8) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -18,7 +18,7 @@
|
||||
- assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> [success: bb1, unwind continue];
|
||||
+ _2 = const 2_u8;
|
||||
+ _3 = const (3_u8, false);
|
||||
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> [success: bb1, unwind continue];
|
||||
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u8, const 1_u8) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -23,7 +23,7 @@
|
||||
- _4 = CheckedAdd(_2, _3);
|
||||
- assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const (0_u8, true);
|
||||
+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind unreachable];
|
||||
+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -23,7 +23,7 @@
|
||||
- _4 = CheckedAdd(_2, _3);
|
||||
- assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const (0_u8, true);
|
||||
+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue];
|
||||
+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -43,8 +43,9 @@
|
||||
StorageLive(_5);
|
||||
_5 = InvalidTag { int: const 4_u32 };
|
||||
- _4 = (_5.1: E);
|
||||
- _3 = [move _4];
|
||||
+ _4 = const Scalar(0x00000004): E;
|
||||
_3 = [move _4];
|
||||
+ _3 = [const Scalar(0x00000004): E];
|
||||
StorageDead(_4);
|
||||
StorageDead(_5);
|
||||
nop;
|
||||
|
@ -8,8 +8,10 @@
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
_2 = (const (), const 0_u8, const 0_u8);
|
||||
_1 = encode(move _2) -> [return: bb1, unwind unreachable];
|
||||
- _2 = (const (), const 0_u8, const 0_u8);
|
||||
- _1 = encode(move _2) -> [return: bb1, unwind unreachable];
|
||||
+ _2 = const ((), 0_u8, 0_u8);
|
||||
+ _1 = encode(const ((), 0_u8, 0_u8)) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -8,8 +8,10 @@
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
_2 = (const (), const 0_u8, const 0_u8);
|
||||
_1 = encode(move _2) -> [return: bb1, unwind continue];
|
||||
- _2 = (const (), const 0_u8, const 0_u8);
|
||||
- _1 = encode(move _2) -> [return: bb1, unwind continue];
|
||||
+ _2 = const ((), 0_u8, 0_u8);
|
||||
+ _1 = encode(const ((), 0_u8, 0_u8)) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -11,10 +11,12 @@
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
- _3 = (const 1_u8, const 2_u8);
|
||||
- _2 = (move _3,);
|
||||
+ _3 = const (1_u8, 2_u8);
|
||||
_2 = (move _3,);
|
||||
+ _2 = const ((1_u8, 2_u8),);
|
||||
StorageDead(_3);
|
||||
_1 = test(move _2) -> [return: bb1, unwind unreachable];
|
||||
- _1 = test(move _2) -> [return: bb1, unwind unreachable];
|
||||
+ _1 = test(const ((1_u8, 2_u8),)) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -11,10 +11,12 @@
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
- _3 = (const 1_u8, const 2_u8);
|
||||
- _2 = (move _3,);
|
||||
+ _3 = const (1_u8, 2_u8);
|
||||
_2 = (move _3,);
|
||||
+ _2 = const ((1_u8, 2_u8),);
|
||||
StorageDead(_3);
|
||||
_1 = test(move _2) -> [return: bb1, unwind continue];
|
||||
- _1 = test(move _2) -> [return: bb1, unwind continue];
|
||||
+ _1 = test(const ((1_u8, 2_u8),)) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -23,7 +23,7 @@
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -23,7 +23,7 @@
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -23,7 +23,7 @@
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -23,7 +23,7 @@
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -28,8 +28,9 @@
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
- _2 = OffsetOf(Alpha, [0]);
|
||||
- _1 = must_use::<usize>(move _2) -> [return: bb1, unwind unreachable];
|
||||
+ _2 = const 4_usize;
|
||||
_1 = must_use::<usize>(move _2) -> [return: bb1, unwind unreachable];
|
||||
+ _1 = must_use::<usize>(const 4_usize) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
@ -37,8 +38,9 @@
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
- _4 = OffsetOf(Alpha, [1]);
|
||||
- _3 = must_use::<usize>(move _4) -> [return: bb2, unwind unreachable];
|
||||
+ _4 = const 0_usize;
|
||||
_3 = must_use::<usize>(move _4) -> [return: bb2, unwind unreachable];
|
||||
+ _3 = must_use::<usize>(const 0_usize) -> [return: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
@ -46,8 +48,9 @@
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
- _6 = OffsetOf(Alpha, [2, 0]);
|
||||
- _5 = must_use::<usize>(move _6) -> [return: bb3, unwind unreachable];
|
||||
+ _6 = const 2_usize;
|
||||
_5 = must_use::<usize>(move _6) -> [return: bb3, unwind unreachable];
|
||||
+ _5 = must_use::<usize>(const 2_usize) -> [return: bb3, unwind unreachable];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
@ -55,8 +58,9 @@
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
- _8 = OffsetOf(Alpha, [2, 1]);
|
||||
- _7 = must_use::<usize>(move _8) -> [return: bb4, unwind unreachable];
|
||||
+ _8 = const 3_usize;
|
||||
_7 = must_use::<usize>(move _8) -> [return: bb4, unwind unreachable];
|
||||
+ _7 = must_use::<usize>(const 3_usize) -> [return: bb4, unwind unreachable];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
|
@ -28,8 +28,9 @@
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
- _2 = OffsetOf(Alpha, [0]);
|
||||
- _1 = must_use::<usize>(move _2) -> [return: bb1, unwind continue];
|
||||
+ _2 = const 4_usize;
|
||||
_1 = must_use::<usize>(move _2) -> [return: bb1, unwind continue];
|
||||
+ _1 = must_use::<usize>(const 4_usize) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
@ -37,8 +38,9 @@
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
- _4 = OffsetOf(Alpha, [1]);
|
||||
- _3 = must_use::<usize>(move _4) -> [return: bb2, unwind continue];
|
||||
+ _4 = const 0_usize;
|
||||
_3 = must_use::<usize>(move _4) -> [return: bb2, unwind continue];
|
||||
+ _3 = must_use::<usize>(const 0_usize) -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
@ -46,8 +48,9 @@
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
- _6 = OffsetOf(Alpha, [2, 0]);
|
||||
- _5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
|
||||
+ _6 = const 2_usize;
|
||||
_5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
|
||||
+ _5 = must_use::<usize>(const 2_usize) -> [return: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
@ -55,8 +58,9 @@
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
- _8 = OffsetOf(Alpha, [2, 1]);
|
||||
- _7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
|
||||
+ _8 = const 3_usize;
|
||||
_7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
|
||||
+ _7 = must_use::<usize>(const 3_usize) -> [return: bb4, unwind continue];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
|
@ -25,7 +25,7 @@
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -25,7 +25,7 @@
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -25,7 +25,7 @@
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -25,7 +25,7 @@
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -16,8 +16,9 @@
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
- _3 = _1;
|
||||
- _2 = consume(move _3) -> [return: bb1, unwind unreachable];
|
||||
+ _3 = const 1_u32;
|
||||
_2 = consume(move _3) -> [return: bb1, unwind unreachable];
|
||||
+ _2 = consume(const 1_u32) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -16,8 +16,9 @@
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
- _3 = _1;
|
||||
- _2 = consume(move _3) -> [return: bb1, unwind continue];
|
||||
+ _3 = const 1_u32;
|
||||
_2 = consume(move _3) -> [return: bb1, unwind continue];
|
||||
+ _2 = consume(const 1_u32) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -30,7 +30,7 @@
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -30,7 +30,7 @@
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -30,7 +30,7 @@
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -30,7 +30,7 @@
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue];
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -17,8 +17,9 @@
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
- _3 = _1;
|
||||
- _2 = consume(move _3) -> [return: bb1, unwind unreachable];
|
||||
+ _3 = const (1_u32, 2_u32);
|
||||
_2 = consume(move _3) -> [return: bb1, unwind unreachable];
|
||||
+ _2 = consume(const (1_u32, 2_u32)) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -17,8 +17,9 @@
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
- _3 = _1;
|
||||
- _2 = consume(move _3) -> [return: bb1, unwind continue];
|
||||
+ _3 = const (1_u32, 2_u32);
|
||||
_2 = consume(move _3) -> [return: bb1, unwind continue];
|
||||
+ _2 = consume(const (1_u32, 2_u32)) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -12,7 +12,6 @@
|
||||
+ debug rhs => _4;
|
||||
+ let mut _5: u16;
|
||||
+ let mut _6: bool;
|
||||
+ let mut _7: u32;
|
||||
+ scope 2 {
|
||||
+ }
|
||||
+ }
|
||||
@ -28,10 +27,7 @@
|
||||
- bb1: {
|
||||
+ StorageLive(_5);
|
||||
+ StorageLive(_6);
|
||||
+ StorageLive(_7);
|
||||
+ _7 = const 65535_u32;
|
||||
+ _6 = Le(_4, move _7);
|
||||
+ StorageDead(_7);
|
||||
+ _6 = Le(_4, const 65535_u32);
|
||||
+ assume(move _6);
|
||||
+ StorageDead(_6);
|
||||
+ _5 = _4 as u16 (IntToInt);
|
||||
|
@ -12,7 +12,6 @@
|
||||
+ debug rhs => _4;
|
||||
+ let mut _5: u16;
|
||||
+ let mut _6: bool;
|
||||
+ let mut _7: u32;
|
||||
+ scope 2 {
|
||||
+ }
|
||||
+ }
|
||||
@ -28,10 +27,7 @@
|
||||
- bb1: {
|
||||
+ StorageLive(_5);
|
||||
+ StorageLive(_6);
|
||||
+ StorageLive(_7);
|
||||
+ _7 = const 65535_u32;
|
||||
+ _6 = Le(_4, move _7);
|
||||
+ StorageDead(_7);
|
||||
+ _6 = Le(_4, const 65535_u32);
|
||||
+ assume(move _6);
|
||||
+ StorageDead(_6);
|
||||
+ _5 = _4 as u16 (IntToInt);
|
||||
|
@ -7,25 +7,21 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
|
||||
scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
|
||||
debug self => _1;
|
||||
debug rhs => _2;
|
||||
let mut _3: u32;
|
||||
let mut _4: bool;
|
||||
let mut _5: u16;
|
||||
let mut _3: bool;
|
||||
let mut _4: u16;
|
||||
scope 2 {
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_5);
|
||||
StorageLive(_4);
|
||||
StorageLive(_3);
|
||||
_3 = const 65535_u32;
|
||||
_4 = Le(_2, move _3);
|
||||
_3 = Le(_2, const 65535_u32);
|
||||
assume(move _3);
|
||||
StorageDead(_3);
|
||||
assume(move _4);
|
||||
_4 = _2 as u16 (IntToInt);
|
||||
_0 = ShlUnchecked(_1, move _4);
|
||||
StorageDead(_4);
|
||||
_5 = _2 as u16 (IntToInt);
|
||||
_0 = ShlUnchecked(_1, move _5);
|
||||
StorageDead(_5);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -7,25 +7,21 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
|
||||
scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
|
||||
debug self => _1;
|
||||
debug rhs => _2;
|
||||
let mut _3: u32;
|
||||
let mut _4: bool;
|
||||
let mut _5: u16;
|
||||
let mut _3: bool;
|
||||
let mut _4: u16;
|
||||
scope 2 {
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_5);
|
||||
StorageLive(_4);
|
||||
StorageLive(_3);
|
||||
_3 = const 65535_u32;
|
||||
_4 = Le(_2, move _3);
|
||||
_3 = Le(_2, const 65535_u32);
|
||||
assume(move _3);
|
||||
StorageDead(_3);
|
||||
assume(move _4);
|
||||
_4 = _2 as u16 (IntToInt);
|
||||
_0 = ShlUnchecked(_1, move _4);
|
||||
StorageDead(_4);
|
||||
_5 = _2 as u16 (IntToInt);
|
||||
_0 = ShlUnchecked(_1, move _5);
|
||||
StorageDead(_5);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
+ debug rhs => _4;
|
||||
+ let mut _5: i16;
|
||||
+ let mut _6: bool;
|
||||
+ let mut _7: u32;
|
||||
+ scope 2 {
|
||||
+ }
|
||||
+ }
|
||||
@ -28,10 +27,7 @@
|
||||
- bb1: {
|
||||
+ StorageLive(_5);
|
||||
+ StorageLive(_6);
|
||||
+ StorageLive(_7);
|
||||
+ _7 = const 32767_u32;
|
||||
+ _6 = Le(_4, move _7);
|
||||
+ StorageDead(_7);
|
||||
+ _6 = Le(_4, const 32767_u32);
|
||||
+ assume(move _6);
|
||||
+ StorageDead(_6);
|
||||
+ _5 = _4 as i16 (IntToInt);
|
||||
|
@ -12,7 +12,6 @@
|
||||
+ debug rhs => _4;
|
||||
+ let mut _5: i16;
|
||||
+ let mut _6: bool;
|
||||
+ let mut _7: u32;
|
||||
+ scope 2 {
|
||||
+ }
|
||||
+ }
|
||||
@ -28,10 +27,7 @@
|
||||
- bb1: {
|
||||
+ StorageLive(_5);
|
||||
+ StorageLive(_6);
|
||||
+ StorageLive(_7);
|
||||
+ _7 = const 32767_u32;
|
||||
+ _6 = Le(_4, move _7);
|
||||
+ StorageDead(_7);
|
||||
+ _6 = Le(_4, const 32767_u32);
|
||||
+ assume(move _6);
|
||||
+ StorageDead(_6);
|
||||
+ _5 = _4 as i16 (IntToInt);
|
||||
|
@ -7,25 +7,21 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 {
|
||||
scope 1 (inlined core::num::<impl i16>::unchecked_shr) {
|
||||
debug self => _1;
|
||||
debug rhs => _2;
|
||||
let mut _3: u32;
|
||||
let mut _4: bool;
|
||||
let mut _5: i16;
|
||||
let mut _3: bool;
|
||||
let mut _4: i16;
|
||||
scope 2 {
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_5);
|
||||
StorageLive(_4);
|
||||
StorageLive(_3);
|
||||
_3 = const 32767_u32;
|
||||
_4 = Le(_2, move _3);
|
||||
_3 = Le(_2, const 32767_u32);
|
||||
assume(move _3);
|
||||
StorageDead(_3);
|
||||
assume(move _4);
|
||||
_4 = _2 as i16 (IntToInt);
|
||||
_0 = ShrUnchecked(_1, move _4);
|
||||
StorageDead(_4);
|
||||
_5 = _2 as i16 (IntToInt);
|
||||
_0 = ShrUnchecked(_1, move _5);
|
||||
StorageDead(_5);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -7,25 +7,21 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 {
|
||||
scope 1 (inlined core::num::<impl i16>::unchecked_shr) {
|
||||
debug self => _1;
|
||||
debug rhs => _2;
|
||||
let mut _3: u32;
|
||||
let mut _4: bool;
|
||||
let mut _5: i16;
|
||||
let mut _3: bool;
|
||||
let mut _4: i16;
|
||||
scope 2 {
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_5);
|
||||
StorageLive(_4);
|
||||
StorageLive(_3);
|
||||
_3 = const 32767_u32;
|
||||
_4 = Le(_2, move _3);
|
||||
_3 = Le(_2, const 32767_u32);
|
||||
assume(move _3);
|
||||
StorageDead(_3);
|
||||
assume(move _4);
|
||||
_4 = _2 as i16 (IntToInt);
|
||||
_0 = ShrUnchecked(_1, move _4);
|
||||
StorageDead(_4);
|
||||
_5 = _2 as i16 (IntToInt);
|
||||
_0 = ShrUnchecked(_1, move _5);
|
||||
StorageDead(_5);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -7,25 +7,24 @@ fn checked_shl(_1: u32, _2: u32) -> Option<u32> {
|
||||
scope 1 (inlined core::num::<impl u32>::checked_shl) {
|
||||
debug self => _1;
|
||||
debug rhs => _2;
|
||||
let mut _7: bool;
|
||||
let mut _6: bool;
|
||||
scope 2 {
|
||||
debug a => _5;
|
||||
debug b => _6;
|
||||
debug a => _4;
|
||||
debug b => _5;
|
||||
}
|
||||
scope 3 (inlined core::num::<impl u32>::overflowing_shl) {
|
||||
debug self => _1;
|
||||
debug rhs => _2;
|
||||
let mut _5: u32;
|
||||
let mut _6: bool;
|
||||
let mut _4: u32;
|
||||
let mut _5: bool;
|
||||
scope 4 (inlined core::num::<impl u32>::wrapping_shl) {
|
||||
debug self => _1;
|
||||
debug rhs => _2;
|
||||
let mut _3: u32;
|
||||
let mut _4: u32;
|
||||
scope 5 {
|
||||
scope 6 (inlined core::num::<impl u32>::unchecked_shl) {
|
||||
debug self => _1;
|
||||
debug rhs => _4;
|
||||
debug rhs => _3;
|
||||
scope 7 {
|
||||
}
|
||||
}
|
||||
@ -35,26 +34,23 @@ fn checked_shl(_1: u32, _2: u32) -> Option<u32> {
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_3);
|
||||
_3 = const 31_u32;
|
||||
_4 = BitAnd(_2, move _3);
|
||||
_3 = BitAnd(_2, const 31_u32);
|
||||
_4 = ShlUnchecked(_1, _3);
|
||||
StorageDead(_3);
|
||||
_5 = ShlUnchecked(_1, _4);
|
||||
StorageDead(_4);
|
||||
_6 = Ge(_2, const _);
|
||||
StorageLive(_7);
|
||||
_7 = unlikely(move _6) -> [return: bb1, unwind unreachable];
|
||||
_5 = Ge(_2, const _);
|
||||
StorageLive(_6);
|
||||
_6 = unlikely(move _5) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
switchInt(move _7) -> [0: bb2, otherwise: bb3];
|
||||
switchInt(move _6) -> [0: bb2, otherwise: bb3];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_0 = Option::<u32>::Some(_5);
|
||||
_0 = Option::<u32>::Some(_4);
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
@ -64,9 +60,9 @@ fn checked_shl(_1: u32, _2: u32) -> Option<u32> {
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2,22 +2,18 @@
|
||||
|
||||
fn f_u64() -> () {
|
||||
let mut _0: ();
|
||||
let mut _1: u64;
|
||||
scope 1 (inlined f_dispatch::<u64>) {
|
||||
debug t => const 0_u64;
|
||||
let _2: ();
|
||||
let _1: ();
|
||||
scope 2 (inlined std::mem::size_of::<u64>) {
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = const 0_u64;
|
||||
_2 = f_non_zst::<u64>(move _1) -> [return: bb1, unwind unreachable];
|
||||
_1 = f_non_zst::<u64>(const 0_u64) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user