Repository navigation
Figure out which target features are required/incompatible for which ABI #131799
Copy link
Copy link
Open
1 / 21 of 2 issues completedOpen
1 / 21 of 2 issues completed
Copy link
Labels
A-ABIArea: Concerning the application binary interface (ABI)Area: Concerning the application binary interface (ABI)A-floating-pointArea: Floating point numbers and arithmeticArea: Floating point numbers and arithmeticA-target-featureArea: Enabling/disabling target features like AVX, Neon, etc.Area: Enabling/disabling target features like AVX, Neon, etc.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
The context for this is #116344: some target features change the way floats are passed between functions. Changing those target features is unsound as code compiled for the same target may now use different ABIs.
In #134794, I am adding the infrastructure to have the compiler recognize this. But this infrastructure needs to be fed with information about which ABIs exist (e.g. softfloat/hardfloat), and which target features they require or are incompatible with. This will have to be done for each architecture we support.
- x86 (32bit and 64bit):
soft-floatcan be set to swap the ABI; if unset, a hardfloat ABI is used- 32bit: uses float registers if
!soft-float && x87(see here). IOW, hardfloat ABI requiresx87.- except
f16uses SSE registers so that's extra fun, see x86-32 "f16" ABI needs SSE, incompatible with i586 targets #131819
- except
- 64bit: floats are passed via SSE registers, so likely
!soft-float && sseis the relevant check -- IOW, hardfloat ABI requiressse/sse2.
- arm
soft-floatcan be set to swap the ABI; if unset, a hardfloat ABI is used- uses float registers if
!soft-float && fpregs(see here), so hardfloat ABI requiresfpregs
- aarch64
- doesn't really have a notion of a softfloat ABI, but we offer a softfloat target anyway...
- uses float registers if
fp-armv8; Rust makes-neonimply-fp-armv8so we have to forbid both -- butneonis stable! See The (stable)neonaarch64 target feature is unsound: it changes the float ABI #131058
- riscv
- "RISC-V has a similar ABI split. -F/-D/-Q is your softfloat/nofloat, but it also comes with the Zfinx/Zdinx/Zqinx variants where floating-point values are carried in the regular registers and the floating-point register file is deleted. Your float-function-features would be +F,-Zfinx, +D,-Zdinx for riscv64gc-unknown-linux (linux does not permit finx). Although I don't think this is as much of a problem because the platform states that +F,+Zfinx is illegal?" (from here)
- For RISC-V targets, the float ABI can be specified by the llvm_abiname target option. As long as this happens, f/d can be enabled without changing the ABI (LLVM doesn't support q yet). Disabling target features required by the requested ABI will cause LLVM to ignore the ABI. The zfinx/zdinx features don't affect the ABI.
- Also see Some
-Ctarget-features must be restrained on RISCV #132618
- loongarch: see here
- s390x: see here and here
- wasm: add ABI check logic for wasm #157106
- powerpc: powerpc: warn against incorrect values for ABI-relevant target features #157085
- sparc64: Missing target feature ABI checks for Sparc64 #157083
- nvptx: Missing target feature ABI checks for nvptx #157532
Tier 3 only:
- bpf
- csky
- hexagon
- mips
- m68k
- sparc32
- more?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
A-ABIArea: Concerning the application binary interface (ABI)Area: Concerning the application binary interface (ABI)A-floating-pointArea: Floating point numbers and arithmeticArea: Floating point numbers and arithmeticA-target-featureArea: Enabling/disabling target features like AVX, Neon, etc.Area: Enabling/disabling target features like AVX, Neon, etc.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Activity
RalfJung commentedon Oct 16, 2024
@rust-lang/wg-llvm @bjorn3 @chorman0773 if you happen to know anything that needs to be added to the list, please let me know, or edit the issue. :) I'm mostly focusing on float ABI here; if it turns out there's a ton of architecture-specific ABI-affecting non-float features we might want to split this up into float and non-float.
[-]Figure out which target features affect ABI[/-][+]Figure out which target features affect float ABI[/+]chorman0773 commentedon Oct 16, 2024
sse should be included for x86-64 and x87 should not be. Floats on 64-bit x86 use xmm registers rather than the x87 stack.
RalfJung commentedon Oct 16, 2024
Does
-x87not also disable SSE?chorman0773 commentedon Oct 16, 2024
I would assume not, they're entirely separate instruction sets and units.
In regardless,
ssestill affects float abi on x86_64.beetrees commentedon Oct 16, 2024
x87without disabling SSE.f16will get returned (and passed on x86-64) in an integer register instead of an SSE register if thesse2feature is disabled.f128will get passed/returned in integer registers instead of an SSE register if thessefeature is disabled.f64whensse2is disabled (a similar error occurs forf32with thessefeature).llvm_abinametarget option. As long as this happens,f/dcan be enabled without changing the ABI (LLVM doesn't supportqyet). Disabling target features required by the requested ABI will cause LLVM to ignore the ABI. Thezfinx/zdinxfeatures don't affect the ABI.beetrees commentedon Oct 16, 2024
f32andf64.hard-floatfeature causes floats to be passed/returned in integer registers.vsxfeature causesf128to be passed/returned in integer registers instead of a vector register (causesf128symbols on powerpc64 give inaccurate results #125109).RalfJung commentedon Oct 17, 2024
What is the default register for f16 on x86-32? I would have expected it matches f32 and f64, i.e., it uses an x87 register for returns and gets passed on the stack for arguments? Why is SSE involved at all?
beetrees commentedon Oct 17, 2024
Oops, I meant returned (passed only applies for x86-64): you're correct that 32-bit x86 always passes arguments on the stack. I've updated my comment. On 32-bit x86, the ABI specifies that
f16gets returned inxmm0, which is what Clang and GCC do (neither Clang nor GCC support_Float16when SSE2 is disabled).RalfJung commentedon Oct 17, 2024
Oh wow that's Just Great. Probably justifies a separate issue: #131819
24 remaining items
kjetilkjeka commentedon Oct 10, 2025
That's how I understand it. But it also very much seems like something there will be put effort into not breaking in practice.
Your concerns are completely justified. A binary will end up with one exact ptx and sm version. From the target docs on nvptx
I think whats meant with "crate granularity" is really more of a "per binary" granularity
Considering that having control of sm/ptx versions is very important for the nvptx target. Do you have a more suitable way to represent these properties in mind?
bjorn3 commentedon Oct 10, 2025
This seems like something for which
-Ctarget-cpuwould make sense. Avr and amdgpu already require specifying a-Ctarget-cpuand maybe deny mixing crates compiled with different-Ctarget-cpuvalues.RalfJung commentedon Oct 10, 2025
Yeah, maybe we could use the target modifier infrastructure to reject mixing different target-cpu on targets where those are mutually exclusive. Let's move this discussion to #141468
I feel like maybe nvptx went tier 2 a bit too quickly, there are some basic aspects of this target that still need figuring out...
Rollup merge of rust-lang#157085 - RalfJung:powerpc-abi-features, r=p…
Rollup merge of rust-lang#157085 - RalfJung:powerpc-abi-features, r=p…
Unrolled build for #157085
Rollup merge of rust-lang#150732 - kulst:cpu_is_target_modifier, r=bj…
Rollup merge of rust-lang#150732 - kulst:cpu_is_target_modifier, r=bj…
Rollup merge of rust-lang#150732 - kulst:cpu_is_target_modifier, r=bj…
Unrolled build for #150732
Rollup merge of #150732 - kulst:cpu_is_target_modifier, r=bjorn3
Rollup merge of #150732 - kulst:cpu_is_target_modifier, r=bjorn3
Rollup merge of #150732 - kulst:cpu_is_target_modifier, r=bjorn3