@@ -1556,7 +1556,8 @@ impl GotocCtx<'_> {
15561556 }
15571557
15581558 /// `simd_shuffle` constructs a new vector from the elements of two input
1559- /// vectors, choosing values according to an input array of indexes.
1559+ /// vectors, choosing values according to an input array of indexes. See
1560+ /// https://doc.rust-lang.org/std/intrinsics/simd/fn.simd_shuffle.html
15601561 ///
15611562 /// We check that:
15621563 /// 1. The return type length is equal to the expected length (`n`) of the
@@ -1571,13 +1572,6 @@ impl GotocCtx<'_> {
15711572 /// TODO: Check that `indexes` contains constant values which are within the
15721573 /// expected bounds. See
15731574 /// <https://github.com/model-checking/kani/issues/1960> for more details.
1574- ///
1575- /// This code mimics CBMC's `shuffle_vector_exprt::lower()` here:
1576- /// <https://github.com/diffblue/cbmc/blob/develop/src/ansi-c/c_expr.cpp>
1577- ///
1578- /// We can't use shuffle_vector_exprt because it's not understood by the CBMC backend,
1579- /// it's immediately lowered by the C frontend.
1580- /// Issue: <https://github.com/diffblue/cbmc/issues/6297>
15811575 fn codegen_intrinsic_simd_shuffle (
15821576 & mut self ,
15831577 mut fargs : Vec < Expr > ,
@@ -1593,7 +1587,7 @@ impl GotocCtx<'_> {
15931587 // [u32; n]: translated wrapped in a struct
15941588 let indexes = fargs. remove ( 0 ) ;
15951589
1596- let ( in_type_len , vec_subtype) = self . simd_size_and_type ( rust_arg_types[ 0 ] ) ;
1590+ let ( _ , vec_subtype) = self . simd_size_and_type ( rust_arg_types[ 0 ] ) ;
15971591 let ( ret_type_len, ret_type_subtype) = self . simd_size_and_type ( rust_ret_type) ;
15981592 if ret_type_len != n {
15991593 let err_msg = format ! (
@@ -1617,24 +1611,20 @@ impl GotocCtx<'_> {
16171611 // An unsigned type here causes an invariant violation in CBMC.
16181612 // Issue: https://github.com/diffblue/cbmc/issues/6298
16191613 let st_rep = Type :: ssize_t ( ) ;
1620- let n_rep = Expr :: int_constant ( in_type_len, st_rep. clone ( ) ) ;
16211614
1622- // P = indexes.expanded_map(v -> if v < N then vec1[v] else vec2[v-N])
16231615 let elems = ( 0 ..n)
16241616 . map ( |i| {
16251617 let idx = Expr :: int_constant ( i, st_rep. clone ( ) ) ;
16261618 // Must not use `indexes.index(i)` directly, because codegen wraps arrays in struct
1627- let v = self . codegen_idx_array ( indexes. clone ( ) , idx) . cast_to ( st_rep. clone ( ) ) ;
1628- let cond = v. clone ( ) . lt ( n_rep. clone ( ) ) ;
1629- let t = vec1. clone ( ) . index ( v. clone ( ) ) ;
1630- let e = vec2. clone ( ) . index ( v. sub ( n_rep. clone ( ) ) ) ;
1631- cond. ternary ( t, e)
1619+ self . codegen_idx_array ( indexes. clone ( ) , idx) . cast_to ( st_rep. clone ( ) )
16321620 } )
16331621 . collect ( ) ;
16341622 self . tcx . dcx ( ) . abort_if_errors ( ) ;
16351623 let cbmc_ret_ty = self . codegen_ty_stable ( rust_ret_type) ;
16361624 let loc = self . codegen_span_stable ( span) ;
1637- self . codegen_expr_to_place_stable ( p, Expr :: vector_expr ( cbmc_ret_ty, elems) , loc)
1625+ let shuffle_vector = Expr :: shuffle_vector ( vec1, vec2, elems) ;
1626+ assert_eq ! ( * shuffle_vector. typ( ) , cbmc_ret_ty) ;
1627+ self . codegen_expr_to_place_stable ( p, shuffle_vector, loc)
16381628 }
16391629
16401630 /// A volatile load of a memory location:
0 commit comments