From e18682e4072674e196cebd4e64362c86acce1e30 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Mon, 14 Oct 2024 22:30:45 +0900 Subject: [PATCH] Support s390x z13 vector ABI --- .../src/collector/abi_check.rs | 10 +- compiler/rustc_monomorphize/src/errors.rs | 4 +- compiler/rustc_target/src/abi/call/s390x.rs | 47 +++- .../spec/targets/s390x_unknown_linux_gnu.rs | 3 - .../spec/targets/s390x_unknown_linux_musl.rs | 3 - tests/assembly/s390x-vector-abi.rs | 228 ++++++++++++++++++ tests/ui/layout/post-mono-layout-cycle-2.rs | 1 - .../ui/layout/post-mono-layout-cycle-2.stderr | 10 +- tests/ui/layout/post-mono-layout-cycle.rs | 1 - tests/ui/layout/post-mono-layout-cycle.stderr | 10 +- tests/ui/simd-abi-checks-s390x.rs | 163 +++++++++++++ tests/ui/simd-abi-checks-s390x.z10.stderr | 86 +++++++ ...simd-abi-checks-s390x.z13_no_vector.stderr | 86 +++++++ ...imd-abi-checks-s390x.z13_soft_float.stderr | 86 +++++++ 14 files changed, 704 insertions(+), 34 deletions(-) create mode 100644 tests/assembly/s390x-vector-abi.rs create mode 100644 tests/ui/simd-abi-checks-s390x.rs create mode 100644 tests/ui/simd-abi-checks-s390x.z10.stderr create mode 100644 tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr create mode 100644 tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr diff --git a/compiler/rustc_monomorphize/src/collector/abi_check.rs b/compiler/rustc_monomorphize/src/collector/abi_check.rs index ecc378ecd3d96..2c641ed0cd12e 100644 --- a/compiler/rustc_monomorphize/src/collector/abi_check.rs +++ b/compiler/rustc_monomorphize/src/collector/abi_check.rs @@ -2,7 +2,7 @@ use rustc_abi::Abi; use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::{Span, Symbol}; -use rustc_target::abi::call::{FnAbi, PassMode}; +use rustc_target::abi::call::{FnAbi, PassMode, RegKind}; use crate::errors::{AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDef}; @@ -10,6 +10,7 @@ use crate::errors::{AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDe // to have their "proper" ABI. const X86_VECTOR_FEATURES: &'static [(u64, &'static str)] = &[(128, "sse"), (256, "avx"), (512, "avx512f")]; +const S390X_VECTOR_FEATURES: &'static [(u64, &'static str)] = &[(128, "vector")]; fn do_check_abi<'tcx>( tcx: TyCtxt<'tcx>, @@ -22,6 +23,8 @@ fn do_check_abi<'tcx>( } else if tcx.sess.target.arch == "aarch64" { // ABI on aarch64 does not depend on target features. return; + } else if tcx.sess.target.arch == "s390x" { + S390X_VECTOR_FEATURES } else { // FIXME: add support for non-tier1 architectures return; @@ -31,6 +34,7 @@ fn do_check_abi<'tcx>( let size = arg_abi.layout.size; if matches!(arg_abi.layout.abi, Abi::Vector { .. }) && !matches!(arg_abi.mode, PassMode::Indirect { .. }) + || matches!(&arg_abi.mode, PassMode::Cast { cast, .. } if cast.rest.unit.kind == RegKind::Vector) { let feature = match feature_def.iter().find(|(bits, _)| size.bits() <= *bits) { Some((_, feature)) => feature, @@ -48,7 +52,7 @@ fn do_check_abi<'tcx>( /// Checks that the ABI of a given instance of a function does not contain vector-passed arguments /// or return values for which the corresponding target feature is not enabled. -pub fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { +pub(crate) fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { let param_env = ParamEnv::reveal_all(); let Ok(abi) = tcx.fn_abi_of_instance(param_env.and((instance, ty::List::empty()))) else { // An error will be reported during codegen if we cannot determine the ABI of this @@ -65,7 +69,7 @@ pub fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { /// Checks that a call expression does not try to pass a vector-passed argument which requires a /// target feature that the caller does not have, as doing so causes UB because of ABI mismatch. -pub fn check_call_site_abi<'tcx>( +pub(crate) fn check_call_site_abi<'tcx>( tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index e99321252bdc9..3005374f16052 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -96,7 +96,7 @@ pub(crate) struct UnknownCguCollectionMode<'a> { #[derive(Diagnostic)] #[diag(monomorphize_abi_error_disabled_vector_type_def)] #[help] -pub struct AbiErrorDisabledVectorTypeDef<'a> { +pub(crate) struct AbiErrorDisabledVectorTypeDef<'a> { #[primary_span] pub span: Span, pub required_feature: &'a str, @@ -105,7 +105,7 @@ pub struct AbiErrorDisabledVectorTypeDef<'a> { #[derive(Diagnostic)] #[diag(monomorphize_abi_error_disabled_vector_type_call)] #[help] -pub struct AbiErrorDisabledVectorTypeCall<'a> { +pub(crate) struct AbiErrorDisabledVectorTypeCall<'a> { #[primary_span] pub span: Span, pub required_feature: &'a str, diff --git a/compiler/rustc_target/src/abi/call/s390x.rs b/compiler/rustc_target/src/abi/call/s390x.rs index 502e733126777..3eb8b88c3edcc 100644 --- a/compiler/rustc_target/src/abi/call/s390x.rs +++ b/compiler/rustc_target/src/abi/call/s390x.rs @@ -1,16 +1,35 @@ -// FIXME: The assumes we're using the non-vector ABI, i.e., compiling -// for a pre-z13 machine or using -mno-vx. - -use crate::abi::call::{ArgAbi, FnAbi, Reg}; -use crate::abi::{HasDataLayout, TyAbiInterface}; +use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind}; +use crate::abi::{Abi, HasDataLayout, Size, TyAbiInterface, TyAndLayout}; use crate::spec::HasTargetSpec; +fn contains_vector<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>, expected_size: Size) -> bool +where + Ty: TyAbiInterface<'a, C> + Copy, +{ + match layout.abi { + Abi::Uninhabited | Abi::Scalar(_) | Abi::ScalarPair(..) => false, + Abi::Vector { .. } => layout.size == expected_size, + Abi::Aggregate { .. } => { + for i in 0..layout.fields.count() { + if contains_vector(cx, layout.field(cx, i), expected_size) { + return true; + } + } + false + } + } +} + fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { - if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 { + let size = ret.layout.size; + if size.bits() <= 128 && matches!(ret.layout.abi, Abi::Vector { .. }) { + return; + } + if !ret.layout.is_aggregate() && size.bits() <= 64 { ret.extend_integer_width_to(64); - } else { - ret.make_indirect(); + return; } + ret.make_indirect(); } fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) @@ -32,19 +51,25 @@ where } return; } - if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 { + + let size = arg.layout.size; + if size.bits() <= 128 && contains_vector(cx, arg.layout, size) { + arg.cast_to(Reg { kind: RegKind::Vector, size }); + return; + } + if !arg.layout.is_aggregate() && size.bits() <= 64 { arg.extend_integer_width_to(64); return; } if arg.layout.is_single_fp_element(cx) { - match arg.layout.size.bytes() { + match size.bytes() { 4 => arg.cast_to(Reg::f32()), 8 => arg.cast_to(Reg::f64()), _ => arg.make_indirect(), } } else { - match arg.layout.size.bytes() { + match size.bytes() { 1 => arg.cast_to(Reg::i8()), 2 => arg.cast_to(Reg::i16()), 4 => arg.cast_to(Reg::i32()), diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs index 3efbb46483613..a84a18a433ffc 100644 --- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs @@ -6,9 +6,6 @@ pub(crate) fn target() -> Target { base.endian = Endian::Big; // z10 is the oldest CPU supported by LLVM base.cpu = "z10".into(); - // FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector - // ABI. Pass the -vector feature string to LLVM to respect this assumption. - base.features = "-vector".into(); base.max_atomic_width = Some(128); base.min_global_align = Some(16); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs index 65b5c1167bdd8..4bde0fb729c75 100644 --- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs @@ -6,9 +6,6 @@ pub(crate) fn target() -> Target { base.endian = Endian::Big; // z10 is the oldest CPU supported by LLVM base.cpu = "z10".into(); - // FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector - // ABI. Pass the -vector feature string to LLVM to respect this assumption. - base.features = "-vector".into(); base.max_atomic_width = Some(128); base.min_global_align = Some(16); base.static_position_independent_executables = true; diff --git a/tests/assembly/s390x-vector-abi.rs b/tests/assembly/s390x-vector-abi.rs new file mode 100644 index 0000000000000..da3829587374f --- /dev/null +++ b/tests/assembly/s390x-vector-abi.rs @@ -0,0 +1,228 @@ +//@ revisions: z10 z10_vector z13 z13_no_vector +// ignore-tidy-linelength +//@ assembly-output: emit-asm +//@ compile-flags: -O -Z merge-functions=disabled +//@[z10] compile-flags: --target s390x-unknown-linux-gnu --cfg no_vector +//@[z10] needs-llvm-components: systemz +//@[z10_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector +//@[z10_vector] needs-llvm-components: systemz +//@[z13] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 +//@[z13] needs-llvm-components: systemz +//@[z13_no_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector --cfg no_vector +//@[z13_no_vector] needs-llvm-components: systemz + +#![feature(no_core, lang_items, repr_simd, s390x_target_feature)] +#![no_core] +#![crate_type = "lib"] +#![allow(non_camel_case_types)] + +// Cases where vector feature is disabled are rejected. +// See tests/ui/simd-abi-checks-s390x.rs for test for them. + +#[lang = "sized"] +pub trait Sized {} +#[lang = "copy"] +pub trait Copy {} +#[lang = "freeze"] +pub trait Freeze {} + +impl Copy for [T; N] {} + +#[repr(simd)] +pub struct i8x8([i8; 8]); +#[repr(simd)] +pub struct i8x16([i8; 16]); +#[repr(simd)] +pub struct i8x32([i8; 32]); +#[repr(C)] +pub struct Wrapper(T); +#[repr(transparent)] +pub struct TransparentWrapper(T); + +impl Copy for i8 {} +impl Copy for i64 {} +impl Copy for i8x8 {} +impl Copy for i8x16 {} +impl Copy for i8x32 {} +impl Copy for Wrapper {} +impl Copy for TransparentWrapper {} + +// CHECK-LABEL: vector_ret_small: +// CHECK: vlrepg %v24, 0(%r2) +// CHECK-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { + *x +} +// CHECK-LABEL: vector_ret: +// CHECK: vl %v24, 0(%r2), 3 +// CHECK-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_ret(x: &i8x16) -> i8x16 { + *x +} +// CHECK-LABEL: vector_ret_large: +// z10: vl %v0, 16(%r3), 4 +// z10-NEXT: vl %v1, 0(%r3), 4 +// z10-NEXT: vst %v0, 16(%r2), 4 +// z10-NEXT: vst %v1, 0(%r2), 4 +// z10-NEXT: br %r14 +// z13: vl %v0, 0(%r3), 4 +// z13-NEXT: vl %v1, 16(%r3), 4 +// z13-NEXT: vst %v1, 16(%r2), 4 +// z13-NEXT: vst %v0, 0(%r2), 4 +// z13-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_ret_large(x: &i8x32) -> i8x32 { + *x +} + +// CHECK-LABEL: vector_wrapper_ret_small: +// CHECK: mvc 0(8,%r2), 0(%r3) +// CHECK-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_wrapper_ret_small(x: &Wrapper) -> Wrapper { + *x +} +// CHECK-LABEL: vector_wrapper_ret: +// CHECK: mvc 0(16,%r2), 0(%r3) +// CHECK-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_wrapper_ret(x: &Wrapper) -> Wrapper { + *x +} +// CHECK-LABEL: vector_wrapper_ret_large: +// z10: vl %v0, 16(%r3), 4 +// z10-NEXT: vl %v1, 0(%r3), 4 +// z10-NEXT: vst %v0, 16(%r2), 4 +// z10-NEXT: vst %v1, 0(%r2), 4 +// z10-NEXT: br %r14 +// z13: vl %v0, 16(%r3), 4 +// z13-NEXT: vst %v0, 16(%r2), 4 +// z13-NEXT: vl %v0, 0(%r3), 4 +// z13-NEXT: vst %v0, 0(%r2), 4 +// z13-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_wrapper_ret_large(x: &Wrapper) -> Wrapper { + *x +} + +// CHECK-LABEL: vector_transparent_wrapper_ret_small: +// CHECK: vlrepg %v24, 0(%r2) +// CHECK-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_transparent_wrapper_ret_small( + x: &TransparentWrapper, +) -> TransparentWrapper { + *x +} +// CHECK-LABEL: vector_transparent_wrapper_ret: +// CHECK: vl %v24, 0(%r2), 3 +// CHECK-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_transparent_wrapper_ret( + x: &TransparentWrapper, +) -> TransparentWrapper { + *x +} +// CHECK-LABEL: vector_transparent_wrapper_ret_large: +// z10: vl %v0, 16(%r3), 4 +// z10-NEXT: vl %v1, 0(%r3), 4 +// z10-NEXT: vst %v0, 16(%r2), 4 +// z10-NEXT: vst %v1, 0(%r2), 4 +// z10-NEXT: br %r14 +// z13: vl %v0, 0(%r3), 4 +// z13-NEXT: vl %v1, 16(%r3), 4 +// z13-NEXT: vst %v1, 16(%r2), 4 +// z13-NEXT: vst %v0, 0(%r2), 4 +// z13-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_transparent_wrapper_ret_large( + x: &TransparentWrapper, +) -> TransparentWrapper { + *x +} + +// CHECK-LABEL: vector_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_arg_small(x: i8x8) -> i64 { + unsafe { *(&x as *const i8x8 as *const i64) } +} +// CHECK-LABEL: vector_arg: +// CHECK: vlgvg %r2, %v24, 0 +// CHECK-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_arg(x: i8x16) -> i64 { + unsafe { *(&x as *const i8x16 as *const i64) } +} +// CHECK-LABEL: vector_arg_large: +// CHECK: lg %r2, 0(%r2) +// CHECK-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_arg_large(x: i8x32) -> i64 { + unsafe { *(&x as *const i8x32 as *const i64) } +} + +// CHECK-LABEL: vector_wrapper_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_arg_small(x: Wrapper) -> i64 { + unsafe { *(&x as *const Wrapper as *const i64) } +} +// CHECK-LABEL: vector_wrapper_arg: +// 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_arg(x: Wrapper) -> i64 { + unsafe { *(&x as *const Wrapper as *const i64) } +} +// CHECK-LABEL: vector_wrapper_arg_large: +// 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_arg_large(x: Wrapper) -> i64 { + unsafe { *(&x as *const Wrapper as *const i64) } +} + +// CHECK-LABEL: vector_transparent_wrapper_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_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { + unsafe { *(&x as *const TransparentWrapper as *const i64) } +} +// CHECK-LABEL: vector_transparent_wrapper_arg: +// CHECK: vlgvg %r2, %v24, 0 +// CHECK-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { + unsafe { *(&x as *const TransparentWrapper as *const i64) } +} +// CHECK-LABEL: vector_transparent_wrapper_arg_large: +// CHECK: lg %r2, 0(%r2) +// CHECK-NEXT: br %r14 +#[cfg_attr(no_vector, target_feature(enable = "vector"))] +#[no_mangle] +unsafe extern "C" fn vector_transparent_wrapper_arg_large(x: TransparentWrapper) -> i64 { + unsafe { *(&x as *const TransparentWrapper as *const i64) } +} diff --git a/tests/ui/layout/post-mono-layout-cycle-2.rs b/tests/ui/layout/post-mono-layout-cycle-2.rs index 356f1e777c7d0..e9a5292fbbdfb 100644 --- a/tests/ui/layout/post-mono-layout-cycle-2.rs +++ b/tests/ui/layout/post-mono-layout-cycle-2.rs @@ -45,7 +45,6 @@ where T: Blah, { async fn ice(&mut self) { - //~^ ERROR a cycle occurred during layout computation let arr: [(); 0] = []; self.t.iter(arr.into_iter()).await; } diff --git a/tests/ui/layout/post-mono-layout-cycle-2.stderr b/tests/ui/layout/post-mono-layout-cycle-2.stderr index ad01c2694faf5..ea69b39706f48 100644 --- a/tests/ui/layout/post-mono-layout-cycle-2.stderr +++ b/tests/ui/layout/post-mono-layout-cycle-2.stderr @@ -12,12 +12,12 @@ LL | Blah::iter(self, iterator).await | = note: a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future -error: a cycle occurred during layout computation - --> $DIR/post-mono-layout-cycle-2.rs:47:5 +note: the above error was encountered while instantiating `fn main::{closure#0}` + --> $DIR/post-mono-layout-cycle-2.rs:16:15 | -LL | async fn ice(&mut self) { - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | match fut.as_mut().poll(ctx) { + | ^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0733`. diff --git a/tests/ui/layout/post-mono-layout-cycle.rs b/tests/ui/layout/post-mono-layout-cycle.rs index 8d136190c0052..6753c01267ecd 100644 --- a/tests/ui/layout/post-mono-layout-cycle.rs +++ b/tests/ui/layout/post-mono-layout-cycle.rs @@ -14,7 +14,6 @@ struct Wrapper { } fn abi(_: Option>) {} -//~^ ERROR a cycle occurred during layout computation fn indirect() { abi::(None); diff --git a/tests/ui/layout/post-mono-layout-cycle.stderr b/tests/ui/layout/post-mono-layout-cycle.stderr index 47f7f30b1cb4c..e2f6ac595d006 100644 --- a/tests/ui/layout/post-mono-layout-cycle.stderr +++ b/tests/ui/layout/post-mono-layout-cycle.stderr @@ -5,12 +5,12 @@ error[E0391]: cycle detected when computing layout of `Wrapper<()>` = note: cycle used when computing layout of `core::option::Option>` = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: a cycle occurred during layout computation - --> $DIR/post-mono-layout-cycle.rs:16:1 +note: the above error was encountered while instantiating `fn indirect::<()>` + --> $DIR/post-mono-layout-cycle.rs:23:5 | -LL | fn abi(_: Option>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | indirect::<()>(); + | ^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/simd-abi-checks-s390x.rs b/tests/ui/simd-abi-checks-s390x.rs new file mode 100644 index 0000000000000..31a91e73af9cd --- /dev/null +++ b/tests/ui/simd-abi-checks-s390x.rs @@ -0,0 +1,163 @@ +//@ revisions: z10 z13_no_vector z13_soft_float +//@ build-fail +//@[z10] compile-flags: --target s390x-unknown-linux-gnu +//@[z10] needs-llvm-components: systemz +//@[z13_no_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector +//@[z13_no_vector] needs-llvm-components: systemz +// FIXME: +soft-float itself doesn't set -vector +//@[z13_soft_float] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector,+soft-float +//@[z13_soft_float] needs-llvm-components: systemz + +#![feature(no_core, lang_items, repr_simd, s390x_target_feature)] +#![no_core] +#![crate_type = "lib"] +#![allow(non_camel_case_types, improper_ctypes_definitions)] + +#[lang = "sized"] +pub trait Sized {} +#[lang = "copy"] +pub trait Copy {} +#[lang = "freeze"] +pub trait Freeze {} + +impl Copy for [T; N] {} + +#[repr(simd)] +pub struct i8x8([i8; 8]); +#[repr(simd)] +pub struct i8x16([i8; 16]); +#[repr(simd)] +pub struct i8x32([i8; 32]); +#[repr(C)] +pub struct Wrapper(T); +#[repr(transparent)] +pub struct TransparentWrapper(T); + +impl Copy for i8 {} +impl Copy for i64 {} +impl Copy for i8x8 {} +impl Copy for i8x16 {} +impl Copy for i8x32 {} +impl Copy for Wrapper {} +impl Copy for TransparentWrapper {} + +#[no_mangle] +extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { + //~^ ABI error: this function definition uses a vector vector type, which is not enabled + *x +} +#[no_mangle] +extern "C" fn vector_ret(x: &i8x16) -> i8x16 { + //~^ ABI error: this function definition uses a vector vector type, which is not enabled + *x +} +#[no_mangle] +extern "C" fn vector_ret_large(x: &i8x32) -> i8x32 { + // Ok + *x +} + +#[no_mangle] +#[target_feature(enable = "vector")] +unsafe extern "C" fn vector_ret_target_feature_small(x: &i8x8) -> i8x8 { + // Ok + *x +} +#[no_mangle] +#[target_feature(enable = "vector")] +unsafe extern "C" fn vector_target_feature_ret(x: &i8x16) -> i8x16 { + // Ok + *x +} +#[no_mangle] +#[target_feature(enable = "vector")] +unsafe extern "C" fn vector_ret_target_feature_large(x: &i8x32) -> i8x32 { + // Ok + *x +} + +#[no_mangle] +extern "C" fn vector_wrapper_ret_small(x: &Wrapper) -> Wrapper { + // Ok + *x +} +#[no_mangle] +extern "C" fn vector_wrapper_ret(x: &Wrapper) -> Wrapper { + // Ok + *x +} +#[no_mangle] +extern "C" fn vector_wrapper_ret_large(x: &Wrapper) -> Wrapper { + // Ok + *x +} + +#[no_mangle] +extern "C" fn vector_transparent_wrapper_ret_small( + x: &TransparentWrapper, +) -> TransparentWrapper { + //~^^^ ABI error: this function definition uses a vector vector type, which is not enabled + *x +} +#[no_mangle] +extern "C" fn vector_transparent_wrapper_ret( + x: &TransparentWrapper, +) -> TransparentWrapper { + //~^^^ ABI error: this function definition uses a vector vector type, which is not enabled + *x +} +#[no_mangle] +extern "C" fn vector_transparent_wrapper_ret_large( + x: &TransparentWrapper, +) -> TransparentWrapper { + // Ok + *x +} + +#[no_mangle] +extern "C" fn vector_arg_small(x: i8x8) -> i64 { + //~^ ABI error: this function definition uses a vector vector type, which is not enabled + unsafe { *(&x as *const i8x8 as *const i64) } +} +#[no_mangle] +extern "C" fn vector_arg(x: i8x16) -> i64 { + //~^ ABI error: this function definition uses a vector vector type, which is not enabled + unsafe { *(&x as *const i8x16 as *const i64) } +} +#[no_mangle] +extern "C" fn vector_arg_large(x: i8x32) -> i64 { + // Ok + unsafe { *(&x as *const i8x32 as *const i64) } +} + +#[no_mangle] +extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { + //~^ ABI error: this function definition uses a vector vector type, which is not enabled + unsafe { *(&x as *const Wrapper as *const i64) } +} +#[no_mangle] +extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { + //~^ ABI error: this function definition uses a vector vector type, which is not enabled + unsafe { *(&x as *const Wrapper as *const i64) } +} +#[no_mangle] +extern "C" fn vector_wrapper_arg_large(x: Wrapper) -> i64 { + // Ok + unsafe { *(&x as *const Wrapper as *const i64) } +} + +#[no_mangle] +extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { + //~^ ABI error: this function definition uses a vector vector type, which is not enabled + unsafe { *(&x as *const TransparentWrapper as *const i64) } +} +#[no_mangle] +extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { + //~^ ABI error: this function definition uses a vector vector type, which is not enabled + unsafe { *(&x as *const TransparentWrapper as *const i64) } +} +#[no_mangle] +extern "C" fn vector_transparent_wrapper_arg_large(x: TransparentWrapper) -> i64 { + // Ok + unsafe { *(&x as *const TransparentWrapper as *const i64) } +} diff --git a/tests/ui/simd-abi-checks-s390x.z10.stderr b/tests/ui/simd-abi-checks-s390x.z10.stderr new file mode 100644 index 0000000000000..f3323d12c4fd2 --- /dev/null +++ b/tests/ui/simd-abi-checks-s390x.z10.stderr @@ -0,0 +1,86 @@ +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:45:1 + | +LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:50:1 + | +LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:96:1 + | +LL | / extern "C" fn vector_transparent_wrapper_ret_small( +LL | | x: &TransparentWrapper, +LL | | ) -> TransparentWrapper { + | |_____________________________^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:103:1 + | +LL | / extern "C" fn vector_transparent_wrapper_ret( +LL | | x: &TransparentWrapper, +LL | | ) -> TransparentWrapper { + | |______________________________^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:118:1 + | +LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:123:1 + | +LL | extern "C" fn vector_arg(x: i8x16) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:134:1 + | +LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:139:1 + | +LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:150:1 + | +LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:155:1 + | +LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: aborting due to 10 previous errors + diff --git a/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr b/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr new file mode 100644 index 0000000000000..f3323d12c4fd2 --- /dev/null +++ b/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr @@ -0,0 +1,86 @@ +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:45:1 + | +LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:50:1 + | +LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:96:1 + | +LL | / extern "C" fn vector_transparent_wrapper_ret_small( +LL | | x: &TransparentWrapper, +LL | | ) -> TransparentWrapper { + | |_____________________________^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:103:1 + | +LL | / extern "C" fn vector_transparent_wrapper_ret( +LL | | x: &TransparentWrapper, +LL | | ) -> TransparentWrapper { + | |______________________________^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:118:1 + | +LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:123:1 + | +LL | extern "C" fn vector_arg(x: i8x16) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:134:1 + | +LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:139:1 + | +LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:150:1 + | +LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:155:1 + | +LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: aborting due to 10 previous errors + diff --git a/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr b/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr new file mode 100644 index 0000000000000..f3323d12c4fd2 --- /dev/null +++ b/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr @@ -0,0 +1,86 @@ +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:45:1 + | +LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:50:1 + | +LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:96:1 + | +LL | / extern "C" fn vector_transparent_wrapper_ret_small( +LL | | x: &TransparentWrapper, +LL | | ) -> TransparentWrapper { + | |_____________________________^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:103:1 + | +LL | / extern "C" fn vector_transparent_wrapper_ret( +LL | | x: &TransparentWrapper, +LL | | ) -> TransparentWrapper { + | |______________________________^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:118:1 + | +LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:123:1 + | +LL | extern "C" fn vector_arg(x: i8x16) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:134:1 + | +LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:139:1 + | +LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:150:1 + | +LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: ABI error: this function definition uses a vector vector type, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:155:1 + | +LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider enabling it globally (-C target-feature=+vector) or locally (#[target_feature(enable="vector")]) + +error: aborting due to 10 previous errors +