about summary refs log tree commit diff
path: root/src/test/codegen
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-11-22 00:16:40 +0000
committerbors <bors@rust-lang.org>2019-11-22 00:16:40 +0000
commitabd69551bf8b8755b5e00d4f4d45ae5d4a0cd17d (patch)
tree6cd22524b2a19f2abff2c9aedba0c086411b1644 /src/test/codegen
parentf11759d38c70d3df67135f88a682701c1cf9762a (diff)
parent2f00e86cb5cbb4d4cfe17abc6136aacadbe02382 (diff)
downloadrust-abd69551bf8b8755b5e00d4f4d45ae5d4a0cd17d.tar.gz
rust-abd69551bf8b8755b5e00d4f4d45ae5d4a0cd17d.zip
Auto merge of #66282 - Centril:simplify-try, r=oli-obk
[mir-opt] asking `?`s in a more optimized fashion

This PR works towards https://github.com/rust-lang/rust/issues/66234 by providing two optimization passes meant to run in sequence:

- `SimplifyArmIdentity` which transforms something like:
  ```rust
  _LOCAL_TMP = ((_LOCAL_1 as Variant ).FIELD: TY );
  ((_LOCAL_0 as Variant).FIELD: TY) = move _LOCAL_TMP;
  discriminant(_LOCAL_0) = VAR_IDX;
  ```

  into:

  ```rust
  _LOCAL_0 = move _LOCAL_1
  ```

- `SimplifyBranchSame` which transforms `SwitchInt`s to identical basic blocks into a `goto` to the first reachable target.

Together, these are meant to simplify the following into just `res`:
```rust
match res {
    Ok(x) => Ok(x),
    Err(x) => Err(x),
}
```

It should be noted however that the desugaring of `?` includes a function call and so the first pass in this PR relies on inlining to substitute that function call for identity on `x`. Inlining requires `mir-opt-level=2` so this might not have any effect in perf-bot but let's find out.

r? @oli-obk -- This is WIP, but I'd appreciate feedback. :)
Diffstat (limited to 'src/test/codegen')
-rw-r--r--src/test/codegen/match.rs8
-rw-r--r--src/test/codegen/try_identity.rs17
2 files changed, 22 insertions, 3 deletions
diff --git a/src/test/codegen/match.rs b/src/test/codegen/match.rs
index 145d4ba6b4c..b5ee5ba2394 100644
--- a/src/test/codegen/match.rs
+++ b/src/test/codegen/match.rs
@@ -9,19 +9,21 @@ pub enum E {
 
 // CHECK-LABEL: @exhaustive_match
 #[no_mangle]
-pub fn exhaustive_match(e: E, unit: ()) {
+pub fn exhaustive_match(e: E) -> u8 {
 // CHECK: switch{{.*}}, label %[[OTHERWISE:[a-zA-Z0-9_]+]] [
 // CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[A:[a-zA-Z0-9_]+]]
 // CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[B:[a-zA-Z0-9_]+]]
 // CHECK-NEXT: ]
 // CHECK: [[B]]:
+// CHECK-NEXT: store i8 1, i8* %1, align 1
 // CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
 // CHECK: [[OTHERWISE]]:
 // CHECK-NEXT: unreachable
 // CHECK: [[A]]:
+// CHECK-NEXT: store i8 0, i8* %1, align 1
 // CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
     match e {
-        E::A => unit,
-        E::B => unit,
+        E::A => 0,
+        E::B => 1,
     }
 }
diff --git a/src/test/codegen/try_identity.rs b/src/test/codegen/try_identity.rs
new file mode 100644
index 00000000000..30e7adfddf7
--- /dev/null
+++ b/src/test/codegen/try_identity.rs
@@ -0,0 +1,17 @@
+// compile-flags: -C no-prepopulate-passes -Z mir-opt-level=2
+
+// Ensure that `x?` has no overhead on `Result<T, E>` due to identity `match`es in lowering.
+// This requires inlining to trigger the MIR optimizations in `SimplifyArmIdentity`.
+
+#![crate_type = "lib"]
+
+type R = Result<u64, i32>;
+
+#[no_mangle]
+fn try_identity(x: R) -> R {
+// CHECK: start:
+// CHECK-NOT: br {{.*}}
+// CHECK ret void
+    let y = x?;
+    Ok(y)
+}