-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
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-float
can be set to swap the ABI; if unset, a hardfloat ABI is used- except
f16
uses SSE registers so that's extra fun, see x86-32 "f16" ABI needs SSE, incompatible with i586 targets #131819
To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.- 64bit: floats are passed via SSE registers, so likely
!soft-float && sse
is the relevant check -- IOW, hardfloat ABI requiressse
/sse2
.
To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.armsoft-float
can be set to swap the ABI; if unset, a hardfloat ABI is used
To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.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-neon
imply-fp-armv8
so we have to forbid both -- butneon
is stable! See The (stable)neon
aarch64 target feature is unsound: it changes the float ABI #131058
To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.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.
To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.loongarch: see herepowerpcs390xwasmsparcbpfcskyhexagonmipsm68kmore?To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
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.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
-Ctarget-feature
#116344RalfJung 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
-x87
not also disable SSE?chorman0773 commentedon Oct 16, 2024
I would assume not, they're entirely separate instruction sets and units.
In regardless,
sse
still affects float abi on x86_64.beetrees commentedon Oct 16, 2024
x87
without disabling SSE.f16
will get returned (and passed on x86-64) in an integer register instead of an SSE register if thesse2
feature is disabled.f128
will get passed/returned in integer registers instead of an SSE register if thesse
feature is disabled.f64
whensse2
is disabled (a similar error occurs forf32
with thesse
feature).llvm_abiname
target option. As long as this happens,f
/d
can be enabled without changing the ABI (LLVM doesn't supportq
yet). Disabling target features required by the requested ABI will cause LLVM to ignore the ABI. Thezfinx
/zdinx
features don't affect the ABI.beetrees commentedon Oct 16, 2024
f32
andf64
.hard-float
feature causes floats to be passed/returned in integer registers.vsx
feature causesf128
to be passed/returned in integer registers instead of a vector register (causesf128
symbols 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?
llvm_abiname
for RISC-V targets #13180715 remaining items
Auto merge of #129884 - RalfJung:forbidden-target-features, r=working…
Auto merge of #129884 - RalfJung:forbidden-target-features, r=working…
f16
andf128
float types #116909[-]Figure out which target features affect float ABI[/-][+]Figure out which target features are required/incompatible for which ABI[/+]RalfJung commentedon Dec 26, 2024
With #134794, the framing for this is changing: all we need now is a full list of
for all our architectures.
ketsuban commentedon Mar 3, 2025
For m68k, built-in hardware floating-point support was added with the 68040, but it was reasonably common to use a 68020 or 68030 in conjunction with a discrete Motorola FPU. As a result GCC defaults to
-msoft-float
for the 68000 and 68010 and-mhard-float
for the 68020 and above. I see no pressing reason not to follow suit.heiher commentedon Mar 17, 2025
For LoongArch targets:
RalfJung commentedon Mar 17, 2025
Okay, so as usual LoongArch works basically exactly like RISC-V, thanks.
RalfJung commentedon Mar 17, 2025
@beetrees For powerpc, I found no trace of a softlfoat target. So it seems like right now, we should just assume a hardfloat ABI and mark the
hard-float
target feature as required for that ABI? Is there some other target feature we need to be worried about, likex87
on x86, that controls access to basic FP registers? Is it a problem that this makes it impossible to build softfloat code?f128 adds extra complications, not the first time. Let's discuss that separately, I opened #138616 for this.
@taiki-e same for s390x: we could just mark
soft-float
as incompatible with the ABI. Without a dedicated softfloat target, that makes it impossible to build softfloat code for that target with Rust. Also, is there some other target feature that disables the FPU (or any other parts relevant for the ABI)?beetrees commentedon Mar 17, 2025
For PowerPC, glancing through the LLVM source code the only other feature I can spot that affects the ABI of
f32
andf64
isspe
(Signal Processing Engine): whenspe
is enabled, floats are passed in general-purpose registers.RalfJung commentedon Mar 18, 2025
So we'd have to reject enabling
spe
or disablinghard-float
on our powerpc targets, and currently there'd be no replacement.tgross35 commentedon Mar 18, 2025
For s390x in particular, I think there may be a softfloat target at some point. See llvm/llvm-project#109164 (comment), my comment below it, and the last paragraph of Ulrich's comment after that.
RalfJung commentedon Mar 18, 2025
I was about to say that having a soft-float target is mostly our decision and not clang's / LLVM, but ofc if there's not even softfloat support in libm or wherever that would go, then yeah there's not a lot we can do.^^
The question is whether we can just make
+soft-float
an error in rustc, or whether there's someone relying on it so we need to add a softfloat target of some sort first.