forked from model-checking/kani
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add integer overflow checking for simd_div and simd_rem (model-checki…
…ng#2645) Co-authored-by: Adrian Palacios <73246657+adpaco-aws@users.noreply.github.com>
- Loading branch information
1 parent
f454193
commit 76badeb
Showing
6 changed files
with
173 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
FAILURE\ | ||
attempt to compute simd_div which would overflow | ||
UNREACHABLE\ | ||
assertion failed: quotients.0 == quotients.1 | ||
FAILURE\ | ||
attempt to compute simd_rem which would overflow | ||
UNREACHABLE\ | ||
assertion failed: remainders.0 == remainders.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
|
||
// Checks that the `simd_div` and `simd_rem` intrinsics check for integer overflows. | ||
|
||
#![feature(repr_simd, platform_intrinsics)] | ||
|
||
#[repr(simd)] | ||
#[allow(non_camel_case_types)] | ||
#[derive(Clone, Copy, PartialEq, Eq)] | ||
pub struct i32x2(i32, i32); | ||
|
||
extern "platform-intrinsic" { | ||
fn simd_div<T>(x: T, y: T) -> T; | ||
fn simd_rem<T>(x: T, y: T) -> T; | ||
} | ||
|
||
unsafe fn do_simd_div(dividends: i32x2, divisors: i32x2) -> i32x2 { | ||
simd_div(dividends, divisors) | ||
} | ||
|
||
unsafe fn do_simd_rem(dividends: i32x2, divisors: i32x2) -> i32x2 { | ||
simd_rem(dividends, divisors) | ||
} | ||
|
||
#[kani::proof] | ||
fn test_simd_div_overflow() { | ||
let dividend = i32::MIN; | ||
let dividends = i32x2(dividend, dividend); | ||
let divisor = -1; | ||
let divisors = i32x2(divisor, divisor); | ||
let quotients = unsafe { do_simd_div(dividends, divisors) }; | ||
assert_eq!(quotients.0, quotients.1); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_simd_rem_overflow() { | ||
let dividend = i32::MIN; | ||
let dividends = i32x2(dividend, dividend); | ||
let divisor = -1; | ||
let divisors = i32x2(divisor, divisor); | ||
let remainders = unsafe { do_simd_rem(dividends, divisors) }; | ||
assert_eq!(remainders.0, remainders.1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
|
||
//! Checks that the `simd_div` intrinsic returns the expected results for floating point numbers. | ||
#![feature(repr_simd, platform_intrinsics)] | ||
|
||
#[repr(simd)] | ||
#[allow(non_camel_case_types)] | ||
#[derive(Clone, Copy, PartialEq, kani::Arbitrary)] | ||
pub struct f32x2(f32, f32); | ||
|
||
impl f32x2 { | ||
fn new_with(f: impl Fn() -> f32) -> Self { | ||
f32x2(f(), f()) | ||
} | ||
|
||
fn non_simd_div(self, divisors: Self) -> Self { | ||
f32x2(self.0 / divisors.0, self.1 / divisors.1) | ||
} | ||
} | ||
|
||
extern "platform-intrinsic" { | ||
fn simd_div<T>(x: T, y: T) -> T; | ||
} | ||
|
||
#[kani::proof] | ||
fn test_simd_div() { | ||
let dividends = f32x2::new_with(|| { | ||
let multiplier = kani::any_where(|&n: &i8| n >= -5 && n <= 5); | ||
0.5 * f32::from(multiplier) | ||
}); | ||
let divisors = f32x2::new_with(|| { | ||
let multiplier = kani::any_where(|&n: &i8| n != 0 && n >= -5 && n <= 5); | ||
0.5 * f32::from(multiplier) | ||
}); | ||
let normal_results = dividends.non_simd_div(divisors); | ||
let simd_results = unsafe { simd_div(dividends, divisors) }; | ||
assert_eq!(normal_results, simd_results); | ||
} |
39 changes: 39 additions & 0 deletions
39
tests/kani/Intrinsics/SIMD/Operators/remainder_float_fixme.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
|
||
//! Checks that the `simd_rem` intrinsic returns the expected results for floating point numbers. | ||
#![feature(repr_simd, platform_intrinsics)] | ||
|
||
#[repr(simd)] | ||
#[allow(non_camel_case_types)] | ||
#[derive(Clone, Copy, PartialEq, kani::Arbitrary)] | ||
pub struct f32x2(f32, f32); | ||
|
||
impl f32x2 { | ||
fn new_with(f: impl Fn() -> f32) -> Self { | ||
f32x2(f(), f()) | ||
} | ||
|
||
fn non_simd_rem(self, divisors: Self) -> Self { | ||
f32x2(self.0 % divisors.0, self.1 % divisors.1) | ||
} | ||
} | ||
|
||
extern "platform-intrinsic" { | ||
fn simd_rem<T>(x: T, y: T) -> T; | ||
} | ||
|
||
#[kani::proof] | ||
fn test_simd_rem() { | ||
let dividends = f32x2::new_with(|| { | ||
let multiplier = kani::any_where(|&n: &i8| n >= -5 && n <= 5); | ||
0.5 * f32::from(multiplier) | ||
}); | ||
let divisors = f32x2::new_with(|| { | ||
let multiplier = kani::any_where(|&n: &i8| n != 0 && n >= -5 && n <= 5); | ||
0.5 * f32::from(multiplier) | ||
}); | ||
let normal_results = dividends.non_simd_rem(divisors); | ||
let simd_results = unsafe { simd_rem(dividends, divisors) }; | ||
assert_eq!(normal_results, simd_results); | ||
} |