]>
Commit | Line | Data |
---|---|---|
49aad941 | 1 | // compile-flags: -O -Z merge-functions=disabled |
49aad941 FG |
2 | // ignore-debug |
3 | ||
4 | #![crate_type = "lib"] | |
5 | ||
6 | // This tests that LLVM can optimize based on the niches in the source or | |
7 | // destination types for transmutes. | |
8 | ||
9 | #[repr(u32)] | |
10 | pub enum AlwaysZero32 { X = 0 } | |
11 | ||
12 | // CHECK-LABEL: i32 @issue_109958(i32 | |
13 | #[no_mangle] | |
14 | pub fn issue_109958(x: AlwaysZero32) -> i32 { | |
15 | // CHECK: ret i32 0 | |
16 | unsafe { std::mem::transmute(x) } | |
17 | } | |
18 | ||
19 | // CHECK-LABEL: i1 @reference_is_null(ptr | |
20 | #[no_mangle] | |
21 | pub fn reference_is_null(x: &i32) -> bool { | |
22 | // CHECK: ret i1 false | |
23 | let p: *const i32 = unsafe { std::mem::transmute(x) }; | |
24 | p.is_null() | |
25 | } | |
26 | ||
27 | // CHECK-LABEL: i1 @non_null_is_null(ptr | |
28 | #[no_mangle] | |
29 | pub fn non_null_is_null(x: std::ptr::NonNull<i32>) -> bool { | |
30 | // CHECK: ret i1 false | |
31 | let p: *const i32 = unsafe { std::mem::transmute(x) }; | |
32 | p.is_null() | |
33 | } | |
34 | ||
35 | // CHECK-LABEL: i1 @non_zero_is_null( | |
36 | #[no_mangle] | |
37 | pub fn non_zero_is_null(x: std::num::NonZeroUsize) -> bool { | |
38 | // CHECK: ret i1 false | |
39 | let p: *const i32 = unsafe { std::mem::transmute(x) }; | |
40 | p.is_null() | |
41 | } | |
42 | ||
43 | // CHECK-LABEL: i1 @non_null_is_zero(ptr | |
44 | #[no_mangle] | |
45 | pub fn non_null_is_zero(x: std::ptr::NonNull<i32>) -> bool { | |
46 | // CHECK: ret i1 false | |
47 | let a: isize = unsafe { std::mem::transmute(x) }; | |
48 | a == 0 | |
49 | } | |
50 | ||
51 | // CHECK-LABEL: i1 @bool_ordering_is_ge(i1 | |
52 | #[no_mangle] | |
53 | pub fn bool_ordering_is_ge(x: bool) -> bool { | |
54 | // CHECK: ret i1 true | |
55 | let y: std::cmp::Ordering = unsafe { std::mem::transmute(x) }; | |
56 | y.is_ge() | |
57 | } | |
58 | ||
59 | // CHECK-LABEL: i1 @ordering_is_ge_then_transmute_to_bool(i8 | |
60 | #[no_mangle] | |
61 | pub fn ordering_is_ge_then_transmute_to_bool(x: std::cmp::Ordering) -> bool { | |
62 | let r = x.is_ge(); | |
63 | let _: bool = unsafe { std::mem::transmute(x) }; | |
64 | r | |
65 | } | |
66 | ||
67 | // CHECK-LABEL: i32 @normal_div(i32 | |
68 | #[no_mangle] | |
69 | pub fn normal_div(a: u32, b: u32) -> u32 { | |
70 | // CHECK: call core::panicking::panic | |
71 | a / b | |
72 | } | |
73 | ||
74 | // CHECK-LABEL: i32 @div_transmute_nonzero(i32 | |
75 | #[no_mangle] | |
76 | pub fn div_transmute_nonzero(a: u32, b: std::num::NonZeroI32) -> u32 { | |
77 | // CHECK-NOT: call core::panicking::panic | |
78 | // CHECK: %[[R:.+]] = udiv i32 %a, %b | |
79 | // CHECK-NEXT: ret i32 %[[R]] | |
80 | // CHECK-NOT: call core::panicking::panic | |
81 | let d: u32 = unsafe { std::mem::transmute(b) }; | |
82 | a / d | |
83 | } | |
84 | ||
85 | #[repr(i8)] | |
86 | pub enum OneTwoThree { One = 1, Two = 2, Three = 3 } | |
87 | ||
88 | // CHECK-LABEL: i8 @ordering_transmute_onetwothree(i8 | |
89 | #[no_mangle] | |
90 | pub unsafe fn ordering_transmute_onetwothree(x: std::cmp::Ordering) -> OneTwoThree { | |
91 | // CHECK: ret i8 1 | |
92 | std::mem::transmute(x) | |
93 | } | |
94 | ||
95 | // CHECK-LABEL: i8 @onetwothree_transmute_ordering(i8 | |
96 | #[no_mangle] | |
97 | pub unsafe fn onetwothree_transmute_ordering(x: OneTwoThree) -> std::cmp::Ordering { | |
98 | // CHECK: ret i8 1 | |
99 | std::mem::transmute(x) | |
100 | } | |
101 | ||
102 | // CHECK-LABEL: i1 @char_is_negative(i32 | |
103 | #[no_mangle] | |
104 | pub fn char_is_negative(c: char) -> bool { | |
105 | // CHECK: ret i1 false | |
106 | let x: i32 = unsafe { std::mem::transmute(c) }; | |
107 | x < 0 | |
108 | } |