about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSimon Vandel Sillesen <simon.vandel@gmail.com>2020-09-03 19:48:27 +0200
committerSimon Vandel Sillesen <simon.vandel@gmail.com>2020-09-06 11:51:44 +0200
commit9b0fc6202bf295e2518f7a781ca069c71c81698f (patch)
tree97ff92407b32d7742abe621f8f4d9749eeb3b75d
parentc2693db264900005ceb13f917dc1fab0cbf8d459 (diff)
downloadrust-9b0fc6202bf295e2518f7a781ca069c71c81698f.tar.gz
rust-9b0fc6202bf295e2518f7a781ca069c71c81698f.zip
Generalize to Eq(true, _place) and Eq(_place, true)
-rw-r--r--compiler/rustc_mir/src/transform/instcombine.rs45
-rw-r--r--src/test/mir-opt/equal_true.opt.InstCombine.diff35
-rw-r--r--src/test/mir-opt/equal_true.rs9
3 files changed, 74 insertions, 15 deletions
diff --git a/compiler/rustc_mir/src/transform/instcombine.rs b/compiler/rustc_mir/src/transform/instcombine.rs
index 18cf2a2ff21..c4924cf16ab 100644
--- a/compiler/rustc_mir/src/transform/instcombine.rs
+++ b/compiler/rustc_mir/src/transform/instcombine.rs
@@ -66,7 +66,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
             *rvalue = Rvalue::Use(Operand::Constant(box constant));
         }
 
-        if let Some(operand) = self.optimizations.unneeded_not_equal.remove(&location) {
+        if let Some(operand) = self.optimizations.unneeded_equality_comparison.remove(&location) {
             debug!("replacing {:?} with {:?}", rvalue, operand);
             *rvalue = Rvalue::Use(operand);
         }
@@ -87,14 +87,39 @@ impl OptimizationFinder<'b, 'tcx> {
         OptimizationFinder { body, tcx, optimizations: OptimizationList::default() }
     }
 
-    fn find_operand_in_ne_false_pattern(
+    fn find_unneeded_equality_comparison(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
+        // find Ne(_place, false) or Ne(false, _place)
+        // or   Eq(_place, true) or Eq(true, _place)
+        if let Rvalue::BinaryOp(op, l, r) = rvalue {
+            let const_to_find = if *op == BinOp::Ne {
+                false
+            } else if *op == BinOp::Eq {
+                true
+            } else {
+                return;
+            };
+            // (const, _place)
+            if let Some(o) = self.find_operand_in_equality_comparison_pattern(l, r, const_to_find) {
+                self.optimizations.unneeded_equality_comparison.insert(location, o.clone());
+            }
+            // (_place, const)
+            else if let Some(o) =
+                self.find_operand_in_equality_comparison_pattern(r, l, const_to_find)
+            {
+                self.optimizations.unneeded_equality_comparison.insert(location, o.clone());
+            }
+        }
+    }
+
+    fn find_operand_in_equality_comparison_pattern(
         &self,
         l: &Operand<'tcx>,
         r: &'a Operand<'tcx>,
+        const_to_find: bool,
     ) -> Option<&'a Operand<'tcx>> {
         let const_ = l.constant()?;
         if const_.literal.ty == self.tcx.types.bool
-            && const_.literal.val.try_to_bool() == Some(false)
+            && const_.literal.val.try_to_bool() == Some(const_to_find)
         {
             if r.place().is_some() {
                 return Some(r);
@@ -128,17 +153,7 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
             }
         }
 
-        // find Ne(_place, false) or Ne(false, _place)
-        if let Rvalue::BinaryOp(BinOp::Ne, l, r) = rvalue {
-            // (false, _place)
-            if let Some(o) = self.find_operand_in_ne_false_pattern(l, r) {
-                self.optimizations.unneeded_not_equal.insert(location, o.clone());
-            }
-            // (_place, false)
-            else if let Some(o) = self.find_operand_in_ne_false_pattern(r, l) {
-                self.optimizations.unneeded_not_equal.insert(location, o.clone());
-            }
-        }
+        self.find_unneeded_equality_comparison(rvalue, location);
 
         self.super_rvalue(rvalue, location)
     }
@@ -148,5 +163,5 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
 struct OptimizationList<'tcx> {
     and_stars: FxHashSet<Location>,
     arrays_lengths: FxHashMap<Location, Constant<'tcx>>,
-    unneeded_not_equal: FxHashMap<Location, Operand<'tcx>>,
+    unneeded_equality_comparison: FxHashMap<Location, Operand<'tcx>>,
 }
diff --git a/src/test/mir-opt/equal_true.opt.InstCombine.diff b/src/test/mir-opt/equal_true.opt.InstCombine.diff
new file mode 100644
index 00000000000..a26776e70d6
--- /dev/null
+++ b/src/test/mir-opt/equal_true.opt.InstCombine.diff
@@ -0,0 +1,35 @@
+- // MIR for `opt` before InstCombine
++ // MIR for `opt` after InstCombine
+  
+  fn opt(_1: bool) -> i32 {
+      debug x => _1;                       // in scope 0 at $DIR/equal_true.rs:3:8: 3:9
+      let mut _0: i32;                     // return place in scope 0 at $DIR/equal_true.rs:3:20: 3:23
+      let mut _2: bool;                    // in scope 0 at $DIR/equal_true.rs:4:8: 4:17
+      let mut _3: bool;                    // in scope 0 at $DIR/equal_true.rs:4:8: 4:9
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/equal_true.rs:4:8: 4:17
+          StorageLive(_3);                 // scope 0 at $DIR/equal_true.rs:4:8: 4:9
+          _3 = _1;                         // scope 0 at $DIR/equal_true.rs:4:8: 4:9
+-         _2 = Eq(move _3, const true);    // scope 0 at $DIR/equal_true.rs:4:8: 4:17
++         _2 = move _3;                    // scope 0 at $DIR/equal_true.rs:4:8: 4:17
+          StorageDead(_3);                 // scope 0 at $DIR/equal_true.rs:4:16: 4:17
+          switchInt(_2) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/equal_true.rs:4:5: 4:34
+      }
+  
+      bb1: {
+          _0 = const 1_i32;                // scope 0 at $DIR/equal_true.rs:4:31: 4:32
+          goto -> bb3;                     // scope 0 at $DIR/equal_true.rs:4:5: 4:34
+      }
+  
+      bb2: {
+          _0 = const 0_i32;                // scope 0 at $DIR/equal_true.rs:4:20: 4:21
+          goto -> bb3;                     // scope 0 at $DIR/equal_true.rs:4:5: 4:34
+      }
+  
+      bb3: {
+          StorageDead(_2);                 // scope 0 at $DIR/equal_true.rs:5:1: 5:2
+          return;                          // scope 0 at $DIR/equal_true.rs:5:2: 5:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/equal_true.rs b/src/test/mir-opt/equal_true.rs
new file mode 100644
index 00000000000..994cd194a45
--- /dev/null
+++ b/src/test/mir-opt/equal_true.rs
@@ -0,0 +1,9 @@
+// EMIT_MIR equal_true.opt.InstCombine.diff
+
+fn opt(x: bool) -> i32 {
+    if x == true { 0 } else { 1 }
+}
+
+fn main() {
+    opt(true);
+}