1
- //@ compile-flags: -Copt-level=3
1
+ //@ revisions: LLVM18 LLVM19PLUS
2
+ //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
3
+ //@[LLVM18] exact-llvm-major-version: 18
4
+ //@[LLVM19PLUS] min-llvm-version: 19
5
+
6
+ // This runs mir-opts to inline the standard library call, but doesn't run LLVM
7
+ // optimizations so it doesn't need to worry about them adding more flags.
2
8
3
9
#![ crate_type = "lib" ]
4
10
#![ feature( unchecked_shifts) ]
@@ -17,12 +23,9 @@ pub unsafe fn unchecked_shl_unsigned_same(a: u32, b: u32) -> u32 {
17
23
// CHECK-LABEL: @unchecked_shl_unsigned_smaller
18
24
#[ no_mangle]
19
25
pub unsafe fn unchecked_shl_unsigned_smaller ( a : u16 , b : u32 ) -> u16 {
20
- // This uses -DAG to avoid failing on irrelevant reorderings,
21
- // like emitting the truncation earlier.
22
-
23
- // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 16
24
- // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
25
- // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i32 %b to i16
26
+ // CHECK-NOT: assume
27
+ // LLVM18-DAG: %[[TRUNC:.+]] = trunc i32 %b to i16
28
+ // LLVM19PLUS-DAG: %[[TRUNC:.+]] = trunc nuw i32 %b to i16
26
29
// CHECK-DAG: shl i16 %a, %[[TRUNC]]
27
30
a. unchecked_shl ( b)
28
31
}
@@ -31,7 +34,7 @@ pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 {
31
34
#[ no_mangle]
32
35
pub unsafe fn unchecked_shl_unsigned_bigger ( a : u64 , b : u32 ) -> u64 {
33
36
// CHECK-NOT: assume
34
- // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i32 %b to i64
37
+ // CHECK: %[[EXT:.+]] = zext i32 %b to i64
35
38
// CHECK: shl i64 %a, %[[EXT]]
36
39
a. unchecked_shl ( b)
37
40
}
@@ -49,21 +52,18 @@ pub unsafe fn unchecked_shr_signed_same(a: i32, b: u32) -> i32 {
49
52
// CHECK-LABEL: @unchecked_shr_signed_smaller
50
53
#[ no_mangle]
51
54
pub unsafe fn unchecked_shr_signed_smaller ( a : i16 , b : u32 ) -> i16 {
52
- // This uses -DAG to avoid failing on irrelevant reorderings,
53
- // like emitting the truncation earlier.
54
-
55
- // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 16
56
- // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
57
- // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i32 %b to i16
58
- // CHECK-DAG: ashr i16 %a, %[[TRUNC]]
55
+ // CHECK-NOT: assume
56
+ // LLVM18: %[[TRUNC:.+]] = trunc i32 %b to i16
57
+ // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i32 %b to i16
58
+ // CHECK: ashr i16 %a, %[[TRUNC]]
59
59
a. unchecked_shr ( b)
60
60
}
61
61
62
62
// CHECK-LABEL: @unchecked_shr_signed_bigger
63
63
#[ no_mangle]
64
64
pub unsafe fn unchecked_shr_signed_bigger ( a : i64 , b : u32 ) -> i64 {
65
65
// CHECK-NOT: assume
66
- // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i32 %b to i64
66
+ // CHECK: %[[EXT:.+]] = zext i32 %b to i64
67
67
// CHECK: ashr i64 %a, %[[EXT]]
68
68
a. unchecked_shr ( b)
69
69
}
@@ -72,7 +72,7 @@ pub unsafe fn unchecked_shr_signed_bigger(a: i64, b: u32) -> i64 {
72
72
#[ no_mangle]
73
73
pub unsafe fn unchecked_shr_u128_i8 ( a : u128 , b : i8 ) -> u128 {
74
74
// CHECK-NOT: assume
75
- // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i8 %b to i128
75
+ // CHECK: %[[EXT:.+]] = zext i8 %b to i128
76
76
// CHECK: lshr i128 %a, %[[EXT]]
77
77
std:: intrinsics:: unchecked_shr ( a, b)
78
78
}
@@ -81,33 +81,27 @@ pub unsafe fn unchecked_shr_u128_i8(a: u128, b: i8) -> u128 {
81
81
#[ no_mangle]
82
82
pub unsafe fn unchecked_shl_i128_u8 ( a : i128 , b : u8 ) -> i128 {
83
83
// CHECK-NOT: assume
84
- // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i8 %b to i128
84
+ // CHECK: %[[EXT:.+]] = zext i8 %b to i128
85
85
// CHECK: shl i128 %a, %[[EXT]]
86
86
std:: intrinsics:: unchecked_shl ( a, b)
87
87
}
88
88
89
89
// CHECK-LABEL: @unchecked_shl_u8_i128
90
90
#[ no_mangle]
91
91
pub unsafe fn unchecked_shl_u8_i128 ( a : u8 , b : i128 ) -> u8 {
92
- // This uses -DAG to avoid failing on irrelevant reorderings,
93
- // like emitting the truncation earlier.
94
-
95
- // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i128 %b, 8
96
- // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
97
- // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i128 %b to i8
98
- // CHECK-DAG: shl i8 %a, %[[TRUNC]]
92
+ // CHECK-NOT: assume
93
+ // LLVM18: %[[TRUNC:.+]] = trunc i128 %b to i8
94
+ // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i128 %b to i8
95
+ // CHECK: shl i8 %a, %[[TRUNC]]
99
96
std:: intrinsics:: unchecked_shl ( a, b)
100
97
}
101
98
102
99
// CHECK-LABEL: @unchecked_shr_i8_u128
103
100
#[ no_mangle]
104
101
pub unsafe fn unchecked_shr_i8_u128 ( a : i8 , b : u128 ) -> i8 {
105
- // This uses -DAG to avoid failing on irrelevant reorderings,
106
- // like emitting the truncation earlier.
107
-
108
- // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i128 %b, 8
109
- // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
110
- // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i128 %b to i8
111
- // CHECK-DAG: ashr i8 %a, %[[TRUNC]]
102
+ // CHECK-NOT: assume
103
+ // LLVM18: %[[TRUNC:.+]] = trunc i128 %b to i8
104
+ // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i128 %b to i8
105
+ // CHECK: ashr i8 %a, %[[TRUNC]]
112
106
std:: intrinsics:: unchecked_shr ( a, b)
113
107
}
0 commit comments