about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-04-16 07:12:45 +0200
committerGitHub <noreply@github.com>2022-04-16 07:12:45 +0200
commitea131bca17144d01434cc5ec5d12cb03bc69dbcb (patch)
tree8fd0fa3a57a8e0b9593c62d8abfe338ce76d5c10 /compiler
parent946d76ec0e3d965bf9a8d3524434abf27db7ecd6 (diff)
parent73f9571d4f45fb56a2076d2c43d21ff618c396d2 (diff)
downloadrust-ea131bca17144d01434cc5ec5d12cb03bc69dbcb.tar.gz
rust-ea131bca17144d01434cc5ec5d12cb03bc69dbcb.zip
Rollup merge of #95961 - RalfJung:gather-scatter, r=workingjubilee
implement SIMD gather/scatter via vector getelementptr

Fixes https://github.com/rust-lang/portable-simd/issues/271

However, I don't *really* know what I am doing here... Cc ``@workingjubilee`` ``@calebzulawski``

I didn't do anything for cranelift -- ``@bjorn3`` not sure if it's okay for that backend to temporarily break. I'm happy to cherry-pick a patch that adds cranelift support. :)
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs21
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_typeck/src/check/intrinsic.rs1
3 files changed, 23 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 48840c76cac..cf9cf1b70aa 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -1839,6 +1839,27 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
         simd_neg: Int => neg, Float => fneg;
     }
 
+    if name == sym::simd_arith_offset {
+        // This also checks that the first operand is a ptr type.
+        let pointee = in_elem.builtin_deref(true).unwrap_or_else(|| {
+            span_bug!(span, "must be called with a vector of pointer types as first argument")
+        });
+        let layout = bx.layout_of(pointee.ty);
+        let ptrs = args[0].immediate();
+        // The second argument must be a ptr-sized integer.
+        // (We don't care about the signedness, this is wrapping anyway.)
+        let (_offsets_len, offsets_elem) = arg_tys[1].simd_size_and_type(bx.tcx());
+        if !matches!(offsets_elem.kind(), ty::Int(ty::IntTy::Isize) | ty::Uint(ty::UintTy::Usize)) {
+            span_bug!(
+                span,
+                "must be called with a vector of pointer-sized integers as second argument"
+            );
+        }
+        let offsets = args[1].immediate();
+
+        return Ok(bx.gep(bx.backend_type(layout), ptrs, &[offsets]));
+    }
+
     if name == sym::simd_saturating_add || name == sym::simd_saturating_sub {
         let lhs = args[0].immediate();
         let rhs = args[1].immediate();
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index f6acb3c76fe..d9bada29589 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1247,6 +1247,7 @@ symbols! {
         simd,
         simd_add,
         simd_and,
+        simd_arith_offset,
         simd_as,
         simd_bitmask,
         simd_cast,
diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs
index 78e77580679..0dd8ee88ca2 100644
--- a/compiler/rustc_typeck/src/check/intrinsic.rs
+++ b/compiler/rustc_typeck/src/check/intrinsic.rs
@@ -437,6 +437,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
         | sym::simd_fpow
         | sym::simd_saturating_add
         | sym::simd_saturating_sub => (1, vec![param(0), param(0)], param(0)),
+        sym::simd_arith_offset => (2, vec![param(0), param(1)], param(0)),
         sym::simd_neg
         | sym::simd_fsqrt
         | sym::simd_fsin