Merge pull request #230 from rust-lang/fix/simd_bitmask

Fix/simd bitmask
This commit is contained in:
antoyo 2022-10-09 12:37:42 -04:00 committed by GitHub
commit 04fd2d3c9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 20 deletions

View File

@ -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

View File

@ -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

View File

@ -1613,9 +1613,9 @@ pub fn vector_select(&mut self, cond: RValue<'gcc>, then_val: RValue<'gcc>, else
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.

View File

@ -337,28 +337,31 @@ macro_rules! arith_binary {
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))
@ -366,7 +369,7 @@ macro_rules! arith_binary {
== 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);