File tree Expand file tree Collapse file tree 2 files changed +89
-1
lines changed Expand file tree Collapse file tree 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 {
104104 #[ inline]
105105 #[ rustc_const_stable( feature = "const_nonzero_get" , since = "1.34.0" ) ]
106106 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+ }
108123 }
109124
110125 }
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