]> git.lizzy.rs Git - rust.git/commitdiff
Generalize to Eq(true, _place) and Eq(_place, true)
authorSimon Vandel Sillesen <simon.vandel@gmail.com>
Thu, 3 Sep 2020 17:48:27 +0000 (19:48 +0200)
committerSimon Vandel Sillesen <simon.vandel@gmail.com>
Sun, 6 Sep 2020 09:51:44 +0000 (11:51 +0200)
compiler/rustc_mir/src/transform/instcombine.rs
src/test/mir-opt/equal_true.opt.InstCombine.diff [new file with mode: 0644]
src/test/mir-opt/equal_true.rs [new file with mode: 0644]

index 18cf2a2ff218b6eb59d45c84ef1b0d751b0df09a..c4924cf16ab647e0249dcc58297915a9edddb3d7 100644 (file)
@@ -66,7 +66,7 @@ fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) {
             *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 @@ fn new(body: &'b Body<'tcx>, tcx: TyCtxt<'tcx>) -> 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 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
             }
         }
 
-        // 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 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
 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 (file)
index 0000000..a26776e
--- /dev/null
@@ -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 (file)
index 0000000..994cd19
--- /dev/null
@@ -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);
+}