about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-03-25 22:33:35 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2024-01-16 22:20:54 +0000
commit5fc23ad8e6b7a5ef0b5a6936cb043bd85f8bed59 (patch)
tree107de973396600174a547ef104b859ed0ff42389 /compiler/rustc_mir_transform/src
parent666030c51b87509a065867f99bf7317a5486470a (diff)
downloadrust-5fc23ad8e6b7a5ef0b5a6936cb043bd85f8bed59.tar.gz
rust-5fc23ad8e6b7a5ef0b5a6936cb043bd85f8bed59.zip
Simplify unary operations.
Diffstat (limited to 'compiler/rustc_mir_transform/src')
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs20
1 files changed, 20 insertions, 0 deletions
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 3052369c3ca..699b218d46d 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -817,6 +817,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
             Rvalue::UnaryOp(op, ref mut arg) => {
                 let arg = self.simplify_operand(arg, location)?;
+                if let Some(value) = self.simplify_unary(op, arg) {
+                    return Some(value);
+                }
                 Value::UnaryOp(op, arg)
             }
             Rvalue::Discriminant(ref mut place) => {
@@ -917,6 +920,23 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
     }
 
     #[instrument(level = "trace", skip(self), ret)]
+    fn simplify_unary(&mut self, op: UnOp, value: VnIndex) -> Option<VnIndex> {
+        let value = match (op, self.get(value)) {
+            (UnOp::Not, Value::UnaryOp(UnOp::Not, inner)) => return Some(*inner),
+            (UnOp::Neg, Value::UnaryOp(UnOp::Neg, inner)) => return Some(*inner),
+            (UnOp::Not, Value::BinaryOp(BinOp::Eq, lhs, rhs)) => {
+                Value::BinaryOp(BinOp::Ne, *lhs, *rhs)
+            }
+            (UnOp::Not, Value::BinaryOp(BinOp::Ne, lhs, rhs)) => {
+                Value::BinaryOp(BinOp::Eq, *lhs, *rhs)
+            }
+            _ => return None,
+        };
+
+        Some(self.insert(value))
+    }
+
+    #[instrument(level = "trace", skip(self), ret)]
     fn simplify_binary(
         &mut self,
         op: BinOp,