Skip to content

Commit c2693db

Browse files
committed
Add peephold optimization that simplifies Ne(_1, false) and Ne(false, _1) into _1
This was observed emitted from the MatchBranchSimplification pass.
1 parent ffaf158 commit c2693db

File tree

5 files changed

+128
-2
lines changed

5 files changed

+128
-2
lines changed

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1954,6 +1954,15 @@ impl<'tcx> Operand<'tcx> {
19541954
Operand::Constant(_) => None,
19551955
}
19561956
}
1957+
1958+
/// Returns the `Constant` that is the target of this `Operand`, or `None` if this `Operand` is a
1959+
/// place.
1960+
pub fn constant(&self) -> Option<&Constant<'tcx>> {
1961+
match self {
1962+
Operand::Constant(x) => Some(&**x),
1963+
Operand::Copy(_) | Operand::Move(_) => None,
1964+
}
1965+
}
19571966
}
19581967

19591968
///////////////////////////////////////////////////////////////////////////

compiler/rustc_mir/src/transform/instcombine.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_hir::Mutability;
66
use rustc_index::vec::Idx;
77
use rustc_middle::mir::visit::{MutVisitor, Visitor};
88
use rustc_middle::mir::{
9-
Body, Constant, Local, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue,
9+
BinOp, Body, Constant, Local, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue,
1010
};
1111
use rustc_middle::ty::{self, TyCtxt};
1212
use std::mem;
@@ -66,6 +66,11 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
6666
*rvalue = Rvalue::Use(Operand::Constant(box constant));
6767
}
6868

69+
if let Some(operand) = self.optimizations.unneeded_not_equal.remove(&location) {
70+
debug!("replacing {:?} with {:?}", rvalue, operand);
71+
*rvalue = Rvalue::Use(operand);
72+
}
73+
6974
self.super_rvalue(rvalue, location)
7075
}
7176
}
@@ -81,6 +86,23 @@ impl OptimizationFinder<'b, 'tcx> {
8186
fn new(body: &'b Body<'tcx>, tcx: TyCtxt<'tcx>) -> OptimizationFinder<'b, 'tcx> {
8287
OptimizationFinder { body, tcx, optimizations: OptimizationList::default() }
8388
}
89+
90+
fn find_operand_in_ne_false_pattern(
91+
&self,
92+
l: &Operand<'tcx>,
93+
r: &'a Operand<'tcx>,
94+
) -> Option<&'a Operand<'tcx>> {
95+
let const_ = l.constant()?;
96+
if const_.literal.ty == self.tcx.types.bool
97+
&& const_.literal.val.try_to_bool() == Some(false)
98+
{
99+
if r.place().is_some() {
100+
return Some(r);
101+
}
102+
}
103+
104+
return None;
105+
}
84106
}
85107

86108
impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
@@ -106,6 +128,18 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
106128
}
107129
}
108130

131+
// find Ne(_place, false) or Ne(false, _place)
132+
if let Rvalue::BinaryOp(BinOp::Ne, l, r) = rvalue {
133+
// (false, _place)
134+
if let Some(o) = self.find_operand_in_ne_false_pattern(l, r) {
135+
self.optimizations.unneeded_not_equal.insert(location, o.clone());
136+
}
137+
// (_place, false)
138+
else if let Some(o) = self.find_operand_in_ne_false_pattern(r, l) {
139+
self.optimizations.unneeded_not_equal.insert(location, o.clone());
140+
}
141+
}
142+
109143
self.super_rvalue(rvalue, location)
110144
}
111145
}
@@ -114,4 +148,5 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
114148
struct OptimizationList<'tcx> {
115149
and_stars: FxHashSet<Location>,
116150
arrays_lengths: FxHashMap<Location, Constant<'tcx>>,
151+
unneeded_not_equal: FxHashMap<Location, Operand<'tcx>>,
117152
}

compiler/rustc_mir/src/transform/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,9 @@ fn run_optimization_passes<'tcx>(
453453

454454
// The main optimizations that we do on MIR.
455455
let optimizations: &[&dyn MirPass<'tcx>] = &[
456-
&instcombine::InstCombine,
457456
&match_branches::MatchBranchSimplification,
457+
// inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
458+
&instcombine::InstCombine,
458459
&const_prop::ConstProp,
459460
&simplify_branches::SimplifyBranches::new("after-const-prop"),
460461
&simplify_comparison_integral::SimplifyComparisonIntegral,
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
- // MIR for `opt` before InstCombine
2+
+ // MIR for `opt` after InstCombine
3+
4+
fn opt(_1: Option<()>) -> bool {
5+
debug x => _1; // in scope 0 at $DIR/not_equal_false.rs:3:8: 3:9
6+
let mut _0: bool; // return place in scope 0 at $DIR/not_equal_false.rs:3:26: 3:30
7+
let mut _2: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
8+
let mut _3: isize; // in scope 0 at $DIR/not_equal_false.rs:4:17: 4:21
9+
let mut _4: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
10+
let mut _5: isize; // in scope 0 at $DIR/not_equal_false.rs:4:38: 4:45
11+
12+
bb0: {
13+
StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
14+
_3 = discriminant(_1); // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21
15+
_2 = Eq(_3, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
16+
goto -> bb7; // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21
17+
}
18+
19+
bb1: {
20+
_0 = const true; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
21+
goto -> bb4; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
22+
}
23+
24+
bb2: {
25+
_0 = const false; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
26+
goto -> bb4; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
27+
}
28+
29+
bb3: {
30+
StorageLive(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
31+
_5 = discriminant(_1); // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45
32+
_4 = Eq(_5, const 1_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
33+
goto -> bb10; // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45
34+
}
35+
36+
bb4: {
37+
StorageDead(_4); // scope 0 at $DIR/not_equal_false.rs:4:45: 4:46
38+
StorageDead(_2); // scope 0 at $DIR/not_equal_false.rs:4:45: 4:46
39+
return; // scope 0 at $DIR/not_equal_false.rs:5:2: 5:2
40+
}
41+
42+
bb5: {
43+
_2 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
44+
goto -> bb7; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
45+
}
46+
47+
bb6: {
48+
_2 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
49+
goto -> bb7; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
50+
}
51+
52+
bb7: {
53+
switchInt(move _2) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
54+
}
55+
56+
bb8: {
57+
_4 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
58+
goto -> bb10; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
59+
}
60+
61+
bb9: {
62+
_4 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
63+
goto -> bb10; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
64+
}
65+
66+
bb10: {
67+
- _0 = Ne(_4, const false); // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
68+
+ _0 = _4; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
69+
goto -> bb4; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
70+
}
71+
}
72+

src/test/mir-opt/not_equal_false.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// EMIT_MIR not_equal_false.opt.InstCombine.diff
2+
3+
fn opt(x: Option<()>) -> bool {
4+
matches!(x, None) || matches!(x, Some(_))
5+
}
6+
7+
fn main() {
8+
opt(None);
9+
}

0 commit comments

Comments
 (0)