about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/codegen/is_val_statically_known.rs50
-rw-r--r--tests/codegen/pow_of_two.rs68
-rw-r--r--tests/ui/consts/is_val_statically_known.rs15
3 files changed, 133 insertions, 0 deletions
diff --git a/tests/codegen/is_val_statically_known.rs b/tests/codegen/is_val_statically_known.rs
new file mode 100644
index 00000000000..4dcab744235
--- /dev/null
+++ b/tests/codegen/is_val_statically_known.rs
@@ -0,0 +1,50 @@
+// #[cfg(bootstrap)]
+// ignore-stage1
+// compile-flags: --crate-type=lib -Zmerge-functions=disabled
+
+#![feature(core_intrinsics)]
+
+use std::intrinsics::is_val_statically_known;
+
+pub struct A(u32);
+pub enum B {
+    Ye(u32),
+}
+
+#[inline]
+pub fn _u32(a: u32) -> i32 {
+    if unsafe { is_val_statically_known(a) } { 1 } else { 0 }
+}
+
+// CHECK-LABEL: @_u32_true(
+#[no_mangle]
+pub fn _u32_true() -> i32 {
+    // CHECK: ret i32 1
+    _u32(1)
+}
+
+// CHECK-LABEL: @_u32_false(
+#[no_mangle]
+pub fn _u32_false(a: u32) -> i32 {
+    // CHECK: ret i32 0
+    _u32(a)
+}
+
+#[inline]
+pub fn _bool(b: bool) -> i32 {
+    if unsafe { is_val_statically_known(b) } { 3 } else { 2 }
+}
+
+// CHECK-LABEL: @_bool_true(
+#[no_mangle]
+pub fn _bool_true() -> i32 {
+    // CHECK: ret i32 3
+    _bool(true)
+}
+
+// CHECK-LABEL: @_bool_false(
+#[no_mangle]
+pub fn _bool_false(b: bool) -> i32 {
+    // CHECK: ret i32 2
+    _bool(b)
+}
diff --git a/tests/codegen/pow_of_two.rs b/tests/codegen/pow_of_two.rs
new file mode 100644
index 00000000000..3bce5535c66
--- /dev/null
+++ b/tests/codegen/pow_of_two.rs
@@ -0,0 +1,68 @@
+// #[cfg(bootstrap)]
+// ignore-stage1
+// compile-flags: --crate-type=lib -Zmerge-functions=disabled
+
+// CHECK-LABEL: @a(
+#[no_mangle]
+pub fn a(exp: u32) -> u64 {
+    // CHECK: %[[R:.+]] = and i32 %exp, 63
+    // CHECK: %[[R:.+]] = zext i32 %[[R:.+]] to i64
+    // CHECK: %[[R:.+]] = shl nuw i64 %[[R:.+]].i, %[[R:.+]]
+    // CHECK: ret i64 %[[R:.+]]
+    2u64.pow(exp)
+}
+
+#[no_mangle]
+pub fn b(exp: u32) -> i64 {
+    // CHECK: %[[R:.+]] = and i32 %exp, 63
+    // CHECK: %[[R:.+]] = zext i32 %[[R:.+]] to i64
+    // CHECK: %[[R:.+]] = shl nuw i64 %[[R:.+]].i, %[[R:.+]]
+    // CHECK: ret i64 %[[R:.+]]
+    2i64.pow(exp)
+}
+
+// CHECK-LABEL: @c(
+#[no_mangle]
+pub fn c(exp: u32) -> u32 {
+    // CHECK: %[[R:.+]].0.i = shl i32 %exp, 1
+    // CHECK: %[[R:.+]].1.i = icmp sgt i32 %exp, -1
+    // CHECK: %[[R:.+]].i = icmp ult i32 %[[R:.+]].0.i, 32
+    // CHECK: %fine.i = and i1 %[[R:.+]].1.i, %[[R:.+]].i
+    // CHECK: %0 = and i32 %[[R:.+]].0.i, 30
+    // CHECK: %[[R:.+]].i = zext i1 %fine.i to i32
+    // CHECK: %[[R:.+]] = shl nuw nsw i32 %[[R:.+]].i, %0
+    // CHECK: ret i32 %[[R:.+]]
+    4u32.pow(exp)
+}
+
+// CHECK-LABEL: @d(
+#[no_mangle]
+pub fn d(exp: u32) -> u32 {
+    // CHECK: tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %exp, i32 5)
+    // CHECK: %[[R:.+]].0.i = extractvalue { i32, i1 } %[[R:.+]], 0
+    // CHECK: %[[R:.+]].1.i = extractvalue { i32, i1 } %[[R:.+]], 1
+    // CHECK: %[[R:.+]].i = xor i1 %[[R:.+]].1.i, true
+    // CHECK: %[[R:.+]].i = icmp ult i32 %[[R:.+]].0.i, 32
+    // CHECK: %fine.i = and i1 %[[R:.+]].i, %[[R:.+]].i
+    // CHECK: %[[R:.+]] = and i32 %[[R:.+]].0.i, 31
+    // CHECK: %[[R:.+]].i = zext i1 %fine.i to i32
+    // CHECK: %[[R:.+]] = shl nuw i32 %[[R:.+]].i, %1
+    // CHECK: ret i32 %[[R:.+]]
+    32u32.pow(exp)
+}
+
+// CHECK-LABEL: @e(
+#[no_mangle]
+pub fn e(exp: u32) -> i32 {
+    // CHECK: tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %exp, i32 5)
+    // CHECK: %[[R:.+]].0.i = extractvalue { i32, i1 } %[[R:.+]], 0
+    // CHECK: %[[R:.+]].i = icmp ult i32 %[[R:.+]].0.i, 32
+    // CHECK: %[[R:.+]].1.i = extractvalue { i32, i1 } %[[R:.+]], 1
+    // CHECK: %[[R:.+]].i = xor i1 %[[R:.+]].1.i, true
+    // CHECK: %fine.i = and i1 %[[R:.+]].i, %[[R:.+]].i
+    // CHECK: %[[R:.+]].i = zext i1 %fine.i to i32
+    // CHECK: %[[R:.+]] = and i32 %[[R:.+]].0.i, 31
+    // CHECK: %[[R:.+]] = shl nuw i32 %[[R:.+]].i, %1
+    // CHECK: ret i32 %[[R:.+]]
+    32i32.pow(exp)
+}
diff --git a/tests/ui/consts/is_val_statically_known.rs b/tests/ui/consts/is_val_statically_known.rs
new file mode 100644
index 00000000000..b0565842eb4
--- /dev/null
+++ b/tests/ui/consts/is_val_statically_known.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+#![feature(core_intrinsics)]
+#![feature(is_val_statically_known)]
+
+use std::intrinsics::is_val_statically_known;
+
+const CONST_TEST: bool = unsafe { is_val_statically_known(0) };
+
+fn main() {
+    if CONST_TEST {
+        unreachable!("currently expected to return false during const eval");
+        // but note that this is not a guarantee!
+    }
+}