From 9d3e137c2771301ea9642039c1ac17bbfe01e636 Mon Sep 17 00:00:00 2001 From: Luca Versari Date: Sun, 10 Nov 2024 11:36:50 +0100 Subject: [PATCH] ABI checks: add support for tier2 arches See #131800 for the data collection behind this change. Also adds a test that exercise the "empty list of features" path. --- compiler/rustc_monomorphize/messages.ftl | 8 +++ .../src/collector/abi_check.rs | 53 +++++++++++++------ compiler/rustc_monomorphize/src/errors.rs | 14 +++++ compiler/rustc_target/src/target_features.rs | 20 ++++++- tests/ui/simd-abi-checks-empty-list.rs | 19 +++++++ tests/ui/simd-abi-checks-empty-list.stderr | 12 +++++ 6 files changed, 109 insertions(+), 17 deletions(-) create mode 100644 tests/ui/simd-abi-checks-empty-list.rs create mode 100644 tests/ui/simd-abi-checks-empty-list.stderr diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl index 6da387bbebcc7..33740bcb4bd34 100644 --- a/compiler/rustc_monomorphize/messages.ftl +++ b/compiler/rustc_monomorphize/messages.ftl @@ -7,6 +7,14 @@ monomorphize_abi_error_disabled_vector_type_def = .label = function defined here .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`) +monomorphize_abi_error_unsupported_vector_type_call = + ABI error: this function call uses a vector type that is not currently supported + .label = function called here + +monomorphize_abi_error_unsupported_vector_type_def = + ABI error: this function definition uses a vector type that is not currently supported + .label = function defined here + monomorphize_couldnt_dump_mono_stats = unexpected error occurred while dumping monomorphization stats: {$error} diff --git a/compiler/rustc_monomorphize/src/collector/abi_check.rs b/compiler/rustc_monomorphize/src/collector/abi_check.rs index f1c57f1e9975f..2e231f7f3bf85 100644 --- a/compiler/rustc_monomorphize/src/collector/abi_check.rs +++ b/compiler/rustc_monomorphize/src/collector/abi_check.rs @@ -12,7 +12,10 @@ use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_target::abi::call::{FnAbi, PassMode}; use rustc_target::abi::{BackendRepr, RegKind}; -use crate::errors::{AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDef}; +use crate::errors::{ + AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDef, + AbiErrorUnsupportedVectorTypeCall, AbiErrorUnsupportedVectorTypeDef, +}; fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool { match mode { @@ -29,7 +32,7 @@ fn do_check_abi<'tcx>( tcx: TyCtxt<'tcx>, abi: &FnAbi<'tcx, Ty<'tcx>>, target_feature_def: DefId, - mut emit_err: impl FnMut(&'static str), + mut emit_err: impl FnMut(Option<&'static str>), ) { let Some(feature_def) = tcx.sess.target.features_for_correct_vector_abi() else { return; @@ -42,7 +45,7 @@ fn do_check_abi<'tcx>( let feature = match feature_def.iter().find(|(bits, _)| size.bits() <= *bits) { Some((_, feature)) => feature, None => { - emit_err(""); + emit_err(None); continue; } }; @@ -50,7 +53,7 @@ fn do_check_abi<'tcx>( if !tcx.sess.unstable_target_features.contains(&feature_sym) && !codegen_attrs.target_features.iter().any(|x| x.name == feature_sym) { - emit_err(feature); + emit_err(Some(&feature)); } } } @@ -67,12 +70,21 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { }; do_check_abi(tcx, abi, instance.def_id(), |required_feature| { let span = tcx.def_span(instance.def_id()); - tcx.emit_node_span_lint( - ABI_UNSUPPORTED_VECTOR_TYPES, - CRATE_HIR_ID, - span, - AbiErrorDisabledVectorTypeDef { span, required_feature }, - ); + if let Some(required_feature) = required_feature { + tcx.emit_node_span_lint( + ABI_UNSUPPORTED_VECTOR_TYPES, + CRATE_HIR_ID, + span, + AbiErrorDisabledVectorTypeDef { span, required_feature }, + ); + } else { + tcx.emit_node_span_lint( + ABI_UNSUPPORTED_VECTOR_TYPES, + CRATE_HIR_ID, + span, + AbiErrorUnsupportedVectorTypeDef { span }, + ); + } }) } @@ -111,12 +123,21 @@ fn check_call_site_abi<'tcx>( return; }; do_check_abi(tcx, callee_abi, caller.def_id(), |required_feature| { - tcx.emit_node_span_lint( - ABI_UNSUPPORTED_VECTOR_TYPES, - CRATE_HIR_ID, - span, - AbiErrorDisabledVectorTypeCall { span, required_feature }, - ); + if let Some(required_feature) = required_feature { + tcx.emit_node_span_lint( + ABI_UNSUPPORTED_VECTOR_TYPES, + CRATE_HIR_ID, + span, + AbiErrorDisabledVectorTypeCall { span, required_feature }, + ); + } else { + tcx.emit_node_span_lint( + ABI_UNSUPPORTED_VECTOR_TYPES, + CRATE_HIR_ID, + span, + AbiErrorUnsupportedVectorTypeCall { span }, + ); + } }); } diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index 5048a8d5d993f..02865cad302cb 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -110,3 +110,17 @@ pub(crate) struct AbiErrorDisabledVectorTypeCall<'a> { pub span: Span, pub required_feature: &'a str, } + +#[derive(LintDiagnostic)] +#[diag(monomorphize_abi_error_unsupported_vector_type_def)] +pub(crate) struct AbiErrorUnsupportedVectorTypeDef { + #[label] + pub span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(monomorphize_abi_error_unsupported_vector_type_call)] +pub(crate) struct AbiErrorUnsupportedVectorTypeCall { + #[label] + pub span: Span, +} diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index c4f9c742650d7..60eb5442ff631 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -582,6 +582,14 @@ pub fn all_rust_features() -> impl Iterator { const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "sse"), (256, "avx"), (512, "avx512f")]; const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")]; +const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")]; +const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")]; +const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")]; +const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")]; +// Always warn on RISCV and SPARC, as the necessary target features cannot be enabled in Rust at +// the moment. +const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[]; +const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[]; impl super::spec::Target { pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] { @@ -606,9 +614,19 @@ impl super::spec::Target { // Returns None if we do not support ABI checks on the given target yet. pub fn features_for_correct_vector_abi(&self) -> Option<&'static [(u64, &'static str)]> { match &*self.arch { + // Tier 1 "x86" | "x86_64" => Some(X86_FEATURES_FOR_CORRECT_VECTOR_ABI), "aarch64" => Some(AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI), - // FIXME: add support for non-tier1 architectures + // Tier 2 + "arm64ec" => Some(AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI), + "arm" => Some(ARM_FEATURES_FOR_CORRECT_VECTOR_ABI), + "powerpc" | "powerpc64" => Some(POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI), + "loongarch64" => Some(&[]), // on-stack ABI, so we complain about all by-val vectors + "riscv32" | "riscv64" => Some(RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI), + "wasm32" | "wasm64" => Some(WASM_FEATURES_FOR_CORRECT_VECTOR_ABI), + "s390x" => Some(S390X_FEATURES_FOR_CORRECT_VECTOR_ABI), + "sparc" | "sparc64" => Some(SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI), + // FIXME: add support for non-tier2 architectures _ => None, } } diff --git a/tests/ui/simd-abi-checks-empty-list.rs b/tests/ui/simd-abi-checks-empty-list.rs new file mode 100644 index 0000000000000..19fd3cfac62ff --- /dev/null +++ b/tests/ui/simd-abi-checks-empty-list.rs @@ -0,0 +1,19 @@ +//@ needs-llvm-components: sparc +//@ compile-flags: --target=sparc-unknown-none-elf --crate-type=rlib +//@ build-pass +//@ ignore-pass (test emits codegen-time warnings) +#![no_core] +#![feature(no_core, lang_items, repr_simd)] +#![allow(improper_ctypes_definitions)] +#[lang = "sized"] +trait Sized {} + +#[lang = "copy"] +trait Copy {} + +#[repr(simd)] +pub struct SimdVec([i32; 4]); + +pub extern "C" fn pass_by_vec(_: SimdVec) {} +//~^ ABI error: this function definition uses a vector type that is not currently supported +//~| WARNING this was previously accepted by the compiler diff --git a/tests/ui/simd-abi-checks-empty-list.stderr b/tests/ui/simd-abi-checks-empty-list.stderr new file mode 100644 index 0000000000000..18c370a0662a7 --- /dev/null +++ b/tests/ui/simd-abi-checks-empty-list.stderr @@ -0,0 +1,12 @@ +warning: ABI error: this function definition uses a vector type that is not currently supported + --> $DIR/simd-abi-checks-empty-list.rs:17:1 + | +LL | pub extern "C" fn pass_by_vec(_: SimdVec) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116558 + = note: `#[warn(abi_unsupported_vector_types)]` on by default + +warning: 1 warning emitted +