about summary refs log tree commit diff
path: root/tests/codegen-llvm/intrinsics/transmute-niched.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/codegen-llvm/intrinsics/transmute-niched.rs')
-rw-r--r--tests/codegen-llvm/intrinsics/transmute-niched.rs223
1 files changed, 223 insertions, 0 deletions
diff --git a/tests/codegen-llvm/intrinsics/transmute-niched.rs b/tests/codegen-llvm/intrinsics/transmute-niched.rs
new file mode 100644
index 00000000000..8ff5cc8ee4f
--- /dev/null
+++ b/tests/codegen-llvm/intrinsics/transmute-niched.rs
@@ -0,0 +1,223 @@
+//@ revisions: OPT DBG
+//@ [OPT] compile-flags: -C opt-level=3 -C no-prepopulate-passes
+//@ [DBG] compile-flags: -C opt-level=0 -C no-prepopulate-passes
+//@ only-64bit (so I don't need to worry about usize)
+#![crate_type = "lib"]
+
+use std::mem::transmute;
+use std::num::NonZero;
+use std::ptr::NonNull;
+
+#[repr(u8)]
+pub enum SmallEnum {
+    A = 10,
+    B = 11,
+    C = 12,
+}
+
+// CHECK-LABEL: @check_to_enum(
+#[no_mangle]
+pub unsafe fn check_to_enum(x: i8) -> SmallEnum {
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // OPT: %0 = sub i8 %x, 10
+    // OPT: %1 = icmp ule i8 %0, 2
+    // OPT: call void @llvm.assume(i1 %1)
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // CHECK: ret i8 %x
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_from_enum(
+#[no_mangle]
+pub unsafe fn check_from_enum(x: SmallEnum) -> i8 {
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // OPT: %0 = sub i8 %x, 10
+    // OPT: %1 = icmp ule i8 %0, 2
+    // OPT: call void @llvm.assume(i1 %1)
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // CHECK: ret i8 %x
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_to_ordering(
+#[no_mangle]
+pub unsafe fn check_to_ordering(x: u8) -> std::cmp::Ordering {
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // OPT: %0 = sub i8 %x, -1
+    // OPT: %1 = icmp ule i8 %0, 2
+    // OPT: call void @llvm.assume(i1 %1)
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // CHECK: ret i8 %x
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_from_ordering(
+#[no_mangle]
+pub unsafe fn check_from_ordering(x: std::cmp::Ordering) -> u8 {
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // OPT: %0 = sub i8 %x, -1
+    // OPT: %1 = icmp ule i8 %0, 2
+    // OPT: call void @llvm.assume(i1 %1)
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // CHECK: ret i8 %x
+
+    transmute(x)
+}
+
+#[repr(i32)]
+pub enum Minus100ToPlus100 {
+    A = -100,
+    B = -90,
+    C = -80,
+    D = -70,
+    E = -60,
+    F = -50,
+    G = -40,
+    H = -30,
+    I = -20,
+    J = -10,
+    K = 0,
+    L = 10,
+    M = 20,
+    N = 30,
+    O = 40,
+    P = 50,
+    Q = 60,
+    R = 70,
+    S = 80,
+    T = 90,
+    U = 100,
+}
+
+// CHECK-LABEL: @check_enum_from_char(
+#[no_mangle]
+pub unsafe fn check_enum_from_char(x: char) -> Minus100ToPlus100 {
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // OPT: %0 = icmp ule i32 %x, 1114111
+    // OPT: call void @llvm.assume(i1 %0)
+    // OPT: %1 = sub i32 %x, -100
+    // OPT: %2 = icmp ule i32 %1, 200
+    // OPT: call void @llvm.assume(i1 %2)
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // CHECK: ret i32 %x
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_enum_to_char(
+#[no_mangle]
+pub unsafe fn check_enum_to_char(x: Minus100ToPlus100) -> char {
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // OPT: %0 = sub i32 %x, -100
+    // OPT: %1 = icmp ule i32 %0, 200
+    // OPT: call void @llvm.assume(i1 %1)
+    // OPT: %2 = icmp ule i32 %x, 1114111
+    // OPT: call void @llvm.assume(i1 %2)
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // CHECK: ret i32 %x
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_swap_pair(
+#[no_mangle]
+pub unsafe fn check_swap_pair(x: (char, NonZero<u32>)) -> (NonZero<u32>, char) {
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // OPT: %0 = icmp ule i32 %x.0, 1114111
+    // OPT: call void @llvm.assume(i1 %0)
+    // OPT: %1 = sub i32 %x.0, 1
+    // OPT: %2 = icmp ule i32 %1, -2
+    // OPT: call void @llvm.assume(i1 %2)
+    // OPT: %3 = sub i32 %x.1, 1
+    // OPT: %4 = icmp ule i32 %3, -2
+    // OPT: call void @llvm.assume(i1 %4)
+    // OPT: %5 = icmp ule i32 %x.1, 1114111
+    // OPT: call void @llvm.assume(i1 %5)
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // CHECK: %[[P1:.+]] = insertvalue { i32, i32 } poison, i32 %x.0, 0
+    // CHECK: %[[P2:.+]] = insertvalue { i32, i32 } %[[P1]], i32 %x.1, 1
+    // CHECK: ret { i32, i32 } %[[P2]]
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_bool_from_ordering(
+#[no_mangle]
+pub unsafe fn check_bool_from_ordering(x: std::cmp::Ordering) -> bool {
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // OPT: %0 = sub i8 %x, -1
+    // OPT: %1 = icmp ule i8 %0, 2
+    // OPT: call void @llvm.assume(i1 %1)
+    // OPT: %2 = icmp ule i8 %x, 1
+    // OPT: call void @llvm.assume(i1 %2)
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // CHECK: %[[R:.+]] = trunc{{( nuw)?}} i8 %x to i1
+    // CHECK: ret i1 %[[R]]
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_bool_to_ordering(
+#[no_mangle]
+pub unsafe fn check_bool_to_ordering(x: bool) -> std::cmp::Ordering {
+    // CHECK: %_0 = zext i1 %x to i8
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // OPT: %0 = icmp ule i8 %_0, 1
+    // OPT: call void @llvm.assume(i1 %0)
+    // OPT: %1 = sub i8 %_0, -1
+    // OPT: %2 = icmp ule i8 %1, 2
+    // OPT: call void @llvm.assume(i1 %2)
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // CHECK: ret i8 %_0
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_nonnull_to_ptr(
+#[no_mangle]
+pub unsafe fn check_nonnull_to_ptr(x: NonNull<u8>) -> *const u8 {
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // OPT: %0 = icmp ne ptr %x, null
+    // OPT: call void @llvm.assume(i1 %0)
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // CHECK: ret ptr %x
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_ptr_to_nonnull(
+#[no_mangle]
+pub unsafe fn check_ptr_to_nonnull(x: *const u8) -> NonNull<u8> {
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // OPT: %0 = icmp ne ptr %x, null
+    // OPT: call void @llvm.assume(i1 %0)
+    // CHECK-NOT: icmp
+    // CHECK-NOT: assume
+    // CHECK: ret ptr %x
+
+    transmute(x)
+}