about summary refs log tree commit diff
diff options
context:
space:
mode:
authorantoyo <antoyo@users.noreply.github.com>2022-10-09 17:24:59 -0400
committerGitHub <noreply@github.com>2022-10-09 17:24:59 -0400
commite84f9a15929d0a915664176cc0dbef43691dd172 (patch)
tree87d8839de06422933dc5ac6b6784b44b495ed5b7
parent04fd2d3c9c58124b3038ff1e575d054660d836ab (diff)
parent173db39f916a1ae33b15543cd42a88113cf3114f (diff)
downloadrust-e84f9a15929d0a915664176cc0dbef43691dd172.tar.gz
rust-e84f9a15929d0a915664176cc0dbef43691dd172.zip
Merge pull request #231 from rust-lang/fix/simd_select_bitmask
Fix/simd select bitmask
-rw-r--r--failing-ui-tests.txt1
-rw-r--r--failing-ui-tests12.txt1
-rw-r--r--src/builder.rs33
-rw-r--r--src/intrinsic/simd.rs9
4 files changed, 36 insertions, 8 deletions
diff --git a/failing-ui-tests.txt b/failing-ui-tests.txt
index 8a780e88147..5b3166113e7 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 00cd42d8e9d..32feb2c886b 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 ee9983830ff..b7342f50716 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -1597,20 +1597,42 @@ 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();
-        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);
 
+        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 +1645,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 7d789009826..fbfcebe46a1 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()));
     }