Skip to content
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

Merged
merged 2 commits into from
Aug 27, 2024

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented Aug 6, 2024

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 pass idx as a vector, and then support for arrays can be removed, which finally lets us get rid of that hack.

@rustbot
Copy link
Collaborator

rustbot commented Aug 6, 2024

r? @BoxyUwU

rustbot has assigned @BoxyUwU.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 6, 2024
@rustbot
Copy link
Collaborator

rustbot commented Aug 6, 2024

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

Some changes occurred to the platform-builtins intrinsics. Make sure the
LLVM backend as well as portable-simd gets adapted for the changes.

cc @antoyo, @GuillaumeGomez, @bjorn3, @calebzulawski, @programmerjake

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

@MelvinShwuaner

This comment was marked as spam.

@RalfJung
Copy link
Member Author

RalfJung commented Aug 6, 2024

@antoyo the code here will need to be changed to work when mask is a struct or a vector. How could that be done?

@antoyo
Copy link
Contributor

antoyo commented Aug 6, 2024

@antoyo the code here will need to be changed to work when mask is a struct or a vector. How could that be done?

If I understand correctly, you can skip all the code up to creating the mask vector if the argument is a vector already.
Unless you also need to adjust the size if different sizes are supported, where you will need to adjust the part pushing the missing elements.

@RalfJung
Copy link
Member Author

RalfJung commented Aug 6, 2024

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).

@RalfJung
Copy link
Member Author

RalfJung commented Aug 6, 2024

There's also some odd casting going on... the mask has u32 elements but apparently that's not what GCC wants.

The complete lack of comments on most of the API makes it really painful to try and doing anything with this code. :/

@RalfJung
Copy link
Member Author

RalfJung commented Aug 6, 2024

I am looking for the array/vector equivalent of access_field, what does that look like? "Give me the n-th element of the vector (that I have as an RValue)"?

@RalfJung
Copy link
Member Author

RalfJung commented Aug 6, 2024

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?

@RalfJung RalfJung force-pushed the simd-shuffle-vector branch from 0962ef9 to 7cd4f58 Compare August 6, 2024 15:12
@antoyo
Copy link
Contributor

antoyo commented Aug 6, 2024

There's also some odd casting going on... the mask has u32 elements but apparently that's not what GCC wants.

The complete lack of comments on most of the API makes it really painful to try and doing anything with this code. :/

Yeah, the doc is only for the original C library for now.

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?

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.

@RalfJung
Copy link
Member Author

RalfJung commented Aug 6, 2024

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...

@antoyo

This comment was marked as off-topic.

@RalfJung

This comment was marked as off-topic.

@antoyo

This comment was marked as off-topic.

@BoxyUwU
Copy link
Member

BoxyUwU commented Aug 8, 2024

r? @workingjubilee

@rustbot rustbot assigned workingjubilee and unassigned BoxyUwU Aug 8, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
@RalfJung RalfJung force-pushed the simd-shuffle-vector branch from 7cd4f58 to daedbd4 Compare August 13, 2024 05:51
@RalfJung
Copy link
Member Author

#128537 landed, so this is now good to go. :)

@workingjubilee
Copy link
Member

@workingjubilee today, yes?

@RalfJung
Copy link
Member Author

@workingjubilee friendly reminder that this is still waiting for review. :)

Copy link
Member

@workingjubilee workingjubilee left a 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.

Comment on lines +224 to +225
// FIXME: this is a terrible abstraction-breaking hack.
// Find a way to reuse `immediate_const_vector` from `codegen_ssa` instead.
Copy link
Member

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;
Copy link
Member

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.

Copy link
Member Author

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]);
Copy link
Member

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...

Copy link
Member Author

@RalfJung RalfJung Aug 27, 2024

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?

Copy link
Member

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?

Copy link
Member

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.

Copy link
Member

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.)

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member

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]) },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thought as above.

Comment on lines 11 to 13
extern "rust-intrinsic" {
fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
}
Copy link
Member

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?

Copy link
Member Author

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)
Copy link
Member

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...

Copy link
Member Author

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.

@workingjubilee
Copy link
Member

I'm feeling optimistic:
@bors r+ rollup

@bors
Copy link
Contributor

bors commented Aug 27, 2024

📌 Commit daedbd4 has been approved by workingjubilee

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 27, 2024
workingjubilee added a commit to workingjubilee/rustc that referenced this pull request Aug 27, 2024

Verified

This commit was signed with the committer’s verified signature.
…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.
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 27, 2024
…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
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 27, 2024

Verified

This commit was signed with the committer’s verified signature.
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
@bors bors merged commit d2ff033 into rust-lang:master Aug 27, 2024
12 checks passed
@rustbot rustbot added this to the 1.82.0 milestone Aug 27, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Aug 27, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
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.
@RalfJung RalfJung deleted the simd-shuffle-vector branch August 28, 2024 05:40
bjorn3 pushed a commit to bjorn3/rust that referenced this pull request Sep 22, 2024

Verified

This commit was signed with the committer’s verified signature.
…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.
antoyo pushed a commit to antoyo/rust that referenced this pull request Jan 13, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants