File tree 2 files changed +89
-1
lines changed
2 files changed +89
-1
lines changed Original file line number Diff line number Diff line change @@ -104,7 +104,22 @@ macro_rules! nonzero_integers {
104
104
#[ inline]
105
105
#[ rustc_const_stable( feature = "const_nonzero_get" , since = "1.34.0" ) ]
106
106
pub const fn get( self ) -> $Int {
107
- self . 0
107
+ // FIXME: Remove this after LLVM supports `!range` metadata for function
108
+ // arguments https://github.com/llvm/llvm-project/issues/76628
109
+ //
110
+ // Rustc can set range metadata only if it loads `self` from
111
+ // memory somewhere. If the value of `self` was from by-value argument
112
+ // of some not-inlined function, LLVM don't have range metadata
113
+ // to understand that the value cannot be zero.
114
+ if self . 0 == 0 {
115
+ // SAFETY: It is an invariant of this type.
116
+ unsafe {
117
+ crate :: hint:: unreachable_unchecked( )
118
+ }
119
+ }
120
+ else {
121
+ self . 0
122
+ }
108
123
}
109
124
110
125
}
Original file line number Diff line number Diff line change
1
+ //! This test checks that compiler don't generate useless compares to zeros
2
+ //! for NonZero integer types.
3
+
4
+ // compile-flags: -O --edition=2021 -Zmerge-functions=disabled
5
+ // only-64bit (because the LLVM type of i64 for usize shows up)
6
+
7
+ #![ crate_type = "lib" ]
8
+
9
+ use core:: num:: * ;
10
+ use core:: ptr:: NonNull ;
11
+
12
+ // CHECK-LABEL: @check_non_null
13
+ #[ no_mangle]
14
+ pub fn check_non_null ( x : NonNull < u8 > ) -> bool {
15
+ // CHECK: ret i1 false
16
+ x. as_ptr ( ) . is_null ( )
17
+ }
18
+
19
+ // CHECK-LABEL: @equals_zero_is_false_u8
20
+ #[ no_mangle]
21
+ pub fn equals_zero_is_false_u8 ( x : NonZeroU8 ) -> bool {
22
+ // CHECK-NOT: br
23
+ // CHECK: ret i1 false
24
+ // CHECK-NOT: br
25
+ x. get ( ) == 0
26
+ }
27
+
28
+ // CHECK-LABEL: @not_equals_zero_is_true_u8
29
+ #[ no_mangle]
30
+ pub fn not_equals_zero_is_true_u8 ( x : NonZeroU8 ) -> bool {
31
+ // CHECK-NOT: br
32
+ // CHECK: ret i1 true
33
+ // CHECK-NOT: br
34
+ x. get ( ) != 0
35
+ }
36
+
37
+ // CHECK-LABEL: @equals_zero_is_false_i8
38
+ #[ no_mangle]
39
+ pub fn equals_zero_is_false_i8 ( x : NonZeroI8 ) -> bool {
40
+ // CHECK-NOT: br
41
+ // CHECK: ret i1 false
42
+ // CHECK-NOT: br
43
+ x. get ( ) == 0
44
+ }
45
+
46
+ // CHECK-LABEL: @not_equals_zero_is_true_i8
47
+ #[ no_mangle]
48
+ pub fn not_equals_zero_is_true_i8 ( x : NonZeroI8 ) -> bool {
49
+ // CHECK-NOT: br
50
+ // CHECK: ret i1 true
51
+ // CHECK-NOT: br
52
+ x. get ( ) != 0
53
+ }
54
+
55
+ // CHECK-LABEL: @usize_try_from_u32
56
+ #[ no_mangle]
57
+ pub fn usize_try_from_u32 ( x : NonZeroU32 ) -> NonZeroUsize {
58
+ // CHECK-NOT: br
59
+ // CHECK: zext i32 %{{.*}} to i64
60
+ // CHECK-NOT: br
61
+ // CHECK: ret i64
62
+ x. try_into ( ) . unwrap ( )
63
+ }
64
+
65
+ // CHECK-LABEL: @isize_try_from_i32
66
+ #[ no_mangle]
67
+ pub fn isize_try_from_i32 ( x : NonZeroI32 ) -> NonZeroIsize {
68
+ // CHECK-NOT: br
69
+ // CHECK: sext i32 %{{.*}} to i64
70
+ // CHECK-NOT: br
71
+ // CHECK: ret i64
72
+ x. try_into ( ) . unwrap ( )
73
+ }
You can’t perform that action at this time.
0 commit comments