about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-07-24 10:01:32 -0700
committerGitHub <noreply@github.com>2020-07-24 10:01:32 -0700
commite59effed3037701aadab11d4ea0ddddf2eedbf3b (patch)
tree806abbeb804a9e25d08bf88e06182518bb532134 /src/test
parent3226d723381a24118f6aaa73b096c8ef4510f189 (diff)
parent711a6807a7979715d6b2940db56eaf1585d30a71 (diff)
downloadrust-e59effed3037701aadab11d4ea0ddddf2eedbf3b.tar.gz
rust-e59effed3037701aadab11d4ea0ddddf2eedbf3b.zip
Rollup merge of #74491 - xldenis:constant-binop-opt, r=oli-obk
Optimize away BitAnd and BitOr when possible

This PR lets `const_prop` optimize away `a | true == true` , `a & false == false` and `a * 0 = 0`. While I was writing this I've realized that constant propagation misses a lot of opportunities. For example:  https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=2a4b45e772f214210a36749b27223bb0

Constant propagation doesn't seem to... propagate constants, additionally the way constant propagation is currently setup makes it tricky to add cases like `a | false == a`.

I tried to organize `eval_rvalue_with_identities` to make the pattern of the optimizations easier to see but it still obscurs what should be a simple peephole optmization.

