Skip to content

Commit

Permalink
Merge pull request rust-lang#230 from rust-lang/fix/simd_bitmask
Browse files Browse the repository at this point in the history
Fix/simd bitmask
  • Loading branch information
antoyo authored Oct 9, 2022
2 parents 44e3ea3 + f73dea7 commit 04fd2d3
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 20 deletions.
1 change: 0 additions & 1 deletion failing-ui-tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ src/test/ui/simd/issue-17170.rs
src/test/ui/simd/issue-39720.rs
src/test/ui/simd/issue-85915-simd-ptrs.rs
src/test/ui/simd/issue-89193.rs
src/test/ui/simd/simd-bitmask.rs
src/test/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs
src/test/ui/sse2.rs
src/test/ui/statics/issue-91050-1.rs
Expand Down
1 change: 1 addition & 0 deletions failing-ui-tests12.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ src/test/ui/simd/intrinsic/inlining-issue67557-ice.rs
src/test/ui/simd/intrinsic/inlining-issue67557.rs
src/test/ui/simd/monomorphize-shuffle-index.rs
src/test/ui/simd/shuffle.rs
src/test/ui/simd/simd-bitmask.rs
6 changes: 3 additions & 3 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1613,9 +1613,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
let masks = self.bitcast_if_needed(masks, then_val.get_type());
let then_vals = masks & then_val;

let ones = vec![self.context.new_rvalue_one(element_type); num_units];
let ones = self.context.new_rvalue_from_vector(None, cond_type, &ones);
let inverted_masks = masks + ones;
let minus_ones = vec![self.context.new_rvalue_from_int(element_type, -1); num_units];
let minus_ones = self.context.new_rvalue_from_vector(None, cond_type, &minus_ones);
let inverted_masks = masks ^ minus_ones;
// NOTE: sometimes, the type of else_val can be different than the type of then_val in
// libgccjit (vector of int vs vector of int32_t), but they should be the same for the AND
// operation to work.
Expand Down
35 changes: 19 additions & 16 deletions src/intrinsic/simd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,36 +337,39 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
let vector = args[0].immediate();
let vector_type = vector.get_type().dyncast_vector().expect("vector type");
let elem_type = vector_type.get_element_type();
let mut shifts = vec![];
let mut masks = vec![];
let mut mask = 1;
for i in 0..in_len {
shifts.push(bx.context.new_rvalue_from_int(elem_type, i as i32));
masks.push(bx.context.new_rvalue_from_int(elem_type, mask));
mask <<= 1;
}
masks.reverse();
let shifts = bx.context.new_rvalue_from_vector(None, vector.get_type(), &shifts);
let shifted = vector >> shifts;
let masks = bx.context.new_rvalue_from_vector(None, vector.get_type(), &masks);
let masked = shifted & masks;
let reduced = bx.vector_reduce_op(masked, BinaryOp::BitwiseOr);

let expected_int_bits = in_len.max(8);
let expected_bytes = expected_int_bits / 8 + ((expected_int_bits % 8 > 0) as u64);

// FIXME(antoyo): that's not going to work for masks bigger than 128 bits.
let result_type = bx.type_ix(expected_int_bits);
let mut result = bx.context.new_rvalue_zero(result_type);

let elem_size = elem_type.get_size() * 8;
let sign_shift = bx.context.new_rvalue_from_int(elem_type, elem_size as i32);
let one = bx.context.new_rvalue_one(elem_type);

let mut shift = 0;
for i in 0..in_len {
let elem = bx.extract_element(vector, bx.context.new_rvalue_from_int(bx.int_type, i as i32));
let shifted = elem >> sign_shift;
let masked = shifted & one;
result = result | (bx.context.new_cast(None, masked, result_type) << bx.context.new_rvalue_from_int(result_type, shift));
shift += 1;
}

match ret_ty.kind() {
ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => {
// Zero-extend iN to the bitmask type:
return Ok(bx.zext(reduced, bx.type_ix(expected_int_bits)));
return Ok(result);
}
ty::Array(elem, len)
if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
&& len.try_eval_usize(bx.tcx, ty::ParamEnv::reveal_all())
== Some(expected_bytes) =>
{
// Zero-extend iN to the array length:
let ze = bx.zext(reduced, bx.type_ix(expected_bytes * 8));
let ze = bx.zext(result, bx.type_ix(expected_bytes * 8));

// Convert the integer to a byte array
let ptr = bx.alloca(bx.type_ix(expected_bytes * 8), Align::ONE);
Expand Down

0 comments on commit 04fd2d3

Please sign in to comment.