-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Conversation
r? @davidtwco (rustbot has picked a reviewer for you, use r? to override) |
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
@davidtwco if you're not comfortable looking at s390x, I can take review on this. |
There was a problem hiding this 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.
Yes, |
There was a problem hiding this 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 { |
There was a problem hiding this comment.
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))
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
972833d
to
eb22d70
Compare
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 ( |
There was a problem hiding this 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 😃
I'm unable to r+ this, but this looks great! |
@bors r+ |
☀️ Test successful - checks-actions |
Finished benchmarking commit (d6da428): comparison URL. Overall result: ✅ improvements - no action needed@rustbot label: -perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)This benchmark run did not return any relevant results for this metric. CyclesThis benchmark run did not return any relevant results for this metric. |
\o/ Thanks @uweigand for working on this! |
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.