Simplify assume of a constant.

This commit is contained in:
Camille GILLOT 2023-07-22 15:34:22 +00:00
parent c748ac1f11
commit 0b13e636f5
6 changed files with 80 additions and 85 deletions

View File

@ -16,8 +16,25 @@ impl<'tcx> MirPass<'tcx> for SimplifyConstCondition {
} }
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
trace!("Running SimplifyConstCondition on {:?}", body.source);
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
for block in body.basic_blocks_mut() { 'blocks: for block in body.basic_blocks_mut() {
for stmt in block.statements.iter_mut() {
if let StatementKind::Intrinsic(box ref intrinsic) = stmt.kind
&& let NonDivergingIntrinsic::Assume(discr) = intrinsic
&& let Operand::Constant(ref c) = discr
&& let Some(constant) = c.const_.try_eval_bool(tcx, param_env)
{
if constant {
stmt.make_nop();
} else {
block.statements.clear();
block.terminator_mut().kind = TerminatorKind::Unreachable;
continue 'blocks;
}
}
}
let terminator = block.terminator_mut(); let terminator = block.terminator_mut();
terminator.kind = match terminator.kind { terminator.kind = match terminator.kind {
TerminatorKind::SwitchInt { TerminatorKind::SwitchInt {

View File

@ -9,6 +9,8 @@
+ debug self => _2; + debug self => _2;
+ let mut _3: &std::option::Option<T>; + let mut _3: &std::option::Option<T>;
+ let mut _4: isize; + let mut _4: isize;
+ let mut _5: bool;
+ let mut _6: bool;
+ scope 2 { + scope 2 {
+ debug val => _0; + debug val => _0;
+ } + }
@ -16,7 +18,6 @@
+ scope 5 (inlined unreachable_unchecked) { + scope 5 (inlined unreachable_unchecked) {
+ scope 6 { + scope 6 {
+ scope 7 (inlined unreachable_unchecked::runtime) { + scope 7 (inlined unreachable_unchecked::runtime) {
+ let _5: !;
+ } + }
+ } + }
+ } + }
@ -30,24 +31,20 @@
StorageLive(_2); StorageLive(_2);
_2 = move _1; _2 = move _1;
- _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind unreachable]; - _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind unreachable];
- }
-
- bb1: {
+ StorageLive(_3); + StorageLive(_3);
+ StorageLive(_4); + StorageLive(_4);
+ StorageLive(_5); + StorageLive(_5);
+ StorageLive(_6);
+ _4 = discriminant(_2); + _4 = discriminant(_2);
+ switchInt(move _4) -> [0: bb1, 1: bb3, otherwise: bb2]; + _5 = Ne(_4, const 0_isize);
} + assume(move _5);
+ _6 = Eq(_4, const 1_isize);
bb1: { + assume(move _6);
+ assume(const false);
+ _5 = core::panicking::panic_nounwind(const "unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached") -> unwind unreachable;
+ }
+
+ bb2: {
+ unreachable;
+ }
+
+ bb3: {
+ _0 = move ((_2 as Some).0: T); + _0 = move ((_2 as Some).0: T);
+ StorageDead(_6);
+ StorageDead(_5); + StorageDead(_5);
+ StorageDead(_4); + StorageDead(_4);
+ StorageDead(_3); + StorageDead(_3);

View File

@ -9,6 +9,8 @@
+ debug self => _2; + debug self => _2;
+ let mut _3: &std::option::Option<T>; + let mut _3: &std::option::Option<T>;
+ let mut _4: isize; + let mut _4: isize;
+ let mut _5: bool;
+ let mut _6: bool;
+ scope 2 { + scope 2 {
+ debug val => _0; + debug val => _0;
+ } + }
@ -16,7 +18,6 @@
+ scope 5 (inlined unreachable_unchecked) { + scope 5 (inlined unreachable_unchecked) {
+ scope 6 { + scope 6 {
+ scope 7 (inlined unreachable_unchecked::runtime) { + scope 7 (inlined unreachable_unchecked::runtime) {
+ let _5: !;
+ } + }
+ } + }
+ } + }
@ -30,33 +31,29 @@
StorageLive(_2); StorageLive(_2);
_2 = move _1; _2 = move _1;
- _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind: bb2]; - _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind: bb2];
- }
-
- bb1: {
+ StorageLive(_3); + StorageLive(_3);
+ StorageLive(_4); + StorageLive(_4);
+ StorageLive(_5); + StorageLive(_5);
+ StorageLive(_6);
+ _4 = discriminant(_2); + _4 = discriminant(_2);
+ switchInt(move _4) -> [0: bb1, 1: bb3, otherwise: bb2]; + _5 = Ne(_4, const 0_isize);
} + assume(move _5);
+ _6 = Eq(_4, const 1_isize);
bb1: { + assume(move _6);
- StorageDead(_2);
- return;
+ assume(const false);
+ _5 = core::panicking::panic_nounwind(const "unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached") -> unwind unreachable;
}
- bb2 (cleanup): {
- resume;
+ bb2: {
+ unreachable;
+ }
+
+ bb3: {
+ _0 = move ((_2 as Some).0: T); + _0 = move ((_2 as Some).0: T);
+ StorageDead(_6);
+ StorageDead(_5); + StorageDead(_5);
+ StorageDead(_4); + StorageDead(_4);
+ StorageDead(_3); + StorageDead(_3);
+ StorageDead(_2); StorageDead(_2);
+ return; return;
- }
-
- bb2 (cleanup): {
- resume;
} }
} }

