-
Notifications
You must be signed in to change notification settings - Fork 98
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
Add integer overflow checking for simd_div and simd_rem #2645
Conversation
In `codegen_simd_op_with_overflow`, place the check before the result in the returned `Stmt`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this! Can you please add a test for float vector too? I'm worried that this could trigger similar failure to #2631.
- Now overflow is checked for signed integers and everything else is passed through. - Updated docstring to clarify what is checked.
While writing a test to confirm that everything works as expected with float vectors, I found I can assert that Details
#![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_rem<T>(x: T, y: T) -> T;
}
#[kani::proof]
fn test_simd_rem() {
let dividend: f32 = kani::any::<i8>().into();
let divisor: f32 = kani::any::<i8>().into();
kani::assume(divisor != 0.0 && divisor.abs() < 5.0);
let normal_result = dividend % divisor;
let dividends = f32x2(dividend, dividend);
let divisors = f32x2(divisor, divisor);
let simd_result = unsafe { simd_rem(dividends, divisors) };
assert_eq!(normal_result, simd_result.0);
} This produces:
Also, as I started talking about here, I'm a bit lost with Regardless, this PR should still be useful even if nothing else was changed about the handling for |
Hi @reisnera, is this ready for review? |
Hi @reisnera , thanks for your work on these intrinsics! When checking if two floating point numbers are the same, we often allow a small amount (usually called "epsilon") to account for precision errors. For example, we use this fn fp_equals(value: f32, expected: f32) -> bool {
let abs_diff = (value - expected).abs();
abs_diff <= f32::EPSILON
} Can you try that for the floating point tests? I can point you to specific tests that make use of it if you can't find them. You may also need to add assumptions that use the Regarding the missing checks, we could ask CBMC if they're interested in adding them first. That way, both tools could benefit from the check. What do you think? |
Hi @adpaco-aws, thanks! I've enjoyed working on these! For I can see where some tests use the fp_equals function and I'm aware of the difficulties with equality comparison of floats, but in the case of the
I agree that this would be great if they could! |
You're right in that we should directly be checking equality in this case. It just occurred to me that maybe both results end up being Can you please check if that's the case? With something like this:
|
@adpaco-aws So I tried your suggestion, and no luck. However this prompted me to investigate further and interestingly the problem might just be with |
The issue you found means that you'll get nondeterministic values as a result of the But I don't that should be blocking this PR: we can put the cases which are currently failing into a |
As I mentioned in #2669, I believe this is a Kani bug (hence the "ignored warning"). We might need to model floating point remainder operation on our side. I do agree that this shouldn't block this PR, since the issue is consistent for SIMD and non-SIMD (i.e.: this PR is not introducing any bad behavior). @reisnera can you please add a fixme test to our suite either as part of this PR or a separate PR that reproduces the issue you created and also add a similar harness to the one you added to the division that checks that simd produces the same value as the non-simd one. |
@celinval and @adpaco-aws, I responded to the review above but FYI I'll also need some time to finish this up as I'll be working my usual job through the weekend into next week :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @reisnera ! With this contribution and #1963, I think we can update the documentation for platform intrinsic support. Would you mind doing that?
@adpaco-aws Absolutely! I'm actually not sure if I should leave something in the notes column for |
Hey @reisnera , sorry for not getting back to you earlier. If I'm not mistaken, we still need to open an issue in the CBMC repo to ask about the missing checks. We can note there's missing support for the operation with floating-point operand, and also the missing checks that should be coming from CBMC. |
@adpaco-aws I updated the docs. According to the comment here, it seems this is already doable on CBMC end unless I'm missing something. I'll work on a pull request for that issue separately. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @reisnera !
…ng#2645) Co-authored-by: Adrian Palacios <73246657+adpaco-aws@users.noreply.github.com>
Description of changes:
As described in #1970, the simd_div and simd_rem intrinsics lack overflow checking. This PR implements them. It also makes a minor (somewhat) related change of moving the check to before the expression in the returned
Stmt
ofcodegen_simd_op_with_overflow
.Resolved issues:
Resolves #1970
Related RFC:
n/a
Call-outs:
Testing:
How is this change tested?
Added new test to ensure that attempted overflow div or rem fails the check.
Is this a refactor change?
No
Checklist
(Except for the minor change in
codegen_simd_op_with_overflow
)By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.