cc @oli-obk
Diffstat (limited to 'src/test')
-rw-r--r--src/test/mir-opt/const_prop/boolean_identities.rs10
-rw-r--r--src/test/mir-opt/const_prop/boolean_identities/rustc.test.ConstProp.diff53
-rw-r--r--src/test/mir-opt/const_prop/mult_by_zero.rs10
-rw-r--r--src/test/mir-opt/const_prop/mult_by_zero/rustc.test.ConstProp.diff25
-rw-r--r--src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs3
-rw-r--r--src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr4
6 files changed, 102 insertions, 3 deletions
diff --git a/src/test/mir-opt/const_prop/boolean_identities.rs b/src/test/mir-opt/const_prop/boolean_identities.rs
new file mode 100644
index 00000000000..4e09acbaa53
--- /dev/null
+++ b/src/test/mir-opt/const_prop/boolean_identities.rs
@@ -0,0 +1,10 @@
+// compile-flags: -O -Zmir-opt-level=3
+
+// EMIT_MIR rustc.test.ConstProp.diff
+pub fn test(x: bool, y: bool) -> bool {
+    (y | true) & (x & false)
+}
+
+fn main() {
+    test(true, false);
+}
diff --git a/src/test/mir-opt/const_prop/boolean_identities/rustc.test.ConstProp.diff b/src/test/mir-opt/const_prop/boolean_identities/rustc.test.ConstProp.diff
new file mode 100644
index 00000000000..b8f0ad4d434
--- /dev/null
+++ b/src/test/mir-opt/const_prop/boolean_identities/rustc.test.ConstProp.diff
@@ -0,0 +1,53 @@
+- // MIR for `test` before ConstProp
++ // MIR for `test` after ConstProp
+  
+  fn test(_1: bool, _2: bool) -> bool {
+      debug x => _1;                       // in scope 0 at $DIR/boolean_identities.rs:4:13: 4:14
+      debug y => _2;                       // in scope 0 at $DIR/boolean_identities.rs:4:22: 4:23
+      let mut _0: bool;                    // return place in scope 0 at $DIR/boolean_identities.rs:4:34: 4:38
+      let mut _3: bool;                    // in scope 0 at $DIR/boolean_identities.rs:5:5: 5:15
+      let mut _4: bool;                    // in scope 0 at $DIR/boolean_identities.rs:5:6: 5:7
+      let mut _5: bool;                    // in scope 0 at $DIR/boolean_identities.rs:5:18: 5:29
+      let mut _6: bool;                    // in scope 0 at $DIR/boolean_identities.rs:5:19: 5:20
+  
+      bb0: {
+          StorageLive(_3);                 // scope 0 at $DIR/boolean_identities.rs:5:5: 5:15
+          StorageLive(_4);                 // scope 0 at $DIR/boolean_identities.rs:5:6: 5:7
+          _4 = _2;                         // scope 0 at $DIR/boolean_identities.rs:5:6: 5:7
+-         _3 = BitOr(move _4, const true); // scope 0 at $DIR/boolean_identities.rs:5:5: 5:15
++         _3 = const true;                 // scope 0 at $DIR/boolean_identities.rs:5:5: 5:15
+                                           // ty::Const
+                                           // + ty: bool
+                                           // + val: Value(Scalar(0x01))
+                                           // mir::Constant
+-                                          // + span: $DIR/boolean_identities.rs:5:10: 5:14
++                                          // + span: $DIR/boolean_identities.rs:5:5: 5:15
+                                           // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
+          StorageDead(_4);                 // scope 0 at $DIR/boolean_identities.rs:5:14: 5:15
+          StorageLive(_5);                 // scope 0 at $DIR/boolean_identities.rs:5:18: 5:29
+          StorageLive(_6);                 // scope 0 at $DIR/boolean_identities.rs:5:19: 5:20
+          _6 = _1;                         // scope 0 at $DIR/boolean_identities.rs:5:19: 5:20
+-         _5 = BitAnd(move _6, const false); // scope 0 at $DIR/boolean_identities.rs:5:18: 5:29
++         _5 = const false;                // scope 0 at $DIR/boolean_identities.rs:5:18: 5:29
+                                           // ty::Const
+                                           // + ty: bool
+                                           // + val: Value(Scalar(0x00))
+                                           // mir::Constant
+-                                          // + span: $DIR/boolean_identities.rs:5:23: 5:28
++                                          // + span: $DIR/boolean_identities.rs:5:18: 5:29
+                                           // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
+          StorageDead(_6);                 // scope 0 at $DIR/boolean_identities.rs:5:28: 5:29
+-         _0 = BitAnd(move _3, move _5);   // scope 0 at $DIR/boolean_identities.rs:5:5: 5:29
++         _0 = const false;                // scope 0 at $DIR/boolean_identities.rs:5:5: 5:29
++                                          // ty::Const
++                                          // + ty: bool
++                                          // + val: Value(Scalar(0x00))
++                                          // mir::Constant
++                                          // + span: $DIR/boolean_identities.rs:5:5: 5:29
++                                          // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
+          StorageDead(_5);                 // scope 0 at $DIR/boolean_identities.rs:5:28: 5:29
+          StorageDead(_3);                 // scope 0 at $DIR/boolean_identities.rs:5:28: 5:29
+          return;                          // scope 0 at $DIR/boolean_identities.rs:6:2: 6:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/const_prop/mult_by_zero.rs b/src/test/mir-opt/const_prop/mult_by_zero.rs
new file mode 100644
index 00000000000..f40faee3110
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mult_by_zero.rs
@@ -0,0 +1,10 @@
+// compile-flags: -O -Zmir-opt-level=3
+
+// EMIT_MIR rustc.test.ConstProp.diff
+fn test(x : i32) -> i32 {
+  x * 0
+}
+
+fn main() {
+    test(10);
+}
diff --git a/src/test/mir-opt/const_prop/mult_by_zero/rustc.test.ConstProp.diff b/src/test/mir-opt/const_prop/mult_by_zero/rustc.test.ConstProp.diff
new file mode 100644
index 00000000000..7b36669bf15
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mult_by_zero/rustc.test.ConstProp.diff
@@ -0,0 +1,25 @@
+- // MIR for `test` before ConstProp
++ // MIR for `test` after ConstProp
+  
+  fn test(_1: i32) -> i32 {
+      debug x => _1;                       // in scope 0 at $DIR/mult_by_zero.rs:4:9: 4:10
+      let mut _0: i32;                     // return place in scope 0 at $DIR/mult_by_zero.rs:4:21: 4:24
+      let mut _2: i32;                     // in scope 0 at $DIR/mult_by_zero.rs:5:3: 5:4
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/mult_by_zero.rs:5:3: 5:4
+          _2 = _1;                         // scope 0 at $DIR/mult_by_zero.rs:5:3: 5:4
+-         _0 = Mul(move _2, const 0_i32);  // scope 0 at $DIR/mult_by_zero.rs:5:3: 5:8
++         _0 = const 0_i32;                // scope 0 at $DIR/mult_by_zero.rs:5:3: 5:8
+                                           // ty::Const
+                                           // + ty: i32
+                                           // + val: Value(Scalar(0x00000000))
+                                           // mir::Constant
+-                                          // + span: $DIR/mult_by_zero.rs:5:7: 5:8
++                                          // + span: $DIR/mult_by_zero.rs:5:3: 5:8
+                                           // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
+          StorageDead(_2);                 // scope 0 at $DIR/mult_by_zero.rs:5:7: 5:8
+          return;                          // scope 0 at $DIR/mult_by_zero.rs:6:2: 6:2
+      }
+  }
+  
diff --git a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs
index 2a983e42683..795c5154f81 100644
--- a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs
+++ b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs
@@ -1,7 +1,7 @@
 // build-fail
 
 // Regression test for #66975
-#![warn(const_err)]
+#![warn(const_err, unconditional_panic)]
 #![feature(never_type)]
 
 struct PrintName<T>(T);
@@ -9,6 +9,7 @@ struct PrintName<T>(T);
 impl<T> PrintName<T> {
     const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
     //~^ WARN any use of this value will cause an error
+
 }
 
 fn f<T>() {
diff --git a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
index d78e0da00f5..33e60dd7c91 100644
--- a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
+++ b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
@@ -9,11 +9,11 @@ LL |     const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
 note: the lint level is defined here
   --> $DIR/index-out-of-bounds-never-type.rs:4:9
    |
-LL | #![warn(const_err)]
+LL | #![warn(const_err, unconditional_panic)]
    |         ^^^^^^^^^
 
 error: erroneous constant encountered
-  --> $DIR/index-out-of-bounds-never-type.rs:15:13
+  --> $DIR/index-out-of-bounds-never-type.rs:16:13
    |
 LL |     let _ = PrintName::<T>::VOID;
    |             ^^^^^^^^^^^^^^^^^^^^