-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
simd_shuffle intrinsic: allow argument to be passed as vector #128731
Conversation
Some changes occurred in compiler/rustc_codegen_gcc Some changes occurred to the platform-builtins intrinsics. Make sure the cc @antoyo, @GuillaumeGomez, @bjorn3, @calebzulawski, @programmerjake Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 |
This comment was marked as spam.
This comment was marked as spam.
If I understand correctly, you can skip all the code up to creating the |
The mask is required to be the same length as the output vector. There's some code in there which seems to be concerned about the input vectors, though... those will often be shorter than the output vector, there's AFAIK no hard requirement here of any particular size (except that the two inputs have the same size). |
There's also some odd casting going on... the mask has The complete lack of comments on most of the API makes it really painful to try and doing anything with this code. :/ |
I am looking for the array/vector equivalent of |
Okay I got something that builds. No idea if it makes any sense.^^ I am quite surprised that this seems to construct a while bunch of runtime computation for the shuffle index list; don't those have to be compile-time known? |
0962ef9
to
7cd4f58
Compare
Yeah, the doc is only for the original C library for now.
I don't remember for this specific case, but some operations like casts are allowed in const context. Thanks for doing this and no worries: If it breaks when we sync back to the rustc_codegen_gcc repo, we'll fix it. |
Well, it will break in rustc CI when the stdarch changes I have planned as a follow-up to this get synced back to the rustc repo... so it might be a bit messy to sort out then. Currently this is dead code as the only user of simd_shuffle with a vector index is the ui test I changed, and that doesn't get run with GCC. Ideally, the GCC backend wouldn't have its own test suite but would carry a list of files from the normal ui test suite that it should run -- that would avoid a ton of duplication of test cases... |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
7cd4f58
to
daedbd4
Compare
#128537 landed, so this is now good to go. :) |
@workingjubilee today, yes? |
@workingjubilee friendly reminder that this is still waiting for review. :) |
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.
Oh, didn't realize half of it was gcc code I didn't need to review because antoyo already had a chance to look at it, heh. Looks fine to me.
// FIXME: this is a terrible abstraction-breaking hack. | ||
// Find a way to reuse `immediate_const_vector` from `codegen_ssa` instead. |
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 guess this is preexisting...
// version of this intrinsic. | ||
let n: u64 = match args[2].layout.ty.kind() { | ||
let idx_ty = args[2].layout.ty; |
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.
"index type"?
isn't it more a "type at this index", so "this type's index"? Doesn't matter much, just curious.
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.
It's the type of the argument named idx
in the signature.
@@ -30,6 +35,17 @@ fn main() { | |||
let y: Simd<u8, 2> = simd_shuffle(a, b, I2); | |||
assert_eq!(y.0, [1, 5]); | |||
} | |||
// Test that we can also use a SIMD vector instead of a normal array for the shuffle. | |||
const I1_SIMD: Simd<u32, 4> = Simd([0, 2, 4, 6]); |
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.
Usually we avoid direct construction of Simd like this, but I suppose the fact that it occasionally emits illegal LLVMIR doesn't matter since this is const-evaluated. I suppose the other accesses and constructions here are preexisting, too, probably preceded that bug report, so not worth blocking this over since we should really try to scan the entire repo for them...
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.
Is there a soundness bug where directly constructing SIMD values can miscompile? We shouldn't work around that in code, we should get codegen fixed...
Is this tracked anywhere?
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.
@scottmcm Can you refresh my memory on what the issue was here?
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.
Direct construction, as far as I know, is fine™. Both rust-lang/stdarch#1624 and (soon) #129403 have a bunch of it.
We might ban projecting into a simd type at some point in the future, because as I recall it's awkward for codegen, which doesn't want the lanes to be places, because it wants to extract/insert them instead of addressing them.
But that's not happened at this point, and is already in enough places that a few more is no big deal. And I think it might not even apply to Rvalue::Aggregate
like seen here anyway, only to field projections.
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.
(And, come to think of it, it might not even be a problem for array-based simd, because using the array as a place forces it to memory anyway. It makes me wonder if the problem was more about just .1
on a lots-of-fields simd type.)
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.
We might ban projecting into a simd type at some point in the future, because as I recall it's awkward for codegen, which doesn't want the lanes to be places, because it wants to extract/insert them instead of addressing them.
Makes sense. However, if "awkward" leads to "generate wrong code" we should track that as an I-unsound issue somewhere.
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 don't know any current "wrong code" cases, just recall that cg_clif had to do a bunch of extra work to make it work.
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.
...turns out I should have looked harder: #137108 🙃
@@ -42,4 +58,11 @@ fn main() { | |||
Simd<u8, 16>, | |||
>(a, b); | |||
} | |||
unsafe { | |||
__shuffle_vector16_v2::< | |||
{ Simd([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) }, |
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.
Same thought as above.
extern "rust-intrinsic" { | ||
fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U; | ||
} |
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.
Hm, can't we just, like, import this from core::intrinsics now?
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.
Yeah, this test is older than that.
_ if idx_ty.is_simd() | ||
&& matches!( | ||
idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(), | ||
ty::Uint(ty::UintTy::U32) |
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 wonder if we actually need to enforce signedness? Though the 32-bitness is certainly fixed...
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.
We enforce it in the array version so I figured we should keep enforcing it in the vector version.
I'm feeling optimistic: |
…rkingjubilee simd_shuffle intrinsic: allow argument to be passed as vector See rust-lang#128738 for context. I'd like to get rid of [this hack](https://github.com/rust-lang/rust/blob/6c0b89dfac65be9a5be12f938f23098ebc36c635/compiler/rustc_codegen_ssa/src/mir/block.rs#L922-L935). rust-lang#128537 almost lets us do that since constant SIMD vectors will then be passed as immediate arguments. However, simd_shuffle for some reason actually takes an *array* as argument, not a vector, so the hack is still required to ensure that the array becomes an immediate (which then later stages of codegen convert into a vector, as that's what LLVM needs). This PR prepares simd_shuffle to also support a vector as the `idx` argument. Once this lands, stdarch can hopefully be updated to pass `idx` as a vector, and then support for arrays can be removed, which finally lets us get rid of that hack.
…kingjubilee Rollup of 9 pull requests Successful merges: - rust-lang#126985 (Implement `-Z embed-source` (DWARFv5 source code embedding extension)) - rust-lang#127922 (Add unsafe to extern blocks in style guide) - rust-lang#128731 (simd_shuffle intrinsic: allow argument to be passed as vector) - rust-lang#128935 (More work on `zstd` compression) - rust-lang#128942 (miri weak memory emulation: put previous value into initial store buffer) - rust-lang#129418 (rustc: Simplify getting sysroot library directory) - rust-lang#129490 (Add Trusty OS as tier 3 target) - rust-lang#129559 (float types: document NaN bit pattern guarantees) - rust-lang#129642 (Bump backtrace to rust-lang/backtrace@fc37b22) r? `@ghost` `@rustbot` modify labels: rollup
Rollup of 9 pull requests Successful merges: - rust-lang#126985 (Implement `-Z embed-source` (DWARFv5 source code embedding extension)) - rust-lang#127922 (Add unsafe to extern blocks in style guide) - rust-lang#128731 (simd_shuffle intrinsic: allow argument to be passed as vector) - rust-lang#128935 (More work on `zstd` compression) - rust-lang#128942 (miri weak memory emulation: put previous value into initial store buffer) - rust-lang#129418 (rustc: Simplify getting sysroot library directory) - rust-lang#129490 (Add Trusty OS as tier 3 target) - rust-lang#129536 (Add `f16` and `f128` inline ASM support for `aarch64`) - rust-lang#129559 (float types: document NaN bit pattern guarantees) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#128731 - RalfJung:simd-shuffle-vector, r=workingjubilee simd_shuffle intrinsic: allow argument to be passed as vector See rust-lang#128738 for context. I'd like to get rid of [this hack](https://github.com/rust-lang/rust/blob/6c0b89dfac65be9a5be12f938f23098ebc36c635/compiler/rustc_codegen_ssa/src/mir/block.rs#L922-L935). rust-lang#128537 almost lets us do that since constant SIMD vectors will then be passed as immediate arguments. However, simd_shuffle for some reason actually takes an *array* as argument, not a vector, so the hack is still required to ensure that the array becomes an immediate (which then later stages of codegen convert into a vector, as that's what LLVM needs). This PR prepares simd_shuffle to also support a vector as the `idx` argument. Once this lands, stdarch can hopefully be updated to pass `idx` as a vector, and then support for arrays can be removed, which finally lets us get rid of that hack.
…rkingjubilee simd_shuffle intrinsic: allow argument to be passed as vector See rust-lang#128738 for context. I'd like to get rid of [this hack](https://github.com/rust-lang/rust/blob/6c0b89dfac65be9a5be12f938f23098ebc36c635/compiler/rustc_codegen_ssa/src/mir/block.rs#L922-L935). rust-lang#128537 almost lets us do that since constant SIMD vectors will then be passed as immediate arguments. However, simd_shuffle for some reason actually takes an *array* as argument, not a vector, so the hack is still required to ensure that the array becomes an immediate (which then later stages of codegen convert into a vector, as that's what LLVM needs). This PR prepares simd_shuffle to also support a vector as the `idx` argument. Once this lands, stdarch can hopefully be updated to pass `idx` as a vector, and then support for arrays can be removed, which finally lets us get rid of that hack.
…rkingjubilee simd_shuffle intrinsic: allow argument to be passed as vector See rust-lang#128738 for context. I'd like to get rid of [this hack](https://github.com/rust-lang/rust/blob/6c0b89dfac65be9a5be12f938f23098ebc36c635/compiler/rustc_codegen_ssa/src/mir/block.rs#L922-L935). rust-lang#128537 almost lets us do that since constant SIMD vectors will then be passed as immediate arguments. However, simd_shuffle for some reason actually takes an *array* as argument, not a vector, so the hack is still required to ensure that the array becomes an immediate (which then later stages of codegen convert into a vector, as that's what LLVM needs). This PR prepares simd_shuffle to also support a vector as the `idx` argument. Once this lands, stdarch can hopefully be updated to pass `idx` as a vector, and then support for arrays can be removed, which finally lets us get rid of that hack.
See #128738 for context.
I'd like to get rid of this hack. #128537 almost lets us do that since constant SIMD vectors will then be passed as immediate arguments. However, simd_shuffle for some reason actually takes an array as argument, not a vector, so the hack is still required to ensure that the array becomes an immediate (which then later stages of codegen convert into a vector, as that's what LLVM needs).
This PR prepares simd_shuffle to also support a vector as the
idx
argument. Once this lands, stdarch can hopefully be updated to passidx
as a vector, and then support for arrays can be removed, which finally lets us get rid of that hack.