Skip to content

Commit 5bd9ce5

Browse files
Rollup merge of #77504 - Amanieu:select_simd_bitmask, r=ecstatic-morse
Support vectors with fewer than 8 elements for simd_select_bitmask Resolves the issue raised here: rust-lang/stdarch#310 (comment)
2 parents 8095317 + e41a144 commit 5bd9ce5

File tree

4 files changed

+37
-8
lines changed

4 files changed

+37
-8
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -793,14 +793,18 @@ fn generic_simd_intrinsic(
793793
require_simd!(arg_tys[1], "argument");
794794
let v_len = arg_tys[1].simd_size(tcx);
795795
require!(
796-
m_len == v_len,
796+
// Allow masks for vectors with fewer than 8 elements to be
797+
// represented with a u8 or i8.
798+
m_len == v_len || (m_len == 8 && v_len < 8),
797799
"mismatched lengths: mask length `{}` != other vector length `{}`",
798800
m_len,
799801
v_len
800802
);
801803
let i1 = bx.type_i1();
802-
let i1xn = bx.type_vector(i1, m_len);
803-
let m_i1s = bx.bitcast(args[0].immediate(), i1xn);
804+
let im = bx.type_ix(v_len);
805+
let i1xn = bx.type_vector(i1, v_len);
806+
let m_im = bx.trunc(args[0].immediate(), im);
807+
let m_i1s = bx.bitcast(m_im, i1xn);
804808
return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
805809
}
806810

src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ fn main() {
4949
simd_select(m4, 0u32, 1u32);
5050
//~^ ERROR found non-SIMD `u32`
5151

52-
simd_select_bitmask(0u8, x, x);
53-
//~^ ERROR mask length `8` != other vector length `4`
52+
simd_select_bitmask(0u16, x, x);
53+
//~^ ERROR mask length `16` != other vector length `4`
5454
//
5555
simd_select_bitmask(0u8, 1u32, 2u32);
5656
//~^ ERROR found non-SIMD `u32`

src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ error[E0511]: invalid monomorphization of `simd_select` intrinsic: expected SIMD
2222
LL | simd_select(m4, 0u32, 1u32);
2323
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
2424

25-
error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: mismatched lengths: mask length `8` != other vector length `4`
25+
error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: mismatched lengths: mask length `16` != other vector length `4`
2626
--> $DIR/simd-intrinsic-generic-select.rs:52:9
2727
|
28-
LL | simd_select_bitmask(0u8, x, x);
29-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
28+
LL | simd_select_bitmask(0u16, x, x);
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3030

3131
error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: expected SIMD argument type, found non-SIMD `u32`
3232
--> $DIR/simd-intrinsic-generic-select.rs:55:9

src/test/ui/simd/simd-intrinsic-generic-select.rs

+25
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,29 @@ fn main() {
167167
let e = u32x8(8, 9, 10, 11, 4, 5, 6, 7);
168168
assert_eq!(r, e);
169169
}
170+
171+
unsafe {
172+
let a = u32x4(0, 1, 2, 3);
173+
let b = u32x4(4, 5, 6, 7);
174+
175+
let r: u32x4 = simd_select_bitmask(0u8, a, b);
176+
let e = b;
177+
assert_eq!(r, e);
178+
179+
let r: u32x4 = simd_select_bitmask(0xfu8, a, b);
180+
let e = a;
181+
assert_eq!(r, e);
182+
183+
let r: u32x4 = simd_select_bitmask(0b0101u8, a, b);
184+
let e = u32x4(0, 5, 2, 7);
185+
assert_eq!(r, e);
186+
187+
let r: u32x4 = simd_select_bitmask(0b1010u8, a, b);
188+
let e = u32x4(4, 1, 6, 3);
189+
assert_eq!(r, e);
190+
191+
let r: u32x4 = simd_select_bitmask(0b1100u8, a, b);
192+
let e = u32x4(4, 5, 2, 3);
193+
assert_eq!(r, e);
194+
}
170195
}

0 commit comments

Comments
 (0)