View File

@ -6,7 +6,9 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
scope 1 (inlined #[track_caller] Option::<T>::unwrap_unchecked) { scope 1 (inlined #[track_caller] Option::<T>::unwrap_unchecked) {
debug self => _1; debug self => _1;
let mut _2: isize; let mut _2: isize;
let mut _4: &std::option::Option<T>; let mut _3: bool;
let mut _4: bool;
let mut _5: &std::option::Option<T>;
scope 2 { scope 2 {
debug val => _0; debug val => _0;
} }
@ -14,36 +16,30 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
scope 5 (inlined unreachable_unchecked) { scope 5 (inlined unreachable_unchecked) {
scope 6 { scope 6 {
scope 7 (inlined unreachable_unchecked::runtime) { scope 7 (inlined unreachable_unchecked::runtime) {
let _3: !;
} }
} }
} }
} }
scope 4 (inlined Option::<T>::is_some) { scope 4 (inlined Option::<T>::is_some) {
debug self => _4; debug self => _5;
} }
} }
bb0: { bb0: {
StorageLive(_4); StorageLive(_5);
StorageLive(_2); StorageLive(_2);
StorageLive(_3);
StorageLive(_4);
_2 = discriminant(_1); _2 = discriminant(_1);
switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3]; _3 = Ne(_2, const 0_isize);
} assume(move _3);
_4 = Eq(_2, const 1_isize);
bb1: { assume(move _4);
assume(const false);
_3 = core::panicking::panic_nounwind(const "unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached") -> unwind unreachable;
}
bb2: {
_0 = move ((_1 as Some).0: T); _0 = move ((_1 as Some).0: T);
StorageDead(_2);
StorageDead(_4); StorageDead(_4);
StorageDead(_3);
StorageDead(_2);
StorageDead(_5);
return; return;
} }
bb3: {
unreachable;
}
} }

View File

@ -6,7 +6,9 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
scope 1 (inlined #[track_caller] Option::<T>::unwrap_unchecked) { scope 1 (inlined #[track_caller] Option::<T>::unwrap_unchecked) {
debug self => _1; debug self => _1;
let mut _2: isize; let mut _2: isize;
let mut _4: &std::option::Option<T>; let mut _3: bool;
let mut _4: bool;
let mut _5: &std::option::Option<T>;
scope 2 { scope 2 {
debug val => _0; debug val => _0;
} }
@ -14,36 +16,30 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
scope 5 (inlined unreachable_unchecked) { scope 5 (inlined unreachable_unchecked) {
scope 6 { scope 6 {
scope 7 (inlined unreachable_unchecked::runtime) { scope 7 (inlined unreachable_unchecked::runtime) {
let _3: !;
} }
} }
} }
} }
scope 4 (inlined Option::<T>::is_some) { scope 4 (inlined Option::<T>::is_some) {
debug self => _4; debug self => _5;
} }
} }
bb0: { bb0: {
StorageLive(_4); StorageLive(_5);
StorageLive(_2); StorageLive(_2);
StorageLive(_3);
StorageLive(_4);
_2 = discriminant(_1); _2 = discriminant(_1);
switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3]; _3 = Ne(_2, const 0_isize);
} assume(move _3);
_4 = Eq(_2, const 1_isize);
bb1: { assume(move _4);
assume(const false);
_3 = core::panicking::panic_nounwind(const "unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached") -> unwind unreachable;
}
bb2: {
_0 = move ((_1 as Some).0: T); _0 = move ((_1 as Some).0: T);
StorageDead(_2);
StorageDead(_4); StorageDead(_4);
StorageDead(_3);
StorageDead(_2);
StorageDead(_5);
return; return;
} }
bb3: {
unreachable;
}
} }

View File

@ -4,30 +4,22 @@ fn ub_if_b(_1: Thing) -> Thing {
debug t => _1; debug t => _1;
let mut _0: Thing; let mut _0: Thing;
let mut _2: isize; let mut _2: isize;
let mut _3: bool;
let mut _4: bool;
scope 1 (inlined unreachable_unchecked) { scope 1 (inlined unreachable_unchecked) {
scope 2 { scope 2 {
scope 3 (inlined unreachable_unchecked::runtime) { scope 3 (inlined unreachable_unchecked::runtime) {
let _3: !;
} }
} }
} }
bb0: { bb0: {
_2 = discriminant(_1); _2 = discriminant(_1);
switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3]; _3 = Ne(_2, const 1_isize);
} assume(move _3);
_4 = Eq(_2, const 0_isize);
bb1: { assume(move _4);
_0 = move _1; _0 = move _1;
return; return;
} }
bb2: {
assume(const false);
_3 = core::panicking::panic_nounwind(const "unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached") -> unwind unreachable;
}
bb3: {
unreachable;
}
} }