From e5ce7a9846ee9479549d153101351f917f858f02 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sun, 9 Oct 2022 14:05:44 -0400 Subject: [PATCH 1/2] Fix simd_select_bitmask --- src/builder.rs | 8 +++++--- src/intrinsic/simd.rs | 9 +++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index ee9983830ff8a..adcd6235b7096 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -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) } } diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 7d78900982656..fbfcebe46a13e 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -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())); } From 173db39f916a1ae33b15543cd42a88113cf3114f Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sun, 9 Oct 2022 14:15:45 -0400 Subject: [PATCH 2/2] Fix simd_select --- failing-ui-tests.txt | 1 - failing-ui-tests12.txt | 1 + src/builder.rs | 25 +++++++++++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/failing-ui-tests.txt b/failing-ui-tests.txt index 8a780e8814780..5b3166113e77f 100644 --- a/failing-ui-tests.txt +++ b/failing-ui-tests.txt @@ -33,7 +33,6 @@ src/test/ui/sepcomp/sepcomp-statics.rs src/test/ui/simd/intrinsic/generic-arithmetic-pass.rs src/test/ui/simd/intrinsic/generic-bitmask-pass.rs src/test/ui/simd/intrinsic/generic-gather-pass.rs -src/test/ui/simd/intrinsic/generic-select-pass.rs src/test/ui/simd/issue-17170.rs src/test/ui/simd/issue-39720.rs src/test/ui/simd/issue-85915-simd-ptrs.rs diff --git a/failing-ui-tests12.txt b/failing-ui-tests12.txt index 00cd42d8e9dc0..32feb2c886b2c 100644 --- a/failing-ui-tests12.txt +++ b/failing-ui-tests12.txt @@ -16,6 +16,7 @@ src/test/ui/simd/intrinsic/generic-cast-pointer-width.rs src/test/ui/simd/intrinsic/generic-comparison-pass.rs src/test/ui/simd/intrinsic/generic-elements-pass.rs src/test/ui/simd/intrinsic/generic-reduction-pass.rs +src/test/ui/simd/intrinsic/generic-select-pass.rs 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 diff --git a/src/builder.rs b/src/builder.rs index adcd6235b7096..b7342f507168c 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1599,10 +1599,31 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { 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(); - let vector_type = cond_type.unqualified().dyncast_vector().expect("vector type"); + let vector_type = cond.get_type().unqualified().dyncast_vector().expect("vector type"); let num_units = vector_type.get_num_units(); let element_type = vector_type.get_element_type(); + + #[cfg(feature="master")] + let (cond, element_type) = { + let then_val_vector_type = then_val.get_type().dyncast_vector().expect("vector type"); + let then_val_element_type = then_val_vector_type.get_element_type(); + let then_val_element_size = then_val_element_type.get_size(); + + // NOTE: the mask needs to be of the same size as the other arguments in order for the & + // operation to work. + if then_val_element_size != element_type.get_size() { + let new_element_type = self.type_ix(then_val_element_size as u64 * 8); + let new_vector_type = self.context.new_vector_type(new_element_type, num_units as u64); + let cond = self.context.convert_vector(None, cond, new_vector_type); + (cond, new_element_type) + } + else { + (cond, element_type) + } + }; + + let cond_type = cond.get_type(); + let zeros = vec![self.context.new_rvalue_zero(element_type); num_units]; let zeros = self.context.new_rvalue_from_vector(None, cond_type, &zeros);