Skip to content
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

Implement va_list and va_arg for s390x FFI #105381

Merged
merged 1 commit into from
Dec 20, 2022

Conversation

uweigand
Copy link
Contributor

@uweigand uweigand commented Dec 6, 2022

Following the s390x ELF ABI and based on the clang implementation, provide appropriate definitions of va_list in library/core/src/ffi/mod.rs and va_arg handling in compiler/rustc_codegen_llvm/src/va_arg.rs.

Fixes the following test cases on s390x:
src/test/run-make-fulldeps/c-link-to-rust-va-list-fn src/test/ui/abi/variadic-ffi.rs

Fixes #84628.

@rustbot
Copy link
Collaborator

rustbot commented Dec 6, 2022

r? @davidtwco

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Dec 6, 2022
@rustbot
Copy link
Collaborator

rustbot commented Dec 6, 2022

Hey! It looks like you've submitted a new PR for the library teams!

If this PR contains changes to any rust-lang/rust public library APIs then please comment with @rustbot label +T-libs-api -T-libs to tag it appropriately. If this PR contains changes to any unstable APIs please edit the PR description to add a link to the relevant API Change Proposal or create one if you haven't already. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.

Examples of T-libs-api changes:

  • Stabilizing library features
  • Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
  • Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
  • Changing public documentation in ways that create new stability guarantees
  • Changing observable runtime behavior of library APIs

@cuviper
Copy link
Member

cuviper commented Dec 6, 2022

@davidtwco if you're not comfortable looking at s390x, I can take review on this.

Copy link
Contributor

@dlrobertson dlrobertson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome! Thanks for the work! I don't know a ton about s390x, but is va_end by chance a nop? See this comment.

@uweigand
Copy link
Contributor Author

uweigand commented Dec 6, 2022

This is awesome! Thanks for the work! I don't know a ton about s390x, but is va_end by chance a nop? See this comment.

Yes, va_end is a no-op on s390x as well.

Copy link
Contributor

@dlrobertson dlrobertson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for working on this! Looks reasonable after look at clangs implementation followed by a review of this, but note that I have no experience with s390x. Also not that I don't have a box to test this on.

// FIXME: structs with a single element of floating-point type should be
// passed in a FPR instead of a GPR.
let gpr_type = indirect || target_ty.is_any_ptr() || target_ty.is_integral();
let (max_regs, reg_count, reg_save_index, reg_padding) = if gpr_type {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I like the way clang does this with a reg_count_field here (either 0 or 1) followed by something like:

let reg_count = bx.struct_gep(...,reg_count_field))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

let reg_ptr =
bx.struct_gep(va_list_ty, va_list_addr, va_list_layout.llvm_field_index(bx.cx, 3));
let reg_ptr_v = bx.load(bx.type_i8p(), reg_ptr, bx.tcx().data_layout.pointer_align.abi);
let reg_off = bx.mul(reg_count_v, bx.const_u64(8));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could we use something more clang-like (e.g. scaled_reg_count). I have no real strong opinions, but it would be nice to avoid re-using reg_off.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

let target_ty_size = bx.cx.size_of(target_ty).bytes();
let indirect: bool = target_ty_size > 8 || !target_ty_size.is_power_of_two();
let unpadded_size = if indirect { 8 } else { target_ty_size };
let padded_size = 8;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

padded_size - unpadded_size is used at least twice, would it make sense to add a variable for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Following the s390x ELF ABI and based on the clang implementation,
provide appropriate definitions of va_list in library/core/src/ffi/mod.rs
and va_arg handling in compiler/rustc_codegen_llvm/src/va_arg.rs.

Fixes the following test cases on s390x:
src/test/run-make-fulldeps/c-link-to-rust-va-list-fn
src/test/ui/abi/variadic-ffi.rs

Fixes rust-lang#84628.
@uweigand
Copy link
Contributor Author

Thanks again for working on this! Looks reasonable after look at clangs implementation followed by a review of this, but note that I have no experience with s390x. Also not that I don't have a box to test this on.

Thanks for the review! I've addressed your comments, and also resolved the one FIXME about aggregate handling.

FWIW I'm pretty confident that the s390x ABI parts are correct (I'm the code owner of the IBM Z LLVM back-end, and one of the authors of the platform ABI specification); if there's still a bug somewhere, it's more likely to be about the Rust compiler implementation details, which I'm not very familar with.

I have run the full test suite (./x.py test) natively on a s390x machine, and the patch does fix the two previously failing test cases mentioned above. If there are any further tests you'd like me to run, please let me know.

Copy link
Contributor

@dlrobertson dlrobertson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if there's still a bug somewhere, it's more likely to be about the Rust compiler implementation details, which I'm not very familar with.

Looks like you got those bits right!

FWIW I'm pretty confident that the s390x ABI parts are correct (I'm the code owner of the IBM Z LLVM back-end, and one of the authors of the platform ABI specification);

👍 just wanted to spot check, and learn a bit about s390x 😃

@dlrobertson
Copy link
Contributor

I'm unable to r+ this, but this looks great!

CC @joshtriplett @cuviper

@nikic
Copy link
Contributor

nikic commented Dec 20, 2022

@nikic
Copy link
Contributor

nikic commented Dec 20, 2022

@bors r+

@bors
Copy link
Contributor

bors commented Dec 20, 2022

📌 Commit eb22d70 has been approved by nikic

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 20, 2022
@bors
Copy link
Contributor

bors commented Dec 20, 2022

⌛ Testing commit eb22d70 with merge d6da428...

@bors
Copy link
Contributor

bors commented Dec 20, 2022

☀️ Test successful - checks-actions
Approved by: nikic
Pushing d6da428 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Dec 20, 2022
@bors bors merged commit d6da428 into rust-lang:master Dec 20, 2022
@rustbot rustbot added this to the 1.68.0 milestone Dec 20, 2022
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (d6da428): comparison URL.

Overall result: ✅ improvements - no action needed

@rustbot label: -perf-regression

Instruction count

This is a highly reliable metric that was used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-1.1% [-1.2%, -1.0%] 2
Improvements ✅
(secondary)
-2.3% [-2.6%, -2.0%] 6
All ❌✅ (primary) -1.1% [-1.2%, -1.0%] 2

Max RSS (memory usage)

This benchmark run did not return any relevant results for this metric.

Cycles

This benchmark run did not return any relevant results for this metric.

@dlrobertson
Copy link
Contributor

\o/ Thanks @uweigand for working on this!

@uweigand uweigand deleted the s390x-ffi-vaarg branch December 22, 2022 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

run-make-fulldeps/c-link-to-rust-va-list-fn fails on s390x
8 participants