-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
add intrinsics for portable packed simd vector reductions #48983
Conversation
I've basically no idea of what I am doing here so please review this thoroughly. |
Thanks! @gnzlbg mind explaining for me how this differs from the codegen that stdsimd does today? |
src/rustllvm/RustWrapper.cpp
Outdated
// Vector reductions: | ||
extern "C" LLVMValueRef | ||
LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) { | ||
return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think CI may be failing on these in the sense that they're not defined on LLVM 3.9, but it's fine to have some #ifdef
here to only compile these in on 6.0+ and otherwise return errors on older versions
So the main difference is that currently Also, for vectors of bools, it is pretty important that the intrinsics get called on I'd say that we should document these on Semantically, this PR (and the stdsimd one) change the behavior of the reductions with respect to float vectors:
Since this behavior wasn't documented on Whether these semantics are the right call, I don't know. We should explore the alternatives in I could change this PR to expose |
Oh no worries I was mainly just curious! The boolean |
LLVM vector reduction intrinsics are new in LLVM 5 (r302514 to be specific), so they are not present in LLVM 3.9. That's the cause of Travis failure. |
I tried this but did not work out because the intrinsics need to be passed I am cleaning the PR a bit to actually expose the different combinations of the intrinsics so that we can experiment in @sanxiyn thanks, yes, I'll add a commit that |
src/rustllvm/RustWrapper.cpp
Outdated
} | ||
extern "C" LLVMValueRef | ||
LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { | ||
return Src; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is going to lead to broken IR (you'll wind up with vectors where scalars are expected). To truly support earlier LLVM versions, you'll need a polyfill that does the reduction "by hand".
@rkruppe I just want to check if this is enough to make the build pass. If
that’s the case, I will add a call to std::terminate() here, and a print
statement saying that to compile code that uses these one needs llvm 6 or
newer.
Or should I definitely add support for LLVM 3.9 here?
…On Wed 14. Mar 2018 at 22:25, Robin Kruppe ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/rustllvm/RustWrapper.cpp
<#48983 (comment)>:
> @@ -1442,4 +1442,51 @@ extern "C" LLVMValueRef
LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN));
}
+
+#else
+
+extern "C" LLVMValueRef
+LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) {
+ return Src;
+}
+extern "C" LLVMValueRef
+LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) {
+ return Src;
This is going to lead to broken IR (you'll wind up with vectors where
scalars are expected). To truly support earlier LLVM versions, you'll need
a polyfill that does the reduction "by hand".
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#48983 (review)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AA3NpsikylRaOlP8bMGmjopNn4bHJHRiks5teYrZgaJpZM4So8Xi>
.
|
I don't know why you didn't put the |
Well, come to think of it, breaking the builds of people using these intrinsics seems bad. The current limitations around older LLVM versions that I know of keep things working with degraded quality (e.g., I think |
Recently the bitreverse intrinsic was added to rustc and it is not
supported by older LLVM versions. How was this solved? Also, we use a lot
of link llvm intrinsics in stdsimd, some of which are only available in
LLVM 5. I don’t think any of that would compile if LLVM3.9 were used :/
|
Or in other words, should rustc compile/link against an older LLVM or
should it also work correctly?
|
Yes for functionality like this it needs to work in terms of linking and the compiler runs correctly on older LLVM versions (like 3.9). The feature itself, though, normally crashes and burns rustc if used. This means if these SIMD intrinsics are used on LLVM 3.9 then rustc would crash and burn. That's fine for now, and we can probably fix it later by having a |
Adding |
What's the use case for supporting LLVM older than the one included in the official builds? For the Linux distro scenario, I understand the use case of compiling with upstream LLVM without Rust-specific LLVM patches, but making it easy for distros to upgrade rustc without upgrading LLVM seems like a way to end up with a defective rustc that makes Rust look bad if e.g. SIMD code compiles but performs badly. |
Do not merge yet - I still need to add some fail tests and check for misuses. This is my largest rustc PR to date so I'd still like as much feedback as possible. |
src/rustllvm/RustWrapper.cpp
Outdated
|
||
#else | ||
|
||
void error_and_exit(const char* msg) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another possible option (if you're willing to do this) would be to return nullptr
and then bug!
in rustc (to get a proper ICE message)
📌 Commit 19b81f6 has been approved by |
@bors r-
|
@kennytm fixed |
@bors r=alexcrichton |
📌 Commit f173a4c has been approved by |
@bors r- So this PR failed in It seems Let's |
@kennytm I've added |
@bors r=alexcrichton |
📌 Commit 06148cb has been approved by |
add intrinsics for portable packed simd vector reductions Adds the following portable vector reduction intrinsics: * fn simd_reduce_add<T, U>(x: T) -> U; * fn simd_reduce_mul<T, U>(x: T) -> U; * fn simd_reduce_min<T, U>(x: T) -> U; * fn simd_reduce_max<T, U>(x: T) -> U; * fn simd_reduce_and<T, U>(x: T) -> U; * fn simd_reduce_or<T, U>(x: T) -> U; * fn simd_reduce_xor<T, U>(x: T) -> U; I've also added: * fn simd_reduce_all<T>(x: T) -> bool; * fn simd_reduce_any<T>(x: T) -> bool; These produce better code that what we are currently producing in `stdsimd`, but the code is still not optimal due to this LLVM bug: https://bugs.llvm.org/show_bug.cgi?id=36702 r? @alexcrichton
Adds the following portable vector reduction intrinsics:
I've also added:
These produce better code that what we are currently producing in
stdsimd
, but the code is still not optimal due to this LLVM bug: https://bugs.llvm.org/show_bug.cgi?id=36702r? @alexcrichton