-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
simd_div
and simd_rem
don't check for overflow cases
#1970
Comments
While fixing this for integers, and thanks to @celinval's review, I've realized that CBMC does checks for overflow/NaN/division by zero on floating point division but apparently not for remainder. This seems to be corroborated by the CBMC manual on page 41 here. So for example: #![feature(repr_simd, platform_intrinsics)]
#[repr(simd)]
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, PartialEq)]
pub struct f32x2(f32, f32);
extern "platform-intrinsic" {
fn simd_div<T>(x: T, y: T) -> T;
fn simd_rem<T>(x: T, y: T) -> T;
}
#[kani::proof]
fn test_simd_div() {
let dividend: f32 = kani::any::<i16>().into();
let dividends = f32x2(dividend, dividend);
let divisor: f32 = kani::any::<i16>().into();
kani::assume(divisor > 0.0 && divisor < 5.0);
let divisors = f32x2(divisor, divisor);
let _simd_result = unsafe { simd_div(dividends, divisors) };
}
#[kani::proof]
fn test_simd_rem() {
let dividend: f32 = kani::any::<i16>().into();
let dividends = f32x2(dividend, dividend);
let divisor: f32 = kani::any::<i16>().into();
kani::assume(divisor > 0.0 && divisor < 5.0);
let divisors = f32x2(divisor, divisor);
let _simd_result = unsafe { simd_rem(dividends, divisors) };
} The verification for
However,
I was able to fix the original issue and implement an integer overflow check, however it looks like I'll have to implement floating point overflow/NaN checks specifically for |
Edit: Upon further further reflection, I have no idea what to do with |
Both
simd_div
andsimd_rem
are missing an overflow check that is done for the regular division operators (i.e.,/
and%
). Consider this example:This is verification output for
test_normal
:This is the verification output for
test_simd
:There are several concerns here:
Note that Kani tweaks the output a little bit in this example. In particular, for properties with class
division-by-zero
it omits the variables, the original outputs are:In diffblue/cbmc#7367 I asked the CBMC folks about this missing check, but it turns out these checks are being generated by MIR! I don't think that the "attempt to divide by zero" property is needed here (as it's basically a duplicate of "division by zero"), but it's unclear how to insert the "attempt to divide with overflow" property for SIMD intrinsics.
The text was updated successfully, but these errors were encountered: