about summary refs log tree commit diff
path: root/src/test/codegen
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-07-10 03:08:47 +0000
committerbors <bors@rust-lang.org>2018-07-10 03:08:47 +0000
commitb3e7d70ce7730a929fd3d5094e8ad2eb71c3a399 (patch)
tree3b1aa2db6d7f2e2ea069bf23cb12f8b801a2ee19 /src/test/codegen
parent295858eba7543b31984184df8a20d874446a6a05 (diff)
parent557736befc84fb72066128a8c42efe6e4e63a3b1 (diff)
downloadrust-b3e7d70ce7730a929fd3d5094e8ad2eb71c3a399.tar.gz
rust-b3e7d70ce7730a929fd3d5094e8ad2eb71c3a399.zip
Auto merge of #51583 - cuviper:packed_pair-bool, r=Mark-Simulacrum
Store scalar pair bools as i8 in memory

We represent `bool` as `i1` in a `ScalarPair`, unlike other aggregates,
to optimize IR for checked operators and the like.  With this patch, we
still do so when the pair is an immediate value, but we use the `i8`
memory type when the value is loaded or stored as an LLVM aggregate.

So `(bool, bool)` looks like an `{ i1, i1 }` immediate, but `{ i8, i8 }`
in memory.  When a pair is a direct function argument, `PassMode::Pair`,
it is still passed using the immediate `i1` type, but as a return value
it will use the `i8` memory type.  Also, `bool`-like` enum tags will now
use scalar pairs when possible, where they were previously excluded due
to optimization issues.

Fixes #51516.
Closes #51566.

r? @eddyb
cc @nox
Diffstat (limited to 'src/test/codegen')
-rw-r--r--src/test/codegen/function-arguments.rs2
-rw-r--r--src/test/codegen/scalar-pair-bool.rs54
2 files changed, 55 insertions, 1 deletions
diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs
index e3fa7a7db39..c027dece014 100644
--- a/src/test/codegen/function-arguments.rs
+++ b/src/test/codegen/function-arguments.rs
@@ -149,7 +149,7 @@ pub fn enum_id_1(x: Option<Result<u16, u16>>) -> Option<Result<u16, u16>> {
   x
 }
 
-// CHECK: i16 @enum_id_2(i16)
+// CHECK: { i8, i8 } @enum_id_2(i1 zeroext %x.0, i8 %x.1)
 #[no_mangle]
 pub fn enum_id_2(x: Option<u8>) -> Option<u8> {
   x
diff --git a/src/test/codegen/scalar-pair-bool.rs b/src/test/codegen/scalar-pair-bool.rs
new file mode 100644
index 00000000000..f50e032f8e6
--- /dev/null
+++ b/src/test/codegen/scalar-pair-bool.rs
@@ -0,0 +1,54 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// CHECK: define { i8, i8 } @pair_bool_bool(i1 zeroext %pair.0, i1 zeroext %pair.1)
+#[no_mangle]
+pub fn pair_bool_bool(pair: (bool, bool)) -> (bool, bool) {
+    pair
+}
+
+// CHECK: define { i8, i32 } @pair_bool_i32(i1 zeroext %pair.0, i32 %pair.1)
+#[no_mangle]
+pub fn pair_bool_i32(pair: (bool, i32)) -> (bool, i32) {
+    pair
+}
+
+// CHECK: define { i32, i8 } @pair_i32_bool(i32 %pair.0, i1 zeroext %pair.1)
+#[no_mangle]
+pub fn pair_i32_bool(pair: (i32, bool)) -> (i32, bool) {
+    pair
+}
+
+// CHECK: define { i8, i8 } @pair_and_or(i1 zeroext %arg0.0, i1 zeroext %arg0.1)
+#[no_mangle]
+pub fn pair_and_or((a, b): (bool, bool)) -> (bool, bool) {
+    // Make sure it can operate directly on the unpacked args
+    // CHECK: and i1 %arg0.0, %arg0.1
+    // CHECK: or i1 %arg0.0, %arg0.1
+    (a && b, a || b)
+}
+
+// CHECK: define void @pair_branches(i1 zeroext %arg0.0, i1 zeroext %arg0.1)
+#[no_mangle]
+pub fn pair_branches((a, b): (bool, bool)) {
+    // Make sure it can branch directly on the unpacked bool args
+    // CHECK: br i1 %arg0.0
+    if a {
+        println!("Hello!");
+    }
+    // CHECK: br i1 %arg0.1
+    if b {
+        println!("Goodbye!");
+    }
+}