-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Figure out which target features are required for which SIMD size #131800
Comments
cc @programmerjake to confirm what features are relevant re: PowerPC |
|
|
+zve32x, +zve32f, +zve64x, +zve64f, +zve64d, +v, +zvbb, +zvkb. There several others that start with +zv*. There is an implies relationship so they all ultimately imply +zve32x. These change the ABI for fixed length vector arguments/returns in IR in the backend. When compiling with clang with the default C ABI, fixed length vectors are passed coerced to a scalar integer type or passed indirectly through memory. clang will not create fixed length vector return types or arguments in IR. There is a fixed length vector ABI being implemented via an attribute llvm/llvm-project#100346. This changes how fixed length vectors are passed. |
vsx just enables an additional 32 registers that overlap with the scalar floating point registers but are otherwise the same as the 32 128-bit registers from vmx (aka. altivec), so no new simd bitwidths. |
@programmerjake and no alterations to the calling convention? |
@topperc hm, it seems LLVM doesn't have the crypto implications for these features specified here? is it somewhere else? https://github.com/llvm/llvm-project/blob/d54953ef472bfd8d4b503aae7682aa76c49f8cc0/llvm/lib/Target/RISCV/RISCVFeatures.td#L734-L746 it seems to rather be the opposite, a requirement relationship, but perhaps I'm misunderstanding: https://github.com/llvm/llvm-project/blob/d54953ef472bfd8d4b503aae7682aa76c49f8cc0/llvm/lib/TargetParser/RISCVISAInfo.cpp#L754-L758 |
My mistake. I'm not sure why we don't have the implies. gcc does. |
enabling vsx doesn't alter the calling convention. |
Are there types which are passed via these MMA registers? |
For us it's nice that there's no "implies" here, that makes it a lot easier to check the ABI consequences. ;) This way we juts have to block the actual feature changing something, not other features implying them. Though maybe this is also unnecessary if #131807 takes care of all that. EDIT: Ah, that's just for float ABI, not for vectors, is it? |
Uh wait a second, we are exposing another flag that can change ABI? 😢 😭 EDIT: That's probably a discussion for Zulip. |
LoongArch: According to the LoongArch ABI Specs, vector type parameters and return values are passed in GAR(general-purpose argument registers) or on the stack, and do not rely on vector registers or vector features. |
after a bit more research, there are types for MMA, but you can't pass them by value in function arguments or return, so they're not ABI-breaking: https://clang.godbolt.org/z/e4sTY37Pv |
...concerning. these blockades are in clang's semantic checks, they don't seem to be enforced by LLVM. |
cc @jacobbramley re: aarch64 |
cc @androm3da re: hexagon |
How do we handle that in Rust? We'd need a special pass during collection rejecting them as arguments, likely as part of the simd arg check that this issue is about. I assume we don't support these types yet, but this will need to be considered when someone decides to add them. |
I only just realized this only affects scalable vector types. Which anyway we don't support. So we can ignore this for now. |
According to the CSKY Development Guide: 4.5 vdsp, the vector width is configured as follows: For vdspv2, the width is fixed at 128 bits. Therefore, for both versions, you can safely set the vector width to 128 bits. csky: |
…ngjubilee ABI checks: add support for tier2 arches See rust-lang#131800 for the data collection behind this change. r? RalfJung
How big are the SPARC vectors that get unlocked by the |
…ngjubilee ABI checks: add support for tier2 arches See rust-lang#131800 for the data collection behind this change. r? RalfJung
AFAIK it's at least 64-bit.
|
@veluca93's PR has a comment indicating
That doesn't mean the register is 256 bits large though, is it? It probably uses more than one register? OTOH vectors larger than a register are also odd. So I don't really understand what to do with this. |
SPARC FP registers (f[0-63]) are 32-bit long, and two/four of these are combined to process f64/f128. 64-bit VIS vectors also use two FP registers, as does f64. 128-bit/258-bit vectors are also passed or returned using four/eight FP registers. (By the way, this complication of the nature of FP registers is one of the reasons I postponed FP register support in the initial implementation of SPARC inline assembly.) |
The relevant question here is: for a vector of size N bits, which target feature must be present so that the vector is passed in a register (whereas if the feature is absent, vectors of that size are passed in a different way). Or I guess in this case, in a group of registers, or whatever these are called. |
IIUC, in that case, we need to refer to the calling conventions'.
Assuming our ABI code is correct:
However, IIUC our ABI code does not support vector types correctly, so for now we may need to treat it as vlen(0) |
You said it's 256 only for return values... not sure how that makes any sense, but something can't be right here then. It should probably be "128" for sparc64? Like, maybe in the future they define 256 bit vectors and then pass them different for arguments. Or so? |
The 256-bit vector in argument position is passed through memory, not FP registers. From calling conventions implemented by GCC:
IIUC, our ABI code should handle this correctly by calling make_indirect for vectors with size>16(argument) or size>32(return value). (If it is handled correctly, the 256-bit vector in argument position should not generate a warning anyway, since the lint trigger condition is no longer satisfied.)
GCC's VIS builtins support 32-bit and 64-bit vectors, but larger sizes of vector types are available via Here is a code generated by GCC (only 256-bit vector is moved from memory to FP reg): https://godbolt.org/z/5vEdejj6j |
In any case, LLVM doesn't currently support Vector ABI (llvm/llvm-project#45418), so it seems that using vlen(0) in the lint is correct for now. |
I guess the number we need is "for vectors of which size is this calling convention guaranteed to be the final word, and future extensions won't change how those vectors are passed". Even assuming a correct ABI implementation on our side, what is that number for SPARC32 + vis / SPARC64 + vis? Or is this somehow not a well-formed question? |
…ngjubilee ABI checks: add support for tier2 arches See rust-lang#131800 for the data collection behind this change. r? RalfJung
SPARC's Vector ABI is defined based on the existing float and aggregate calling convention, not the VIS ISA 1, and changing it without a new ABI would also break other non-vector arguments due to the nature of using FP registers. So, I don't believe it can be changed without a new ABI. (This is very different from the x86_64, which extended the ISA in the form of increasing the size of the vector registers.) That said, if our policy is to not trust the current behavior of psABI with respect to vectors larger than ISA supports 2, I think the 64-bit mentioned in #131800 (comment) is safe selection. Footnotes
|
Rollup merge of rust-lang#132842 - veluca93:abi-checks-tier2, r=workingjubilee ABI checks: add support for tier2 arches See rust-lang#131800 for the data collection behind this change. r? RalfJung
So having or not having |
Good point. Looking at the assemblies generated by GCC it does not appear to be affected by -mvis (affected by -msoft-float, though): https://godbolt.org/z/3sTMqoaq4 (As for SPARC's soft-float target feature, it should be marked as Forbidden anyway because it affects the float ABI: #131799 (comment)) |
Yeah, most targets have a |
Fun facts to know and tell: RVV also supports these! it's something called a "register group", and is modified by |
…jubilee ABI checks: add support for some tier3 arches, warn on others. Followup to - rust-lang#132842 - rust-lang#132173 - rust-lang#131800 r? `@workingjubilee`
…ngjubilee ABI checks: add support for some tier3 arches, warn on others. Followup to - rust-lang#132842 - rust-lang#132173 - rust-lang#131800 r? `@workingjubilee`
…ngjubilee ABI checks: add support for some tier3 arches, warn on others. Followup to - rust-lang#132842 - rust-lang#132173 - rust-lang#131800 r? ``@workingjubilee``
Rollup merge of rust-lang#133029 - veluca93:abi-checks-tier3, r=workingjubilee ABI checks: add support for some tier3 arches, warn on others. Followup to - rust-lang#132842 - rust-lang#132173 - rust-lang#131800 r? ``@workingjubilee``
Thank you everyone for participating, I believe we have concluded this investigation for now. There are some only-partly-resolved questions so I opened new issues for them: |
The context for this is #116558: passing vector types by-value over
extern "C"
needs certain registers to be present, so if the target feature enabling these registers is missing, then either the ABI needs to change (which can lead to soundness issues if caller and callee disagree on their target features), or LLVM just errors outright.#127731 moves us towards detecting this situation, but that approach needs data about which target feature is needed to pass which vector size. That will be different for each architecture. So this issue is about gathering all that data.
x86_amx_intrinsics
#126622 )The text was updated successfully, but these errors were encountered: