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.
28
39#![ crate_type = "lib" ]
410#![ feature( unchecked_shifts) ]
@@ -17,12 +23,9 @@ pub unsafe fn unchecked_shl_unsigned_same(a: u32, b: u32) -> u32 {
1723// CHECK-LABEL: @unchecked_shl_unsigned_smaller
1824#[ no_mangle]
1925pub 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
2629 // CHECK-DAG: shl i16 %a, %[[TRUNC]]
2730 a. unchecked_shl ( b)
2831}
@@ -31,7 +34,7 @@ pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 {
3134#[ no_mangle]
3235pub unsafe fn unchecked_shl_unsigned_bigger ( a : u64 , b : u32 ) -> u64 {
3336 // CHECK-NOT: assume
34- // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i32 %b to i64
37+ // CHECK: %[[EXT:.+]] = zext i32 %b to i64
3538 // CHECK: shl i64 %a, %[[EXT]]
3639 a. unchecked_shl ( b)
3740}
@@ -49,21 +52,18 @@ pub unsafe fn unchecked_shr_signed_same(a: i32, b: u32) -> i32 {
4952// CHECK-LABEL: @unchecked_shr_signed_smaller
5053#[ no_mangle]
5154pub 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]]
5959 a. unchecked_shr ( b)
6060}
6161
6262// CHECK-LABEL: @unchecked_shr_signed_bigger
6363#[ no_mangle]
6464pub unsafe fn unchecked_shr_signed_bigger ( a : i64 , b : u32 ) -> i64 {
6565 // CHECK-NOT: assume
66- // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i32 %b to i64
66+ // CHECK: %[[EXT:.+]] = zext i32 %b to i64
6767 // CHECK: ashr i64 %a, %[[EXT]]
6868 a. unchecked_shr ( b)
6969}
@@ -72,7 +72,7 @@ pub unsafe fn unchecked_shr_signed_bigger(a: i64, b: u32) -> i64 {
7272#[ no_mangle]
7373pub unsafe fn unchecked_shr_u128_i8 ( a : u128 , b : i8 ) -> u128 {
7474 // CHECK-NOT: assume
75- // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i8 %b to i128
75+ // CHECK: %[[EXT:.+]] = zext i8 %b to i128
7676 // CHECK: lshr i128 %a, %[[EXT]]
7777 std:: intrinsics:: unchecked_shr ( a, b)
7878}
@@ -81,33 +81,27 @@ pub unsafe fn unchecked_shr_u128_i8(a: u128, b: i8) -> u128 {
8181#[ no_mangle]
8282pub unsafe fn unchecked_shl_i128_u8 ( a : i128 , b : u8 ) -> i128 {
8383 // CHECK-NOT: assume
84- // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i8 %b to i128
84+ // CHECK: %[[EXT:.+]] = zext i8 %b to i128
8585 // CHECK: shl i128 %a, %[[EXT]]
8686 std:: intrinsics:: unchecked_shl ( a, b)
8787}
8888
8989// CHECK-LABEL: @unchecked_shl_u8_i128
9090#[ no_mangle]
9191pub 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]]
9996 std:: intrinsics:: unchecked_shl ( a, b)
10097}
10198
10299// CHECK-LABEL: @unchecked_shr_i8_u128
103100#[ no_mangle]
104101pub 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]]
112106 std:: intrinsics:: unchecked_shr ( a, b)
113107}
0 commit comments