-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MCP: More Cranelift-friendly portable SIMD intrinsics #381
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed. |
@rustbot second |
@rustbot label -final-comment-period +major-change-accepted |
Error: The feature Please let |
Proposal
cc @rust-lang/project-portable-simd
Summary
simd_*
intrinsics fromextern "platform-intrinsic"
will form the basis of backend-agnostic intrinsics within the standard library.simd_*
intrinsics so thatcore::simd
can avoid any direct LLVM dependency.simd_*
intrinsics that are exposed throughcompiler_builtins
.Implementation of this MCP will be coordinated between the Portable SIMD project and Compiler team for Cranelift and LLVM implementations.
Motivations
The user-facing goal of the
core::simd
API being developed by the @rust-lang/project-portable-simd group is to let users take advantage of SIMD intrinsics in a way that's automatically portable across hardware. Realizing that goal requires special backend support so thatcore::simd
can utilize existing intrinsics rather than having to target ISAs specifically. Sincerustc
has multiple compiler backends (LLVM and Cranelift) thecore::simd
implementation also needs to also be portable across compiler backends in order to be portable across hardware in the way we want.We currently have a best-effort approach to backend-agnostic SIMD intrinsics through the
extern "platform-intrinsic"
mechanism. There are a number of existing platform intrinsics likesimd_add
andsimd_mul
that are used throughoutcore::arch
, but also many ISA idiosyncrasies that aren't reasonable to create platform intrinsics for so it also uses a mix of LLVM intrinsics and inline assembly. The story forcore::simd
is a bit different. Its goal is specifically to expose standard lowest-common-denominator functionality that's consistent across all supported ISAs. That makescore::simd
a great fit for platform intrinsics, andcore::simd
would like to use them exclusively over LLVM intrinsics.We can think of
core::simd
almost like a thin user-friendly wrapper over platform intrinsics. Since it's going to rely on these intrinsics and make promises about their behavior across platforms we should write reference implementations of them all in plain Rust. These reference implementations will both document the conformant behavior of these intrinsics and give compiler backends a way to supportcore::simd
without necessarily having to generate vectorized code for all platforms.Implementation
The overall picture of how Rust's portable SIMD story will fit together covers a few areas of the compiler and libraries:
core::simd
call platform intrinsics throughextern "platform-intrinsic"
. These are generic functions that are backend agnostic. They work with types that are#[repr(simd)]
.compiler_builtins
. They're named so that backends can easily name them given the platform intrinsic and shape of the inputs. Instead of working with some generic#[repr(simd)] struct T
, they work with[T; N]
s.compiler_builtins
, they can be backed by a single generic implementation to make them easier to write.To get a better idea of how this is expected to hang together, let's consider a working example of a conceptual
core::simd
and Rust compiler.This example implements addition for
i64x4
, a vector type with 4i64
lanes:At the top level, in
core::simd
we call into generic platform intrinsics.In our compiler backend, we have one of two options; emit ISA-specific vectorized code for
simd_add
(such as a call to x86's_mm256_add_epi64
), or emit a call to the fallback implementation fromcompiler_builtins
. The#[repr(simd)]
attribute ensures we can convert to and from arrays for the fallback implementation. Given a#[repr(simd)]
struct withN
fields of typeT
we can read them into a[T; N]
and then write them from a[T; N]
back into the#[repr(simd)]
struct.We pass these fallback vectors to the intrinsic as slices instead of arrays, so that arbitrarily sized inputs can be supported.
New SIMD operations can be defined with a reference implementation in
compiler_builtins
. They can then be picked up by compiler backends automatically until they choose to generate specific code for them.There's an implicit bound on the
T
insimd_add
, which is that it somehow maps to an intrinsic likesimd_fallback_add_i64
. This isn't currently communicated in its contract, and could be masked by compiler backends that don't forward to intrinsics. We suggest compiler backends always validate an appropriate fallback exists for a given platform intrinsic and vector type, even if it doesn't plan to use it.Who defines intrinsics?
The Portable SIMD group will be responsible for determining the behavior of the
simd_*
intrinsics it needs. These will take the form of the reference/fallback implementations incompiler_builtins
.What do we need from
T-compiler
?We'll need a lot of help figuring out where to put reference implementations and how to make them available to the various backends.
Mentors or Reviewers
rustc
's Cranelift backend andextern "platform-intrinsic"
.Process
The main points of the Major Change Process is as follows:
@rustbot second
.-C flag
, then full team check-off is required.@rfcbot fcp merge
on either the MCP or the PR.You can read more about Major Change Proposals on forge.
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.
The text was updated successfully, but these errors were encountered: