Skip to content

Conversation

@tedinski
Copy link
Contributor

Description of changes:

Adds support for two new intrinsics: simd_extract and simd_insert.

Resolved issues:

Resolves #308

Call-outs:

  • I needed to add a cast_to to the simd_insert translation to avoid [main.assertion.5] line 50 Reached assignment statement with unequal types Signedbv { width: 64 } Signedbv { width: 32 }: FAILURE from CBMC.
  • Is there a better pattern for how to handle assumptions in our translation? I think typechecking will catch non-vector types getting passed to simd_insert but I did just unwrap the base type in there, and I'm not sure if there's a better way to do that that would aid debugging later.
  • I'm still figuring out what assumptions apply in the translation. I translated P = simd_insert(e, i, v) as T tmp; tmp = e; e[i] = v; P=tmp where P is our input Place. We could maybe do P=e; P[i] = v; if that's not violating any assumptions of the translation. Would get rid of a temp.
  • CBMC does seem to be emitting "array" bounds checks on the vectors, so I think we're good on soundness.

Testing:

  • How is this change tested? Added to an existing test case.

  • Is this a refactor change? No.

Checklist

  • Each commit message has a non-empty body, explaining why the change was made
  • Methods or procedures are documented
  • Regression or unit tests are included, or existing tests cover the modified code
  • My PR is restricted to a single feature or bugfix

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

Copy link
Contributor

@adpaco-aws adpaco-aws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks great but after reading #308 I would like to make sure that there is no support for these builtins in CBMC before we try to implement them ourselves. This is not easy to do, but for instance looking at this file I can tell there exists support for shuffle builtins. In that case, the right thing to do would be to:

  1. Add a constructor for vector shuffle expressions.
  2. Define how vector shuffle expressions are converted into the associated ireps.
  3. Test that the verification results are the ones that we expect.

In some cases, we may ask CBMC developers for support via ireps if there are good reasons.

As an example, you can take a look to the count intrinsics (ctlz, cttz & friends) defined there. We do not handle them ourselves but rather we let CBMC process them by emitting an irep and nothing else.

Comment on lines 40 to 53
// Indexing into the vectors
assert!(z.1 == 2);
assert!(z.0 == 1);

{
let y_0: i64 = unsafe { simd_extract(y, 0) };
let y_1: i64 = unsafe { simd_extract(y, 1) };
assert!(y_0 == 0);
assert!(y_1 == 1);
let m = unsafe { simd_insert(y, 0, 1) };
let n = unsafe { simd_insert(y, 1, 5) };
assert!(m.0 == 1 && m.1 == 1);
assert!(n.0 == 0 && n.1 == 5);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would create another folder in SIMD and put this test in there.

assert_op!(res_rem, simd_rem, v, z, 0, 1);
assert_op!(res_rem, simd_rem, v, z, 0, 1);
assert_op!(res_shr, simd_shl, z, z, 2, 8);
assert_op!(res_shl, simd_shl, z, z, 2, 8);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch!

}
"simd_ge" => codegen_intrinsic_binop!(ge),
"simd_gt" => codegen_intrinsic_binop!(gt),
"simd_insert" => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe put this code into a function? So we can keep one-liners for SIMD intrinsics. But first let's talk about what support does CBMC provide for them.

@tedinski
Copy link
Contributor Author

After entirely too much investigation, I've got this example:

#include <immintrin.h>
#include <assert.h>

int main() {
    __m256i x = {0};
    __m256i y = _mm256_insert_epi32(x, 7, 0);
    assert(y[0] == 7);
}

CBMC outputs:

**** WARNING: no body for function __builtin_ia32_vextractf128_si256
**** WARNING: no body for function __builtin_ia32_vec_set_v4si
**** WARNING: no body for function __builtin_ia32_vinsertf128_si256

Which I believe is confirmation that CBMC doesn't implement these kinds of intrinsics (inserts). This makes sense as I'm guessing the idiomatic C code is to just do the assignment (y[0] = 7) instead.

@adpaco-aws
Copy link
Contributor

Yes, your example shows that the insert/extract builtins are not implemented. But array indices seem to be working well so I am happy with this proposal. Thanks for the investigation!

@adpaco-aws adpaco-aws merged commit d47ea38 into model-checking:main-153-2021-07-15 Jul 26, 2021
@tedinski tedinski deleted the simd-intrinsics branch July 26, 2021 13:58
adpaco-aws added a commit that referenced this pull request Jul 26, 2021
* support simd_extract intrinsic

* support simd_insert intrinsic

* move insert/extract tests to their own tile

* extract codegen_intrinsic_simd_insert

Co-authored-by: Adrian Palacios <[email protected]>
adpaco-aws added a commit that referenced this pull request Aug 2, 2021
* support simd_extract intrinsic

* support simd_insert intrinsic

* move insert/extract tests to their own tile

* extract codegen_intrinsic_simd_insert

Co-authored-by: Adrian Palacios <[email protected]>
@zhassan-aws zhassan-aws mentioned this pull request Aug 6, 2021
4 tasks
adpaco-aws added a commit that referenced this pull request Aug 6, 2021
* support simd_extract intrinsic

* support simd_insert intrinsic

* move insert/extract tests to their own tile

* extract codegen_intrinsic_simd_insert

Co-authored-by: Adrian Palacios <[email protected]>
adpaco-aws added a commit that referenced this pull request Aug 17, 2021
* support simd_extract intrinsic

* support simd_insert intrinsic

* move insert/extract tests to their own tile

* extract codegen_intrinsic_simd_insert

Co-authored-by: Adrian Palacios <[email protected]>
adpaco-aws added a commit that referenced this pull request Aug 24, 2021
* support simd_extract intrinsic

* support simd_insert intrinsic

* move insert/extract tests to their own tile

* extract codegen_intrinsic_simd_insert

Co-authored-by: Adrian Palacios <[email protected]>
tedinski added a commit to tedinski/rmc that referenced this pull request Apr 26, 2022
* support simd_extract intrinsic

* support simd_insert intrinsic

* move insert/extract tests to their own tile

* extract codegen_intrinsic_simd_insert

Co-authored-by: Adrian Palacios <[email protected]>
tedinski added a commit that referenced this pull request Apr 27, 2022
* support simd_extract intrinsic

* support simd_insert intrinsic

* move insert/extract tests to their own tile

* extract codegen_intrinsic_simd_insert

Co-authored-by: Adrian Palacios <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Codegen failure: Unsupported intrinisic simd_insert

2 participants