-
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
x86-32 "f16" ABI needs SSE, incompatible with i586 targets #131819
Comments
I think this will require LLVM changes to properly fix, as A similar issue can occur on PowerPC targets with |
Oh lol so LLVM inserts calls to builtins that use the wrong ABI? Yeah that sounds like an LLVM bug. Could you file an issue there? You probably are better at explaining the problem in their terms. :) |
I have been thinking that is would probably be in our advantage to just submit MRs against the ABIs whenever there are ambiguities like this. LLVM seems to usually pass |
Silently falling back to a different register is a bad idea. It means we get subtly different ABI in ways people don't expect - we already have soundness issues due to that, let's not add more cases like this. ABI choices need to be explicit.
|
What would be the silent part? I was mostly suggesting that the ABIs should specify a concrete calling convention for primitives when their usual cc is feature-dependent (either via other registers or indirect). Which doesn't help us with the "target features change ABI" issue, but does help us with the "is our |
The silent part is where using For "Rust" we can just define our own ABI in a consistent way -- we already special case f32/f64 returning on x86-32, we should just extend the logic here to the remaining float types. For non-"Rust" ABI however, we have two options:
@beetrees btw you said this is about |
I've filed an LLVM issue at llvm/llvm-project#112885.
AFAIK it should be, but LLVM currently switches to returning in |
I guess there is an alternative to this, which is to say that on x86 targets without SSE, f16 uses a different ABI for returns. Not sure if there is an official standard ABI for this, but LLVM implements some de-facto ABI. Then we have to reject ever enabling SSE on that target (including on a per-function level via |
…bilee x86-32 float return for 'Rust' ABI: treat all float types consistently This helps with rust-lang#131819: for our own ABI on x86-32, we want to *never* use the float registers. The previous logic only considered F32 and F64, but skipped F16 and F128. So I made the logic just apply to all float types.
…bilee x86-32 float return for 'Rust' ABI: treat all float types consistently This helps with rust-lang#131819: for our own ABI on x86-32, we want to *never* use the float registers. The previous logic only considered F32 and F64, but skipped F16 and F128. So I made the logic just apply to all float types.
…bilee x86-32 float return for 'Rust' ABI: treat all float types consistently This helps with rust-lang#131819: for our own ABI on x86-32, we want to *never* use the float registers. The previous logic only considered F32 and F64, but skipped F16 and F128. So I made the logic just apply to all float types.
That seems to match what C does: https://godbolt.org/z/GYETdPaEe |
x86-32 float return for 'Rust' ABI: treat all float types consistently This helps with rust-lang#131819: for our own ABI on x86-32, we want to *never* use the float registers. The previous logic only considered F32 and F64, but skipped F16 and F128. So I made the logic just apply to all float types.
x86-32 float return for 'Rust' ABI: treat all float types consistently This helps with rust-lang#131819: for our own ABI on x86-32, we want to *never* use the float registers. The previous logic only considered F32 and F64, but skipped F16 and F128. So I made the logic just apply to all float types. try-job: i686-gnu try-job: i686-gnu-nopt
x86-32 float return for 'Rust' ABI: treat all float types consistently This helps with rust-lang#131819: for our own ABI on x86-32, we want to *never* use the float registers. The previous logic only considered F32 and F64, but skipped F16 and F128. So I made the logic just apply to all float types. try-job: i686-gnu try-job: i686-gnu-nopt
x86-32 float return for 'Rust' ABI: treat all float types consistently This helps with rust-lang#131819: for our own ABI on x86-32, we want to *never* use the float registers. The previous logic only considered F32 and F64, but skipped F16 and F128. So I made the logic just apply to all float types. try-job: i686-gnu try-job: i686-gnu-nopt
x86-32 float return for 'Rust' ABI: treat all float types consistently This helps with rust-lang#131819: for our own ABI on x86-32, we want to *never* use the float registers. The previous logic only considered F32 and F64, but skipped F16 and F128. So I made the logic just apply to all float types. try-job: i686-gnu try-job: i686-gnu-nopt
x86-32 float return for 'Rust' ABI: treat all float types consistently This helps with rust-lang/rust#131819: for our own ABI on x86-32, we want to *never* use the float registers. The previous logic only considered F32 and F64, but skipped F16 and F128. So I made the logic just apply to all float types. try-job: i686-gnu try-job: i686-gnu-nopt
x86-32 float return for 'Rust' ABI: treat all float types consistently This helps with rust-lang/rust#131819: for our own ABI on x86-32, we want to *never* use the float registers. The previous logic only considered F32 and F64, but skipped F16 and F128. So I made the logic just apply to all float types. try-job: i686-gnu try-job: i686-gnu-nopt
One way to describe this is to say that there are 3 ABIs on x86-32: softfloat, full-hardfloat (with SSE2), and semi-hardfloat (with x87 but not using SSE registers for anything). Every target triple would have to decide which of these to use, and we'd use the check from #134794 to ensure the right target features are enabled. However, LLVM doesn't actually have a way to force the semi-hardfloat ABI it seems, so wed have to forbid the SSE target feature on those targets... We definitely need a larger discussion here before f16 gets stabilized. We either accept "some targets just can't pass f16 across a function boundary" or we come up with our own ABI and try to convince LLVM to support that. |
@beetrees wrote
So... for the "Rust" ABI we can do our own thing bypassing this (likely similar fo
f32
/f64
, we should just always returnf16
in viaPassMode::Indirect
), but what shall we do for theextern "C"
ABI? We'll need a new dedicated compiler error (likely as part of the pass that we are adding here) that rejects returningf16
when the SSE registers are not available.That will mean that libcore does not compile on i586 targets....Actually libcore uses the "Rust" ABI so that one is fine. But if we haveextern "C"
float functions somewhere those would not be portable any more.Cc @tgross35 @chorman0773
The text was updated successfully, but these errors were encountered: