mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 09:14:20 +00:00
Fix simd_select_bitmask
This commit is contained in:
parent
04fd2d3c9c
commit
e5ce7a9846
@ -1597,7 +1597,6 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
||||
pub fn vector_select(&mut self, cond: RValue<'gcc>, then_val: RValue<'gcc>, else_val: RValue<'gcc>) -> RValue<'gcc> {
|
||||
// cond is a vector of integers, not of bools.
|
||||
let cond_type = cond.get_type();
|
||||
@ -1607,10 +1606,12 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
||||
let zeros = vec![self.context.new_rvalue_zero(element_type); num_units];
|
||||
let zeros = self.context.new_rvalue_from_vector(None, cond_type, &zeros);
|
||||
|
||||
let result_type = then_val.get_type();
|
||||
|
||||
let masks = self.context.new_comparison(None, ComparisonOp::NotEquals, cond, zeros);
|
||||
// NOTE: masks is a vector of integers, but the values can be vectors of floats, so use bitcast to make
|
||||
// the & operation work.
|
||||
let masks = self.bitcast_if_needed(masks, then_val.get_type());
|
||||
let then_val = self.bitcast_if_needed(then_val, masks.get_type());
|
||||
let then_vals = masks & then_val;
|
||||
|
||||
let minus_ones = vec![self.context.new_rvalue_from_int(element_type, -1); num_units];
|
||||
@ -1623,7 +1624,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
||||
let else_val = self.context.new_bitcast(None, else_val, then_val.get_type());
|
||||
let else_vals = inverted_masks & else_val;
|
||||
|
||||
then_vals | else_vals
|
||||
let res = then_vals | else_vals;
|
||||
self.bitcast_if_needed(res, result_type)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,14 +93,19 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
|
||||
let arg1_vector_type = arg1_type.unqualified().dyncast_vector().expect("vector type");
|
||||
let arg1_element_type = arg1_vector_type.get_element_type();
|
||||
|
||||
// NOTE: since the arguments can be vectors of floats, make sure the mask is a vector of
|
||||
// integer.
|
||||
let mask_element_type = bx.type_ix(arg1_element_type.get_size() as u64 * 8);
|
||||
let vector_mask_type = bx.context.new_vector_type(mask_element_type, arg1_vector_type.get_num_units() as u64);
|
||||
|
||||
let mut elements = vec![];
|
||||
let one = bx.context.new_rvalue_one(mask.get_type());
|
||||
for _ in 0..len {
|
||||
let element = bx.context.new_cast(None, mask & one, arg1_element_type);
|
||||
let element = bx.context.new_cast(None, mask & one, mask_element_type);
|
||||
elements.push(element);
|
||||
mask = mask >> one;
|
||||
}
|
||||
let vector_mask = bx.context.new_rvalue_from_vector(None, arg1_type, &elements);
|
||||
let vector_mask = bx.context.new_rvalue_from_vector(None, vector_mask_type, &elements);
|
||||
|
||||
return Ok(bx.vector_select(vector_mask, arg1, args[2].immediate()));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user