Skip to content

Commit e84f9a1

Browse files
authored
Merge pull request #231 from rust-lang/fix/simd_select_bitmask
Fix/simd select bitmask
2 parents 04fd2d3 + 173db39 commit e84f9a1

File tree

4 files changed

+36
-8
lines changed

4 files changed

+36
-8
lines changed

failing-ui-tests.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ src/test/ui/sepcomp/sepcomp-statics.rs
3333
src/test/ui/simd/intrinsic/generic-arithmetic-pass.rs
3434
src/test/ui/simd/intrinsic/generic-bitmask-pass.rs
3535
src/test/ui/simd/intrinsic/generic-gather-pass.rs
36-
src/test/ui/simd/intrinsic/generic-select-pass.rs
3736
src/test/ui/simd/issue-17170.rs
3837
src/test/ui/simd/issue-39720.rs
3938
src/test/ui/simd/issue-85915-simd-ptrs.rs

failing-ui-tests12.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ src/test/ui/simd/intrinsic/generic-cast-pointer-width.rs
1616
src/test/ui/simd/intrinsic/generic-comparison-pass.rs
1717
src/test/ui/simd/intrinsic/generic-elements-pass.rs
1818
src/test/ui/simd/intrinsic/generic-reduction-pass.rs
19+
src/test/ui/simd/intrinsic/generic-select-pass.rs
1920
src/test/ui/simd/intrinsic/inlining-issue67557-ice.rs
2021
src/test/ui/simd/intrinsic/inlining-issue67557.rs
2122
src/test/ui/simd/monomorphize-shuffle-index.rs

src/builder.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,20 +1597,42 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
15971597
unimplemented!();
15981598
}
15991599

1600-
16011600
pub fn vector_select(&mut self, cond: RValue<'gcc>, then_val: RValue<'gcc>, else_val: RValue<'gcc>) -> RValue<'gcc> {
16021601
// cond is a vector of integers, not of bools.
1603-
let cond_type = cond.get_type();
1604-
let vector_type = cond_type.unqualified().dyncast_vector().expect("vector type");
1602+
let vector_type = cond.get_type().unqualified().dyncast_vector().expect("vector type");
16051603
let num_units = vector_type.get_num_units();
16061604
let element_type = vector_type.get_element_type();
1605+
1606+
#[cfg(feature="master")]
1607+
let (cond, element_type) = {
1608+
let then_val_vector_type = then_val.get_type().dyncast_vector().expect("vector type");
1609+
let then_val_element_type = then_val_vector_type.get_element_type();
1610+
let then_val_element_size = then_val_element_type.get_size();
1611+
1612+
// NOTE: the mask needs to be of the same size as the other arguments in order for the &
1613+
// operation to work.
1614+
if then_val_element_size != element_type.get_size() {
1615+
let new_element_type = self.type_ix(then_val_element_size as u64 * 8);
1616+
let new_vector_type = self.context.new_vector_type(new_element_type, num_units as u64);
1617+
let cond = self.context.convert_vector(None, cond, new_vector_type);
1618+
(cond, new_element_type)
1619+
}
1620+
else {
1621+
(cond, element_type)
1622+
}
1623+
};
1624+
1625+
let cond_type = cond.get_type();
1626+
16071627
let zeros = vec![self.context.new_rvalue_zero(element_type); num_units];
16081628
let zeros = self.context.new_rvalue_from_vector(None, cond_type, &zeros);
16091629

1630+
let result_type = then_val.get_type();
1631+
16101632
let masks = self.context.new_comparison(None, ComparisonOp::NotEquals, cond, zeros);
16111633
// NOTE: masks is a vector of integers, but the values can be vectors of floats, so use bitcast to make
16121634
// the & operation work.
1613-
let masks = self.bitcast_if_needed(masks, then_val.get_type());
1635+
let then_val = self.bitcast_if_needed(then_val, masks.get_type());
16141636
let then_vals = masks & then_val;
16151637

16161638
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> {
16231645
let else_val = self.context.new_bitcast(None, else_val, then_val.get_type());
16241646
let else_vals = inverted_masks & else_val;
16251647

1626-
then_vals | else_vals
1648+
let res = then_vals | else_vals;
1649+
self.bitcast_if_needed(res, result_type)
16271650
}
16281651
}
16291652

src/intrinsic/simd.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,19 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
9393
let arg1_vector_type = arg1_type.unqualified().dyncast_vector().expect("vector type");
9494
let arg1_element_type = arg1_vector_type.get_element_type();
9595

96+
// NOTE: since the arguments can be vectors of floats, make sure the mask is a vector of
97+
// integer.
98+
let mask_element_type = bx.type_ix(arg1_element_type.get_size() as u64 * 8);
99+
let vector_mask_type = bx.context.new_vector_type(mask_element_type, arg1_vector_type.get_num_units() as u64);
100+
96101
let mut elements = vec![];
97102
let one = bx.context.new_rvalue_one(mask.get_type());
98103
for _ in 0..len {
99-
let element = bx.context.new_cast(None, mask & one, arg1_element_type);
104+
let element = bx.context.new_cast(None, mask & one, mask_element_type);
100105
elements.push(element);
101106
mask = mask >> one;
102107
}
103-
let vector_mask = bx.context.new_rvalue_from_vector(None, arg1_type, &elements);
108+
let vector_mask = bx.context.new_rvalue_from_vector(None, vector_mask_type, &elements);
104109

105110
return Ok(bx.vector_select(vector_mask, arg1, args[2].immediate()));
106111
}

0 commit comments

Comments
 (0)