-
Notifications
You must be signed in to change notification settings - Fork 218
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-64: Some extern "C"
functions use U64x2
on a softfloat target, which makes no sense
#758
Comments
I believe compiler-builtins/src/macros.rs Lines 580 to 601 in 3c09866
I don't understand the uefi situation though; is LLVM still expecting that builtins return via xmm0 even though we consider it no-sse2? In that case, removing the workaround for uefi would break things if done after rust-lang/rust#137094 lands. Or is something already broken now? |
The UEFI target has |
I didn't realize |
Enabling that hack on uefi was done in #475 to fix u128 division: rust-lang/rust#86494 So it was certainly getting used on the x86_64 UEFI target in 2021, but perhaps other changes since then have made that no longer true? |
@nicholasbishop do you happen to remember what the difference was between the broken ABI and the fixed ABI? It seems unlikely that either of them used xmm0, given the target features we are setting for LLVM. |
To confirm, the target has been using soft float since it was introduced rust-lang/rust@88cf2a2. |
The ABI is now correct on |
rust-lang/rust#132570 would probably be the best solution then. However, that doesn't seem too close to ready. I guess making our |
So we should emit an i128 does not fit into a single register. So does it use two registers for the return value then? |
LLVM seems to give the desired behavior for for that returns i128 directly. It looks like Clang is returning
That seems to be what Clang is doing now, and what LLVM expects for UEFI and no-sse Windows. Which probably isn’t ideal. An alternative we have is to make our ABI return indirect but use naked asm to forward the calling convention in builtins. But I think it would be simplest to just match what LLVM expects for now and open an issue upstream. |
The Windows calling convention only allows a single return register. Are you sure |
#759 removes the abi hack, I hope that should then fix this problem.
When LLVM calls
So, it seems to be passing something via rax and rdx, i.e., via two registers? See here for the full assembly. This godbolt shared above also seems to confirm that LLVM uses two registers for |
It looks like UEFI, Windows+softfloat, and linux+softfloat act exactly the same for By Microsoft's ABI, i128 needs to be passed indirectly so this behavior violates the guidelines. I think this is something LLVM leaves up to us to get correct, however. For libcalls, x86_64 Linux and UEFI the same CC as I don't know what the libcall ABI is on i686/i586 because LLVM seems to emit a large inline assembly routine rather than calling out. For reference: https://llvm.godbolt.org/z/fzP1xozGq |
I opened llvm/llvm-project#127723 for the LLVM change. But I think that with rust-lang/rust#137094 our behavior should agree with what LLVM expects for libcalls as well as what Clang does, using our definition |
What is particularly confusing me here is |
I think this may just be LLVM's expected behavior (I'll elaborate at llvm/llvm-project#127723) |
Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: rust-lang/compiler-builtins#759 Link: rust-lang#116558 Link: rust-lang/compiler-builtins#758
Update `compiler-builtins` to 0.1.147 Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: rust-lang/compiler-builtins#759 Link: rust-lang#116558 Link: rust-lang/compiler-builtins#758 try-job: x86_64-msvc-1 try-job: x86_64-msvc-2 try-job: x86_64-mingw-1 try-job: x86_64-mingw-2
Update `compiler-builtins` to 0.1.147 Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: rust-lang/compiler-builtins#759 Link: rust-lang#116558 Link: rust-lang/compiler-builtins#758 try-job: x86_64-mingw-1 try-job: x86_64-mingw-2
Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: rust-lang/compiler-builtins#759 Link: rust-lang#116558 Link: rust-lang/compiler-builtins#758
Update `compiler-builtins` to 0.1.147 Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: rust-lang/compiler-builtins#759 Link: rust-lang#116558 Link: rust-lang/compiler-builtins#758 try-job: x86_64-mingw-1 try-job: x86_64-mingw-2
Update `compiler-builtins` to 0.1.147 Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: rust-lang/compiler-builtins#759 Link: rust-lang#116558 Link: rust-lang/compiler-builtins#758 try-job: x86_64-mingw-1 try-job: x86_64-mingw-2
Rollup merge of rust-lang#137297 - tgross35:update-builtins, r=tgross35 Update `compiler-builtins` to 0.1.147 Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: rust-lang/compiler-builtins#759 Link: rust-lang#116558 Link: rust-lang/compiler-builtins#758 try-job: x86_64-mingw-1 try-job: x86_64-mingw-2
Update `compiler-builtins` to 0.1.147 Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: rust-lang/compiler-builtins#759 Link: rust-lang/rust#116558 Link: rust-lang/compiler-builtins#758 try-job: x86_64-mingw-1 try-job: x86_64-mingw-2
Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: rust-lang/compiler-builtins#759 Link: rust-lang/rust#116558 Link: rust-lang/compiler-builtins#758
Update `compiler-builtins` to 0.1.147 Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: rust-lang/compiler-builtins#759 Link: rust-lang/rust#116558 Link: rust-lang/compiler-builtins#758 try-job: x86_64-mingw-1 try-job: x86_64-mingw-2
Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: rust-lang/compiler-builtins#759 Link: rust-lang#116558 Link: rust-lang/compiler-builtins#758
Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: rust-lang/compiler-builtins#759 Link: rust-lang#116558 Link: rust-lang/compiler-builtins#758
Passing
U64x2
across anextern "C"
boundary on x86-64 requires SSE; it is hence not possible to pass those types when SSE is disabled, which is the case for softfloat targets. (See rust-lang/rust#116558 for more context on how ABI and SIMD target features interact.) This comes up, for instance, when building forx86_64-unknown-uefi
.Here are the places where a SIMD type is passed via
extern "C"
:The text was updated successfully, but these errors were encountered: