Skip to content

Commit 9b0fc62

Browse files
committed
Generalize to Eq(true, _place) and Eq(_place, true)
1 parent c2693db commit 9b0fc62

File tree

3 files changed

+74
-15
lines changed

3 files changed

+74
-15
lines changed

compiler/rustc_mir/src/transform/instcombine.rs

+30-15
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ 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) {
69+
if let Some(operand) = self.optimizations.unneeded_equality_comparison.remove(&location) {
7070
debug!("replacing {:?} with {:?}", rvalue, operand);
7171
*rvalue = Rvalue::Use(operand);
7272
}
@@ -87,14 +87,39 @@ impl OptimizationFinder<'b, 'tcx> {
8787
OptimizationFinder { body, tcx, optimizations: OptimizationList::default() }
8888
}
8989

90-
fn find_operand_in_ne_false_pattern(
90+
fn find_unneeded_equality_comparison(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
91+
// find Ne(_place, false) or Ne(false, _place)
92+
// or Eq(_place, true) or Eq(true, _place)
93+
if let Rvalue::BinaryOp(op, l, r) = rvalue {
94+
let const_to_find = if *op == BinOp::Ne {
95+
false
96+
} else if *op == BinOp::Eq {
97+
true
98+
} else {
99+
return;
100+
};
101+
// (const, _place)
102+
if let Some(o) = self.find_operand_in_equality_comparison_pattern(l, r, const_to_find) {
103+
self.optimizations.unneeded_equality_comparison.insert(location, o.clone());
104+
}
105+
// (_place, const)
106+
else if let Some(o) =
107+
self.find_operand_in_equality_comparison_pattern(r, l, const_to_find)
108+
{
109+
self.optimizations.unneeded_equality_comparison.insert(location, o.clone());
110+
}
111+
}
112+
}
113+
114+
fn find_operand_in_equality_comparison_pattern(
91115
&self,
92116
l: &Operand<'tcx>,
93117
r: &'a Operand<'tcx>,
118+
const_to_find: bool,
94119
) -> Option<&'a Operand<'tcx>> {
95120
let const_ = l.constant()?;
96121
if const_.literal.ty == self.tcx.types.bool
97-
&& const_.literal.val.try_to_bool() == Some(false)
122+
&& const_.literal.val.try_to_bool() == Some(const_to_find)
98123
{
99124
if r.place().is_some() {
100125
return Some(r);
@@ -128,17 +153,7 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
128153
}
129154
}
130155

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-
}
156+
self.find_unneeded_equality_comparison(rvalue, location);
142157

143158
self.super_rvalue(rvalue, location)
144159
}
@@ -148,5 +163,5 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
148163
struct OptimizationList<'tcx> {
149164
and_stars: FxHashSet<Location>,
150165
arrays_lengths: FxHashMap<Location, Constant<'tcx>>,
151-
unneeded_not_equal: FxHashMap<Location, Operand<'tcx>>,
166+
unneeded_equality_comparison: FxHashMap<Location, Operand<'tcx>>,
152167
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
- // MIR for `opt` before InstCombine
2+
+ // MIR for `opt` after InstCombine
3+
4+
fn opt(_1: bool) -> i32 {
5+
debug x => _1; // in scope 0 at $DIR/equal_true.rs:3:8: 3:9
6+
let mut _0: i32; // return place in scope 0 at $DIR/equal_true.rs:3:20: 3:23
7+
let mut _2: bool; // in scope 0 at $DIR/equal_true.rs:4:8: 4:17
8+
let mut _3: bool; // in scope 0 at $DIR/equal_true.rs:4:8: 4:9
9+
10+
bb0: {
11+
StorageLive(_2); // scope 0 at $DIR/equal_true.rs:4:8: 4:17
12+
StorageLive(_3); // scope 0 at $DIR/equal_true.rs:4:8: 4:9
13+
_3 = _1; // scope 0 at $DIR/equal_true.rs:4:8: 4:9
14+
- _2 = Eq(move _3, const true); // scope 0 at $DIR/equal_true.rs:4:8: 4:17
15+
+ _2 = move _3; // scope 0 at $DIR/equal_true.rs:4:8: 4:17
16+
StorageDead(_3); // scope 0 at $DIR/equal_true.rs:4:16: 4:17
17+
switchInt(_2) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/equal_true.rs:4:5: 4:34
18+
}
19+
20+
bb1: {
21+
_0 = const 1_i32; // scope 0 at $DIR/equal_true.rs:4:31: 4:32
22+
goto -> bb3; // scope 0 at $DIR/equal_true.rs:4:5: 4:34
23+
}
24+
25+
bb2: {
26+
_0 = const 0_i32; // scope 0 at $DIR/equal_true.rs:4:20: 4:21
27+
goto -> bb3; // scope 0 at $DIR/equal_true.rs:4:5: 4:34
28+
}
29+
30+
bb3: {
31+
StorageDead(_2); // scope 0 at $DIR/equal_true.rs:5:1: 5:2
32+
return; // scope 0 at $DIR/equal_true.rs:5:2: 5:2
33+
}
34+
}
35+

src/test/mir-opt/equal_true.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// EMIT_MIR equal_true.opt.InstCombine.diff
2+
3+
fn opt(x: bool) -> i32 {
4+
if x == true { 0 } else { 1 }
5+
}
6+
7+
fn main() {
8+
opt(true);
9+
}

0 commit comments

Comments
 (0)