Skip to content

Commit 379b221

Browse files
authored
Rollup merge of #131586 - taiki-e:s390x-vector-abi, r=compiler-errors,uweigand
Support s390x z13 vector ABI cc #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 ~~#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
2 parents 3956495 + 7652e34 commit 379b221

9 files changed

+865
-14
lines changed

Diff for: compiler/rustc_abi/src/layout/ty.rs

+18
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,24 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
209209
}
210210
}
211211

212+
pub fn is_single_vector_element<C>(self, cx: &C, expected_size: Size) -> bool
213+
where
214+
Ty: TyAbiInterface<'a, C>,
215+
C: HasDataLayout,
216+
{
217+
match self.backend_repr {
218+
BackendRepr::Vector { .. } => self.size == expected_size,
219+
BackendRepr::Memory { .. } => {
220+
if self.fields.count() == 1 && self.fields.offset(0).bytes() == 0 {
221+
self.field(cx, 0).is_single_vector_element(cx, expected_size)
222+
} else {
223+
false
224+
}
225+
}
226+
_ => false,
227+
}
228+
}
229+
212230
pub fn is_adt<C>(self) -> bool
213231
where
214232
Ty: TyAbiInterface<'a, C>,

Diff for: compiler/rustc_target/src/callconv/s390x.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
// FIXME: The assumes we're using the non-vector ABI, i.e., compiling
2-
// for a pre-z13 machine or using -mno-vx.
1+
// Reference: ELF Application Binary Interface s390x Supplement
2+
// https://github.com/IBM/s390x-abi
33

4-
use crate::abi::call::{ArgAbi, FnAbi, Reg};
5-
use crate::abi::{HasDataLayout, TyAbiInterface};
4+
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind};
5+
use crate::abi::{BackendRepr, HasDataLayout, TyAbiInterface};
66
use crate::spec::HasTargetSpec;
77

88
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
9-
if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
9+
let size = ret.layout.size;
10+
if size.bits() <= 128 && matches!(ret.layout.backend_repr, BackendRepr::Vector { .. }) {
11+
return;
12+
}
13+
if !ret.layout.is_aggregate() && size.bits() <= 64 {
1014
ret.extend_integer_width_to(64);
1115
} else {
1216
ret.make_indirect();
@@ -32,19 +36,25 @@ where
3236
}
3337
return;
3438
}
35-
if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {
39+
40+
let size = arg.layout.size;
41+
if size.bits() <= 128 && arg.layout.is_single_vector_element(cx, size) {
42+
arg.cast_to(Reg { kind: RegKind::Vector, size });
43+
return;
44+
}
45+
if !arg.layout.is_aggregate() && size.bits() <= 64 {
3646
arg.extend_integer_width_to(64);
3747
return;
3848
}
3949

4050
if arg.layout.is_single_fp_element(cx) {
41-
match arg.layout.size.bytes() {
51+
match size.bytes() {
4252
4 => arg.cast_to(Reg::f32()),
4353
8 => arg.cast_to(Reg::f64()),
4454
_ => arg.make_indirect(),
4555
}
4656
} else {
47-
match arg.layout.size.bytes() {
57+
match size.bytes() {
4858
1 => arg.cast_to(Reg::i8()),
4959
2 => arg.cast_to(Reg::i16()),
5060
4 => arg.cast_to(Reg::i32()),

Diff for: compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs

-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ pub(crate) fn target() -> Target {
66
base.endian = Endian::Big;
77
// z10 is the oldest CPU supported by LLVM
88
base.cpu = "z10".into();
9-
// FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
10-
// ABI. Pass the -vector feature string to LLVM to respect this assumption.
11-
base.features = "-vector".into();
129
base.max_atomic_width = Some(128);
1310
base.min_global_align = Some(16);
1411
base.stack_probes = StackProbeType::Inline;

Diff for: compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs

-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ pub(crate) fn target() -> Target {
66
base.endian = Endian::Big;
77
// z10 is the oldest CPU supported by LLVM
88
base.cpu = "z10".into();
9-
// FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
10-
// ABI. Pass the -vector feature string to LLVM to respect this assumption.
11-
base.features = "-vector".into();
129
base.max_atomic_width = Some(128);
1310
base.min_global_align = Some(16);
1411
base.static_position_independent_executables = true;

0 commit comments

Comments
 (0)