about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2018-12-13 12:50:42 -0800
committerAlex Crichton <alex@alexcrichton.com>2018-12-14 11:17:24 -0800
commitceee7f34f5cfae23f8b9f43314cf81cf26150b4f (patch)
tree9996e89bca6cc36572af6c8f83059009bc453f7d
parent1897657ef09eea3d0b0afbbbd154a12fbb8fbf3f (diff)
downloadrust-ceee7f34f5cfae23f8b9f43314cf81cf26150b4f.tar.gz
rust-ceee7f34f5cfae23f8b9f43314cf81cf26150b4f.zip
rustc: Add an unstable `simd_select_bitmask` intrinsic
This is going to be required for binding a number of AVX-512 intrinsics
in the `stdsimd` repository, and this intrinsic is the same as
`simd_select` except that it takes a bitmask as the first argument
instead of a SIMD vector. This bitmask is then transmuted into a `<NN x
i8>` argument, depending on how many bits it is.

cc rust-lang-nursery/stdsimd#310
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs3
-rw-r--r--src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs6
-rw-r--r--src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr20
3 files changed, 24 insertions, 5 deletions
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 8b26ada1576..e229f8d95cd 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -1192,7 +1192,7 @@ fn generic_simd_intrinsic(
         return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
     }
 
-    // every intrinsic takes a SIMD vector as its first argument
+    // every intrinsic below takes a SIMD vector as its first argument
     require_simd!(arg_tys[0], "input");
     let in_ty = arg_tys[0];
     let in_elem = arg_tys[0].simd_type(tcx);
@@ -1296,6 +1296,7 @@ fn generic_simd_intrinsic(
     if name == "simd_select" {
         let m_elem_ty = in_elem;
         let m_len = in_len;
+        require_simd!(arg_tys[1], "argument");
         let v_len = arg_tys[1].simd_size(tcx);
         require!(m_len == v_len,
                  "mismatched lengths: mask length `{}` != other vector length `{}`",
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs
index 2a2d35e7bd9..31ec8a7dc1c 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs
@@ -54,8 +54,14 @@ fn main() {
         simd_select(z, z, z);
         //~^ ERROR mask element type is `f32`, expected `i_`
 
+        simd_select(m4, 0u32, 1u32);
+        //~^ ERROR found non-SIMD `u32`
+
         simd_select_bitmask(0u8, x, x);
         //~^ ERROR mask length `8` != other vector length `4`
+        //
+        simd_select_bitmask(0u8, 1u32, 2u32);
+        //~^ ERROR found non-SIMD `u32`
 
         simd_select_bitmask(0.0f32, x, x);
         //~^ ERROR `f32` is not an integral type
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr
index 584f3d53921..05317da2475 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr
@@ -16,24 +16,36 @@ error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element
 LL |         simd_select(z, z, z);
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: mismatched lengths: mask length `8` != other vector length `4`
+error[E0511]: invalid monomorphization of `simd_select` intrinsic: expected SIMD argument type, found non-SIMD `u32`
   --> $DIR/simd-intrinsic-generic-select.rs:57:9
    |
+LL |         simd_select(m4, 0u32, 1u32);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: mismatched lengths: mask length `8` != other vector length `4`
+  --> $DIR/simd-intrinsic-generic-select.rs:60:9
+   |
 LL |         simd_select_bitmask(0u8, x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: expected SIMD argument type, found non-SIMD `u32`
+  --> $DIR/simd-intrinsic-generic-select.rs:63:9
+   |
+LL |         simd_select_bitmask(0u8, 1u32, 2u32);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `f32` is not an integral type
-  --> $DIR/simd-intrinsic-generic-select.rs:60:9
+  --> $DIR/simd-intrinsic-generic-select.rs:66:9
    |
 LL |         simd_select_bitmask(0.0f32, x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `&str` is not an integral type
-  --> $DIR/simd-intrinsic-generic-select.rs:63:9
+  --> $DIR/simd-intrinsic-generic-select.rs:69:9
    |
 LL |         simd_select_bitmask("x", x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0511`.