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

Support s390x z13 vector ABI #131586

Merged
merged 1 commit into from
Nov 21, 2024
Merged

Support s390x z13 vector ABI #131586

merged 1 commit into from
Nov 21, 2024

Conversation

taiki-e
Copy link
Member

@taiki-e taiki-e commented Oct 12, 2024

cc #130869

This resolves the following fixmes:

Refs: Section 1.2.3 "Parameter Passing" and section 1.2.5 "Return Values" in ELF Application Binary Interface s390x Supplement, Version 1.6.1 (lzsabi_s390x.pdf in https://github.com/IBM/s390x-abi/releases/tag/v1.6.1)

This PR extends #127731 #132173 (merged) 's ABI check to handle cases where vector target feature is disabled.
If we do not do ABI check, we run into the ABI problems as described in #116558 and #130869 (comment), and the problem of the compiler generating strange code (#131586 (comment)).

cc @uweigand

@rustbot label +O-SystemZ +A-ABI

@rustbot
Copy link
Collaborator

rustbot commented Oct 12, 2024

r? @jieyouxu

rustbot has assigned @jieyouxu.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@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. O-SystemZ Target: SystemZ processors (s390x) labels Oct 12, 2024
@taiki-e taiki-e mentioned this pull request Oct 12, 2024
11 tasks
@rust-log-analyzer

This comment has been minimized.

@jieyouxu
Copy link
Member

r? compiler

@rust-log-analyzer

This comment has been minimized.

@taiki-e taiki-e force-pushed the s390x-vector-abi branch 3 times, most recently from c14d9b2 to d39e822 Compare October 12, 2024 13:40
@taiki-e

This comment was marked as outdated.

@taiki-e

This comment was marked as outdated.

@rustbot rustbot added S-blocked Status: Blocked on something else such as an RFC or other implementation work. A-ABI Area: Concerning the application binary interface (ABI) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 12, 2024
Copy link
Contributor

@uweigand uweigand left a comment

Choose a reason for hiding this comment

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

In addition to the problem mentioned inline, we should also verify that building with soft-float works as expected. This option implicitly disables any use of floating-point or vector registers, and therefore also disables use of the vector facility. I believe the LLVM back-end should handle that logic correctly, but it would be good to have the test check.

tests/assembly/s390x-vector-abi.rs Outdated Show resolved Hide resolved
@taiki-e taiki-e force-pushed the s390x-vector-abi branch 2 times, most recently from 0a6b7ad to c1835bd Compare October 14, 2024 11:31
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-blocked Status: Blocked on something else such as an RFC or other implementation work. labels Nov 10, 2024
@rust-log-analyzer

This comment has been minimized.

Comment on lines 251 to 279
// CHECK-LABEL: vector_wrapper_with_zst_arg_small:
// CHECK: vlgvg %r2, %v24, 0
// CHECK-NEXT: br %r14
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
#[no_mangle]
unsafe extern "C" fn vector_wrapper_with_zst_arg_small(x: WrapperWithZst<i8x8>) -> i64 {
Copy link
Member Author

@taiki-e taiki-e Nov 10, 2024

Choose a reason for hiding this comment

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

The current implementation of this PR ignores ZST (zero sized type) in a structure, is this incorrect? Or is the current implementation where ZST is specifically ignored correct?

From the ABI doc mentioned in PR description:

‹vector_arg›: A vector_arg has one of the following types:

  • Any vector type whose size is 16 bytes or less.
  • A structure equivalent to such a vector type, where “equivalent” has the same meaning as for double_or_float.

And double_or_float is:

‹double_or_float›: A double_or_float is one of the following:

  • A float or _Decimal32.
  • A double or _Decimal64.
  • A structure equivalent to one of the above. A structure is equivalent to a type 𝑇 if and only if it has exactly one member, which is either of type 𝑇 itself or a structure equivalent to type 𝑇.

Looking at the existing code, is the handling of ZST platform dependent? (#125854)

if arg.is_ignore() {
// s390x-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs.
if cx.target_spec().os == "linux"
&& matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc")
&& arg.layout.is_zst()
{
arg.make_indirect_from_ignore();
}
return;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

This is unfortunately a bit more complicated due to historical reasons. For the purposes of deciding whether an aggregate is a "structure equivalent to a float or vector", zero-sized members in C are not ignored. The presence of a zero-sized bitfield, nested struct, or nested array member does make the aggregate not equivalent, i.e. it will be passed in GPRs and not in FPRs/VRs.

However, for C++ types, there are some zero-sized members that are ignored; this applies in particular to zero-sized base classes as well as C++20 empty data members (marked with [[no_unique_address]]). This is not currently documented in the ABI (but then again, the ABI doesn't document anything about C++ ...).

The question is, what does this now mean for Rust? My understanding is that Rust here attempts to be ABI-compatible with C only (not C++), and therefore I think it makes sense that Rust should be treated like C, i.e. zero-sized members are not ignored. Current Rust code seems to correctly implement this for FP types via is_single_fp_element, so I think this PR should do the same for vector types.

As to the second question, what if the whole argument is zero-sized? Both the strict reading of the ABI document and the actual GCC/clang implementation agree that this is passed via implicit pointer (which arguably doesn't make much sense, but we cannot change this anymore). So the current Rust code looks correct to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks. I fixed this PR's implementation by adding&using is_single_vector_element based on is_single_fp_element.

// CHECK-LABEL: vector_wrapper_with_zst_arg_small:
// CHECK: .cfi_startproc
// CHECK-NOT: vlgvg
// CHECK-NEXT: br %r14
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
#[no_mangle]
unsafe extern "C" fn vector_wrapper_with_zst_arg_small(x: WrapperWithZst<i8x8>) -> i64 {
unsafe { *(&x as *const WrapperWithZst<i8x8> as *const i64) }
}
// CHECK-LABEL: vector_wrapper_with_zst_arg:
// CHECK: lg %r2, 0(%r2)
// CHECK-NEXT: br %r14
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
#[no_mangle]
unsafe extern "C" fn vector_wrapper_with_zst_arg(x: WrapperWithZst<i8x16>) -> i64 {

@taiki-e taiki-e force-pushed the s390x-vector-abi branch 2 times, most recently from f5a7735 to 55d960e Compare November 11, 2024 17:08
if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {

let size = arg.layout.size;
if size.bits() <= 128 && arg.layout.is_single_vector_element(cx) {
Copy link
Contributor

Choose a reason for hiding this comment

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

There's one more quirk I think we need to handle here: for single-element vector aggregates, the aggregate must have no padding, i.e. the aggregate size must match the vector size. (This is different for FP aggregates, where e.g. an 8-byte aligned struct with a single float element is passed like a double.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, good catch. Older versions of this PR had a check for that, but I accidentally removed it when I rewrote it based on is_single_fp_element.

Re-added size check and added a test for this case:

// https://github.com/rust-lang/rust/pull/131586#discussion_r1837071121
// CHECK-LABEL: vector_wrapper_padding_arg:
// CHECK: lg %r2, 0(%r2)
// CHECK-NEXT: br %r14
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
#[no_mangle]
unsafe extern "C" fn vector_wrapper_padding_arg(x: WrapperAlign16<i8x8>) -> i64 {

@rust-log-analyzer

This comment has been minimized.

Copy link
Contributor

@uweigand uweigand left a comment

Choose a reason for hiding this comment

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

Thanks! This now looks fully correct from an s390x ABI perspective.

@bors
Copy link
Contributor

bors commented Nov 14, 2024

☔ The latest upstream changes (presumably #133006) made this pull request unmergeable. Please resolve the merge conflicts.

@rust-log-analyzer

This comment has been minimized.

@compiler-errors
Copy link
Member

@bors r=compiler-errors,uweigand

@bors
Copy link
Contributor

bors commented Nov 21, 2024

📌 Commit 7652e34 has been approved by compiler-errors,uweigand

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 Nov 21, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Nov 21, 2024
…iaskrgr

Rollup of 6 pull requests

Successful merges:

 - rust-lang#130236 (unstable feature usage metrics)
 - rust-lang#131544 (Make asm label blocks safe context)
 - rust-lang#131586 (Support s390x z13 vector ABI)
 - rust-lang#132489 (Fix closure arg extraction in `extract_callable_info`, generalize it to async closures)
 - rust-lang#133078 (tests: ui/inline-consts: add issue number to a test, rename other tests)
 - rust-lang#133283 (Don't exclude relnotes from `needs-triage` label)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 379b221 into rust-lang:master Nov 21, 2024
6 checks passed
@rustbot rustbot added this to the 1.84.0 milestone Nov 21, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Nov 21, 2024
Rollup merge of rust-lang#131586 - taiki-e:s390x-vector-abi, r=compiler-errors,uweigand

Support s390x z13 vector ABI

cc rust-lang#130869

This resolves the following fixmes:
- https://github.com/rust-lang/rust/blob/58420a065b68ecb3eec03b942740c761cdadd5c4/compiler/rustc_target/src/abi/call/s390x.rs#L1-L2
- https://github.com/rust-lang/rust/blob/58420a065b68ecb3eec03b942740c761cdadd5c4/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs#L9-L11

Refs: Section 1.2.3 "Parameter Passing" and section 1.2.5 "Return Values" in ELF Application Binary Interface s390x Supplement, Version 1.6.1 (lzsabi_s390x.pdf in https://github.com/IBM/s390x-abi/releases/tag/v1.6.1)

This PR extends ~~rust-lang#127731 rust-lang#132173 (merged) 's ABI check to handle cases where `vector` target feature is disabled.
If we do not do ABI check, we run into the ABI problems as described in rust-lang#116558 and rust-lang#130869 (comment), and the problem of the compiler generating strange code (rust-lang#131586 (comment)).

cc `@uweigand`

`@rustbot` label +O-SystemZ +A-ABI
@taiki-e taiki-e deleted the s390x-vector-abi branch November 21, 2024 17:24
@RalfJung
Copy link
Member

This PR extends #127731 #132173 (merged) 's ABI check to handle cases where vector target feature is disabled.
If we do not do ABI check, we run into the ABI problems as described in #116558 and #130869 (comment), and the problem of the compiler generating strange code (#131586 (comment)).

Is this an outdated part of the description? This PR does not seem to touch that logic at all.

@taiki-e
Copy link
Member Author

taiki-e commented Nov 30, 2024

@RalfJung That part is indeed outdated since it is handled by #132842 that opened after this PR and merged before this PR.1

(As for the ABI check, only the addition of the test was eventually remained in this PR.)

Footnotes

  1. To be more precise, that PR was merged after this PR was approved by the target maintainer: https://github.com/rust-lang/rust/pull/131586#issuecomment-2475414732

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ABI Area: Concerning the application binary interface (ABI) A-testsuite Area: The testsuite used to check the correctness of rustc O-SystemZ Target: SystemZ processors (s390x) S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants