Skip to content

Commit ff485c9

Browse files
committed
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.
1 parent 6689597 commit ff485c9

File tree

6 files changed

+112
-17
lines changed

6 files changed

+112
-17
lines changed

compiler/rustc_monomorphize/messages.ftl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ monomorphize_abi_error_disabled_vector_type_def =
77
.label = function defined here
88
.help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`)
99
10+
monomorphize_abi_error_unsupported_vector_type_call =
11+
this function call uses a SIMD vector type that is not currently supported with the chosen ABI
12+
.label = function called here
13+
monomorphize_abi_error_unsupported_vector_type_def =
14+
this function definition uses a SIMD vector type that is not currently supported with the chosen ABI
15+
.label = function defined here
16+
1017
monomorphize_couldnt_dump_mono_stats =
1118
unexpected error occurred while dumping monomorphization stats: {$error}
1219

compiler/rustc_monomorphize/src/collector/abi_check.rs

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ use rustc_span::{DUMMY_SP, Span, Symbol};
1212
use rustc_target::abi::call::{FnAbi, PassMode};
1313
use rustc_target::abi::{BackendRepr, RegKind};
1414

15-
use crate::errors::{AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDef};
15+
use crate::errors::{
16+
AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDef,
17+
AbiErrorUnsupportedVectorTypeCall, AbiErrorUnsupportedVectorTypeDef,
18+
};
1619

1720
fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool {
1821
match mode {
@@ -25,11 +28,15 @@ fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool {
2528
}
2629
}
2730

31+
/// Checks whether a certain function ABI is compatible with the target features currently enabled
32+
/// for a certain function.
33+
/// If not, `emit_err` is called, with `Some(feature)` if a certain feature should be enabled and
34+
/// with `None` if no feature is known that would make the ABI compatible.
2835
fn do_check_abi<'tcx>(
2936
tcx: TyCtxt<'tcx>,
3037
abi: &FnAbi<'tcx, Ty<'tcx>>,
3138
target_feature_def: DefId,
32-
mut emit_err: impl FnMut(&'static str),
39+
mut emit_err: impl FnMut(Option<&'static str>),
3340
) {
3441
let Some(feature_def) = tcx.sess.target.features_for_correct_vector_abi() else {
3542
return;
@@ -42,15 +49,15 @@ fn do_check_abi<'tcx>(
4249
let feature = match feature_def.iter().find(|(bits, _)| size.bits() <= *bits) {
4350
Some((_, feature)) => feature,
4451
None => {
45-
emit_err("<no available feature for this size>");
52+
emit_err(None);
4653
continue;
4754
}
4855
};
4956
let feature_sym = Symbol::intern(feature);
5057
if !tcx.sess.unstable_target_features.contains(&feature_sym)
5158
&& !codegen_attrs.target_features.iter().any(|x| x.name == feature_sym)
5259
{
53-
emit_err(feature);
60+
emit_err(Some(&feature));
5461
}
5562
}
5663
}
@@ -67,12 +74,21 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
6774
};
6875
do_check_abi(tcx, abi, instance.def_id(), |required_feature| {
6976
let span = tcx.def_span(instance.def_id());
70-
tcx.emit_node_span_lint(
71-
ABI_UNSUPPORTED_VECTOR_TYPES,
72-
CRATE_HIR_ID,
73-
span,
74-
AbiErrorDisabledVectorTypeDef { span, required_feature },
75-
);
77+
if let Some(required_feature) = required_feature {
78+
tcx.emit_node_span_lint(
79+
ABI_UNSUPPORTED_VECTOR_TYPES,
80+
CRATE_HIR_ID,
81+
span,
82+
AbiErrorDisabledVectorTypeDef { span, required_feature },
83+
);
84+
} else {
85+
tcx.emit_node_span_lint(
86+
ABI_UNSUPPORTED_VECTOR_TYPES,
87+
CRATE_HIR_ID,
88+
span,
89+
AbiErrorUnsupportedVectorTypeDef { span },
90+
);
91+
}
7692
})
7793
}
7894

@@ -111,12 +127,21 @@ fn check_call_site_abi<'tcx>(
111127
return;
112128
};
113129
do_check_abi(tcx, callee_abi, caller.def_id(), |required_feature| {
114-
tcx.emit_node_span_lint(
115-
ABI_UNSUPPORTED_VECTOR_TYPES,
116-
CRATE_HIR_ID,
117-
span,
118-
AbiErrorDisabledVectorTypeCall { span, required_feature },
119-
);
130+
if let Some(required_feature) = required_feature {
131+
tcx.emit_node_span_lint(
132+
ABI_UNSUPPORTED_VECTOR_TYPES,
133+
CRATE_HIR_ID,
134+
span,
135+
AbiErrorDisabledVectorTypeCall { span, required_feature },
136+
);
137+
} else {
138+
tcx.emit_node_span_lint(
139+
ABI_UNSUPPORTED_VECTOR_TYPES,
140+
CRATE_HIR_ID,
141+
span,
142+
AbiErrorUnsupportedVectorTypeCall { span },
143+
);
144+
}
120145
});
121146
}
122147

compiler/rustc_monomorphize/src/errors.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,17 @@ pub(crate) struct AbiErrorDisabledVectorTypeCall<'a> {
110110
pub span: Span,
111111
pub required_feature: &'a str,
112112
}
113+
114+
#[derive(LintDiagnostic)]
115+
#[diag(monomorphize_abi_error_unsupported_vector_type_def)]
116+
pub(crate) struct AbiErrorUnsupportedVectorTypeDef {
117+
#[label]
118+
pub span: Span,
119+
}
120+
121+
#[derive(LintDiagnostic)]
122+
#[diag(monomorphize_abi_error_unsupported_vector_type_call)]
123+
pub(crate) struct AbiErrorUnsupportedVectorTypeCall {
124+
#[label]
125+
pub span: Span,
126+
}

compiler/rustc_target/src/target_features.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,14 @@ pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
582582
const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
583583
&[(128, "sse"), (256, "avx"), (512, "avx512f")];
584584
const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
585+
const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
586+
const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")];
587+
const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")];
588+
const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];
589+
// Always warn on RISCV and SPARC, as the necessary target features cannot be enabled in Rust at
590+
// the moment.
591+
const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[];
592+
const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[];
585593

586594
impl super::spec::Target {
587595
pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
@@ -606,9 +614,19 @@ impl super::spec::Target {
606614
// Returns None if we do not support ABI checks on the given target yet.
607615
pub fn features_for_correct_vector_abi(&self) -> Option<&'static [(u64, &'static str)]> {
608616
match &*self.arch {
617+
// Tier 1
609618
"x86" | "x86_64" => Some(X86_FEATURES_FOR_CORRECT_VECTOR_ABI),
610619
"aarch64" => Some(AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI),
611-
// FIXME: add support for non-tier1 architectures
620+
// Tier 2
621+
"arm64ec" => Some(AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI),
622+
"arm" => Some(ARM_FEATURES_FOR_CORRECT_VECTOR_ABI),
623+
"powerpc" | "powerpc64" => Some(POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI),
624+
"loongarch64" => Some(&[]), // on-stack ABI, so we complain about all by-val vectors
625+
"riscv32" | "riscv64" => Some(RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI),
626+
"wasm32" | "wasm64" => Some(WASM_FEATURES_FOR_CORRECT_VECTOR_ABI),
627+
"s390x" => Some(S390X_FEATURES_FOR_CORRECT_VECTOR_ABI),
628+
"sparc" | "sparc64" => Some(SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI),
629+
// FIXME: add support for non-tier2 architectures
612630
_ => None,
613631
}
614632
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ needs-llvm-components: sparc
2+
//@ compile-flags: --target=sparc-unknown-none-elf --crate-type=rlib
3+
//@ build-pass
4+
//@ ignore-pass (test emits codegen-time warnings)
5+
#![no_core]
6+
#![feature(no_core, lang_items, repr_simd)]
7+
#![allow(improper_ctypes_definitions)]
8+
#[lang = "sized"]
9+
trait Sized {}
10+
11+
#[lang = "copy"]
12+
trait Copy {}
13+
14+
#[repr(simd)]
15+
pub struct SimdVec([i32; 4]);
16+
17+
pub extern "C" fn pass_by_vec(_: SimdVec) {}
18+
//~^ this function definition uses a SIMD vector type that is not currently supported with the chosen ABI
19+
//~| WARNING this was previously accepted by the compiler
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
warning: this function definition uses a SIMD vector type that is not currently supported with the chosen ABI
2+
--> $DIR/simd-abi-checks-empty-list.rs:17:1
3+
|
4+
LL | pub extern "C" fn pass_by_vec(_: SimdVec) {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
6+
|
7+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8+
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
9+
= note: `#[warn(abi_unsupported_vector_types)]` on by default
10+
11+
warning: 1 warning emitted
12+

0 commit comments

Comments
 (0)