Skip to content

Commit cf017e8

Browse files
authored
Restore support for bitwise SIMD intrinsics (rust-lang#1893)
1 parent 0e1f2aa commit cf017e8

File tree

3 files changed

+107
-13
lines changed

3 files changed

+107
-13
lines changed

kani-compiler/src/codegen_cprover_gotoc/codegen/intrinsic.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ impl<'tcx> GotocCtx<'tcx> {
609609
"simd_add" => {
610610
unstable_codegen!(codegen_simd_with_overflow_check!(plus, add_overflow_p))
611611
}
612-
"simd_and" => unstable_codegen!(codegen_intrinsic_binop!(bitand)),
612+
"simd_and" => codegen_intrinsic_binop!(bitand),
613613
"simd_div" => unstable_codegen!(codegen_intrinsic_binop!(div)),
614614
"simd_eq" => self.codegen_simd_cmp(Expr::vector_eq, fargs, p, span, farg_types, ret_ty),
615615
"simd_extract" => {
@@ -628,7 +628,7 @@ impl<'tcx> GotocCtx<'tcx> {
628628
"simd_ne" => {
629629
self.codegen_simd_cmp(Expr::vector_neq, fargs, p, span, farg_types, ret_ty)
630630
}
631-
"simd_or" => unstable_codegen!(codegen_intrinsic_binop!(bitor)),
631+
"simd_or" => codegen_intrinsic_binop!(bitor),
632632
"simd_rem" => unstable_codegen!(codegen_intrinsic_binop!(rem)),
633633
"simd_shl" => unstable_codegen!(codegen_intrinsic_binop!(shl)),
634634
"simd_shr" => {
@@ -643,7 +643,7 @@ impl<'tcx> GotocCtx<'tcx> {
643643
}
644644
// "simd_shuffle#" => handled in an `if` preceding this match
645645
"simd_sub" => unstable_codegen!(codegen_simd_with_overflow_check!(sub, sub_overflow_p)),
646-
"simd_xor" => unstable_codegen!(codegen_intrinsic_binop!(bitxor)),
646+
"simd_xor" => codegen_intrinsic_binop!(bitxor),
647647
"size_of" => codegen_intrinsic_const!(),
648648
"size_of_val" => codegen_size_align!(size),
649649
"sqrtf32" => unstable_codegen!(codegen_simple_intrinsic!(Sqrtf)),
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
//! Checks that the following SIMD intrinsics are supported:
5+
//! * `simd_and`
6+
//! * `simd_or`
7+
//! * `simd_xor`
8+
//! This is done by initializing vectors with the contents of 2-member tuples
9+
//! with symbolic values. The result of using each of the intrinsics is compared
10+
//! against the result of using the associated bitwise operator on the tuples.
11+
#![feature(repr_simd, platform_intrinsics)]
12+
13+
#[repr(simd)]
14+
#[allow(non_camel_case_types)]
15+
#[derive(Clone, Copy, PartialEq, Eq)]
16+
pub struct i8x2(i8, i8);
17+
18+
#[repr(simd)]
19+
#[allow(non_camel_case_types)]
20+
#[derive(Clone, Copy, PartialEq, Eq)]
21+
pub struct i16x2(i16, i16);
22+
23+
#[repr(simd)]
24+
#[allow(non_camel_case_types)]
25+
#[derive(Clone, Copy, PartialEq, Eq)]
26+
pub struct i32x2(i32, i32);
27+
28+
#[repr(simd)]
29+
#[allow(non_camel_case_types)]
30+
#[derive(Clone, Copy, PartialEq, Eq)]
31+
pub struct i64x2(i64, i64);
32+
33+
#[repr(simd)]
34+
#[allow(non_camel_case_types)]
35+
#[derive(Clone, Copy, PartialEq, Eq)]
36+
pub struct u8x2(u8, u8);
37+
38+
#[repr(simd)]
39+
#[allow(non_camel_case_types)]
40+
#[derive(Clone, Copy, PartialEq, Eq)]
41+
pub struct u16x2(u16, u16);
42+
43+
#[repr(simd)]
44+
#[allow(non_camel_case_types)]
45+
#[derive(Clone, Copy, PartialEq, Eq)]
46+
pub struct u32x2(u32, u32);
47+
48+
#[repr(simd)]
49+
#[allow(non_camel_case_types)]
50+
#[derive(Clone, Copy, PartialEq, Eq)]
51+
pub struct u64x2(u64, u64);
52+
53+
extern "platform-intrinsic" {
54+
fn simd_and<T>(x: T, y: T) -> T;
55+
fn simd_or<T>(x: T, y: T) -> T;
56+
fn simd_xor<T>(x: T, y: T) -> T;
57+
}
58+
macro_rules! compare_simd_op_with_normal_op {
59+
($simd_op: ident, $normal_op: tt, $simd_type: ident) => {
60+
let tup_x = (kani::any(), kani::any());
61+
let tup_y = (kani::any(), kani::any());
62+
let x = $simd_type(tup_x.0, tup_x.1);
63+
let y = $simd_type(tup_y.0, tup_y.1);
64+
let res_and = unsafe { $simd_op(x, y) };
65+
assert_eq!(tup_x.0 $normal_op tup_y.0, res_and.0);
66+
assert_eq!(tup_x.1 $normal_op tup_y.1, res_and.1);
67+
};
68+
}
69+
70+
#[kani::proof]
71+
fn test_simd_and() {
72+
compare_simd_op_with_normal_op!(simd_and, &, i8x2);
73+
compare_simd_op_with_normal_op!(simd_and, &, i16x2);
74+
compare_simd_op_with_normal_op!(simd_and, &, i32x2);
75+
compare_simd_op_with_normal_op!(simd_and, &, i64x2);
76+
compare_simd_op_with_normal_op!(simd_and, &, u8x2);
77+
compare_simd_op_with_normal_op!(simd_and, &, u16x2);
78+
compare_simd_op_with_normal_op!(simd_and, &, u32x2);
79+
compare_simd_op_with_normal_op!(simd_and, &, u64x2);
80+
}
81+
82+
#[kani::proof]
83+
fn test_simd_or() {
84+
compare_simd_op_with_normal_op!(simd_or, |, i8x2);
85+
compare_simd_op_with_normal_op!(simd_or, |, i16x2);
86+
compare_simd_op_with_normal_op!(simd_or, |, i32x2);
87+
compare_simd_op_with_normal_op!(simd_or, |, i64x2);
88+
compare_simd_op_with_normal_op!(simd_or, |, u8x2);
89+
compare_simd_op_with_normal_op!(simd_or, |, u16x2);
90+
compare_simd_op_with_normal_op!(simd_or, |, u32x2);
91+
compare_simd_op_with_normal_op!(simd_or, |, u64x2);
92+
}
93+
94+
#[kani::proof]
95+
fn test_simd_xor() {
96+
compare_simd_op_with_normal_op!(simd_xor, ^, i8x2);
97+
compare_simd_op_with_normal_op!(simd_xor, ^, i16x2);
98+
compare_simd_op_with_normal_op!(simd_xor, ^, i32x2);
99+
compare_simd_op_with_normal_op!(simd_xor, ^, i64x2);
100+
compare_simd_op_with_normal_op!(simd_xor, ^, u8x2);
101+
compare_simd_op_with_normal_op!(simd_xor, ^, u16x2);
102+
compare_simd_op_with_normal_op!(simd_xor, ^, u32x2);
103+
compare_simd_op_with_normal_op!(simd_xor, ^, u64x2);
104+
}

tests/kani/Intrinsics/SIMD/Operators/main_fixme.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,6 @@ extern "platform-intrinsic" {
1717
fn simd_mul<T>(x: T, y: T) -> T;
1818
fn simd_div<T>(x: T, y: T) -> T;
1919
fn simd_rem<T>(x: T, y: T) -> T;
20-
fn simd_shl<T>(x: T, y: T) -> T;
21-
fn simd_shr<T>(x: T, y: T) -> T;
22-
fn simd_and<T>(x: T, y: T) -> T;
23-
fn simd_or<T>(x: T, y: T) -> T;
24-
fn simd_xor<T>(x: T, y: T) -> T;
2520
}
2621

2722
macro_rules! assert_op {
@@ -46,10 +41,5 @@ fn main() {
4641
assert_op!(res_mul, simd_mul, y, z, 0, 2);
4742
assert_op!(res_div, simd_div, v, z, 1, 1);
4843
assert_op!(res_rem, simd_rem, v, z, 0, 1);
49-
assert_op!(res_shl, simd_shl, z, z, 2, 8);
50-
assert_op!(res_shr, simd_shr, z, y, 1, 1);
51-
assert_op!(res_and, simd_and, y, v, 0, 1);
52-
assert_op!(res_or, simd_or, x, y, 0, 1);
53-
assert_op!(res_xor, simd_xor, x, y, 0, 1);
5444
}
5545
}

0 commit comments

Comments
 (0)