-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Add support for unaligned simd masked load/store #126919
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
Comments
The alignment required is only the alignment of the |
Do you have a use-case in mind? |
Oh, I see. It seems this is about rust-lang/stdarch#1594 yes? Except you have underaligned loads and stores, also! I think I'd rather see us pass the alignment as a const generic parameter if we want to go down this road, then we can pass 1 or whatever. |
Yes, this is for stdarch. There are a lot of unaligned masked load/store intrinsics, and they all resort to using inline asm. |
the aligned ones also, thus my remark about a generic alignment. (at least, I hope emitting the correct alignment would encourage LLVM to lower things correctly...) |
Even if we add a generic alignment parameter, most if not all use cases will be fully-aligned or fully-unaligned. Also, having a random |
For who? Standard library developers? I agree it doesn't have many possible values though. |
For any contributor, it may be confusing. I think stdarch code should be as clear as possible to avoid possible bugs |
The only practical values are 1, 2, 4 and 8 |
Not if you want to emit vmovaps. That puts 16, 32, and 64 on the table. And I understand that desire, but I also think that the compiler code implementing these intrinsics should be as clear as possible to avoid possible bugs. |
Oh, yeah. I misread the doc. Then it should be a const generic parameter, as it has quite a few possible values (1 for movu, 16/32/64 for mova, 1/2/4/8/16 for portable simd) |
Should we introduce a new function with an alignment const generic parameter, or should we modify the existing masked load/store functions to take an extra const generic parameter (breaking change)? |
I would prefer the latter if possible. |
It is possible to do, we just need to grep stdlib for its uses (I don't think there are any uses except for portable simd). In portable simd, we need something like |
oh, darn. |
We can also use inline consts and a normal alignment parameter, like used in |
That's an ad-hoc hack and something we'd rather not see more of. |
The alternative, using const generics, will need |
Yeah it may just currently not be possible to do this, then. Why does alignment need to be a const parameter anyway? Usually in Rust the alignment is given by the type. |
llvm needs it to be an immediate value. the alignment is for the pointer. if the pointer is 16-byte aligned and we are loading a 128-bit value, llvm can generate an aligned load, but not if it is not 16-byte aligned. in this case the element type may be |
Elsewhere in Rust people encode that with types just fine, e.g. via |
by default, these intrinsics use the alignment of the element type. and that may not be the desired alignment of the pointer. we may have a |
So should the definition of
We have |
Ah wait this is about masked access, so I guess In general Rust doesn't support having over/underaligned references. It's either "use standard alignment" or "use raw pointer". There's clearly a gap here, supporting explicit alignment annotations would be nice, but I don't think it makes sense for the SIMD types to be the part that tries to work out a solution -- this needs a language-side solution.
Until const generics get better, using inline asm seems like not the worst solution to me... |
We don't need to do much, the LLVM intrinsic already has an alignment parameter. For masked access, a reference doesn't really make sense, as the point of masked loads, instead of load-then-select is that if you don't have permission to load from the masked-out positions, it should work just fine. And a reference is always safe to dereference, in which case we can just use load-then-select |
Yeah sorry I had forgotten that this was about masked accesses.
Not much, just finish const generics? ;) You are asking for quite a lot here. Compile-time constants passed as parameters to functions are a non-trivial topic. So "don't need to do much" is not accurate I am afraid. |
Hmm, I somewhat wonder if the proper direction would be supporting more ergonomic ways to specify the alignment of types... |
Why does portable_simd even use the alignment of the element type? It is an awkward position between traditionally "aligned" (to the vector type) and "unaligned" (byte-aligned) simd load/stores. We can avoid the problem of const generics simply by modifying the existing intrinsic to use the alignment of the vector type, and adding a new intrinsic that generates byte-aligned load/stores. Or, we can add a const generic boolean |
How did this issue get resolved?
|
This is no longer needed in stdarch because we used some llvm intrinsics directly, and as this issue was opened because of stdarch I thought we don't need it anymore |
Would be good to cross-reference that change with this issue, so that in the future someone can figure out what happened. |
rust-lang/stdarch#1613 eliminated the need for this feature in strarch |
Thanks :) |
We currently have only an aligned version of
simd_masked_load
, but the underlying llvm intrinsic doesn't have any alignment requirement. So I propose to addsimd_masked_load_unaligned
andsimd_masked_store_unaligned
. These will link with the llvm intrinsic with an alignment of 8 bits (the lowest permissible in Rust)The text was updated successfully, but these errors were encountered: