Merge pull request #230 from rust-lang/fix/simd_bitmask
Fix/simd bitmask
This commit is contained in:
commit
04fd2d3c9c
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user