-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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_win64 ABI: do not use xmm0 with softfloat ABI #137094
Conversation
f91c8f4
to
aa699ee
Compare
I have extended the |
Thanks, I didn't realize this code path is also used for softfloat targets. @bors r+ rollup |
@bors r- Per rust-lang/compiler-builtins#758, it seems like it would be better to return |
That solution still isn't very clean because LLVM's use of a register pair doesn't seem to match the Windows CC:
However, doing a hack-ish fixup on our side seems preferable in order to unblock work on #116558, with the expectation that #132570 will remove that requirement. LLVM probably should also fix the i128 return convention for Windows without SSE (looks like windows without sse2 was supported until mid windows 7?) but I don't think we need to wait for that. |
So are you saying I should do this for all ABIs, or just the softfloat ABI?
"Not very clean" or "quite unsound"? If the ABIs are different it'd be more like the latter, no? |
Hm, is it expected that f128 and i128 are handled very differently as arguments? We generate a native LLVM IR argument for |
aa699ee
to
778ec18
Compare
So, like this I guess? Not sure how to test this, I guess one has to look at the assembly to see what LLVM does with this but assembly is all gibberish to me.^^ |
Just for softfloat, we still need to make sure it uses the xmm0 return for hardfloat.
It has the same soundness issue as other x86 targets if code with and without sse is mixed. I don’t think there is any compatibility concern within the targets, Clang seems to reject __int128 for i586 Windows and it returns in two registers for UEFI (not at a computer so I can’t post the godbolt links). There isn’t anything to be compatible with from the Microsoft side, but indirect returning seems like a more faithful read of the calling convention. I haven’t confirmed this but I think our i128 is incompatible with __int128 on UEFI and i586 Windows, since Clang seems to return it as a register pair (which LLVM also expects for calls to builtins) but we return indirectly. So matching that seems reasonable until/unless LLVM changes to return indirectly. I am unsure if there is a good reference for what the UEFI calling convention for i128 would be in an ideal world or where an ABI spec comes from. @nicholasbishop do you have any idea? |
Didn't you say in rust-lang/compiler-builtins#758 that LLVM is now doing this right by itself? |
778ec18
to
ae0d314
Compare
Iirc something about using LLVM’s i128 type didn’t produce the correct results. I’ll double check this and get some better reproductions. |
I built this code for various different targets with this PR: #[no_mangle]
pub unsafe extern "C" fn ret_u128(x: &u128) -> u128 {
*x
}
#[repr(simd)]
pub struct U64x2([u64; 2]);
impl Copy for U64x2 {}
#[no_mangle]
pub unsafe extern "C" fn ret_simd(x: &U64x2) -> U64x2 {
*x
}
#[no_mangle]
pub unsafe extern "C" fn do_div(x: &u128, y: &u128, z: &mut u128) {
*z = *x / *y;
} Here's what I got:
Does that look like it's using the right registers or not? I don't see |
9697b34
to
0b78678
Compare
I did that now, and also added an assembly test to ensure this does not regress. I guess this snippet means that for softfloat, when LLVM invokes the intrinsic, rax and rdx are the right registers:
|
Isn't it an LLVM bug that an intrinsic that returns |
This comment has been minimized.
This comment has been minimized.
0b78678
to
cbaf42d
Compare
Two nits if this needs future changes but no reason to wait on those now. The behavior looks correct to me. @bors r+ rollup |
Nevermind, LLVM is still using rax and rdx for |
Also to confirm this, LLVM seems to return More at rust-lang/compiler-builtins#758. |
@bors r- |
cbaf42d
to
73b6482
Compare
@bors r=tgross35 |
…iaskrgr Rollup of 9 pull requests Successful merges: - rust-lang#127793 (Added project-specific Zed IDE settings) - rust-lang#134995 (Stabilize const_slice_flatten) - rust-lang#136301 (Improve instant docs) - rust-lang#136347 (Add a bullet point to `std::fs::copy`) - rust-lang#136794 (Stabilize file_lock) - rust-lang#137094 (x86_win64 ABI: do not use xmm0 with softfloat ABI) - rust-lang#137227 (docs(dev): Update the feature-gate instructions) - rust-lang#137232 (Don't mention `FromResidual` on bad `?`) - rust-lang#137251 (coverage: Get hole spans from nested items without fully visiting them) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#137094 - RalfJung:softfloat-means-no-simd, r=tgross35 x86_win64 ABI: do not use xmm0 with softfloat ABI This adjusts rust-lang#134290 to not apply the new logic to targets marked as "softfloat". That fixes most instances of the issue brought up [here](rust-lang#116558 (comment)). r? `@tgross35`
This adjusts #134290 to not apply the new logic to targets marked as "softfloat". That fixes most instances of the issue brought up here.
r? @tgross35