Skip to content

make abi_unsupported_vector_types a hard error #139309

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

Merged
merged 2 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions compiler/rustc_codegen_cranelift/example/std_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
unboxed_closures
)]
#![allow(internal_features)]
// FIXME once abi_unsupported_vector_types is a hard error disable the foo test when the respective
// target feature is not enabled.
#![allow(abi_unsupported_vector_types)]

#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,11 @@ fn register_builtins(store: &mut LintStore) {
"converted into hard error, see PR #139001 \
<https://github.com/rust-lang/rust/issues/139001> for more information",
);
store.register_removed(
"abi_unsupported_vector_types",
"converted into hard error, \
see <https://github.com/rust-lang/rust/issues/116558> for more information",
);
}

fn register_internals(store: &mut LintStore) {
Expand Down
69 changes: 0 additions & 69 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ declare_lint_pass! {
/// that are used by other parts of the compiler.
HardwiredLints => [
// tidy-alphabetical-start
ABI_UNSUPPORTED_VECTOR_TYPES,
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
AMBIGUOUS_ASSOCIATED_ITEMS,
AMBIGUOUS_GLOB_IMPORTS,
Expand Down Expand Up @@ -5027,74 +5026,6 @@ declare_lint! {
crate_level_only
}

declare_lint! {
/// The `abi_unsupported_vector_types` lint detects function definitions and calls
/// whose ABI depends on enabling certain target features, but those features are not enabled.
///
/// ### Example
///
/// ```rust,ignore (fails on non-x86_64)
/// extern "C" fn missing_target_feature(_: std::arch::x86_64::__m256) {
/// todo!()
/// }
///
/// #[target_feature(enable = "avx")]
/// unsafe extern "C" fn with_target_feature(_: std::arch::x86_64::__m256) {
/// todo!()
/// }
///
/// fn main() {
/// let v = unsafe { std::mem::zeroed() };
/// unsafe { with_target_feature(v); }
/// }
/// ```
///
/// This will produce:
///
/// ```text
/// warning: ABI error: this function call uses a avx vector type, which is not enabled in the caller
/// --> lint_example.rs:18:12
/// |
/// | unsafe { with_target_feature(v); }
/// | ^^^^^^^^^^^^^^^^^^^^^^ function called 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 <https://github.com/rust-lang/rust/issues/116558>
/// = help: consider enabling it globally (-C target-feature=+avx) or locally (#[target_feature(enable="avx")])
/// = note: `#[warn(abi_unsupported_vector_types)]` on by default
///
///
/// warning: ABI error: this function definition uses a avx vector type, which is not enabled
/// --> lint_example.rs:3:1
/// |
/// | pub extern "C" fn with_target_feature(_: std::arch::x86_64::__m256) {
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 <https://github.com/rust-lang/rust/issues/116558>
/// = help: consider enabling it globally (-C target-feature=+avx) or locally (#[target_feature(enable="avx")])
/// ```
///
///
///
/// ### Explanation
///
/// The C ABI for `__m256` requires the value to be passed in an AVX register,
/// which is only possible when the `avx` target feature is enabled.
/// Therefore, `missing_target_feature` cannot be compiled without that target feature.
/// A similar (but complementary) message is triggered when `with_target_feature` is called
/// by a function that does not enable the `avx` target feature.
///
/// Note that this lint is very similar to the `-Wpsabi` warning in `gcc`/`clang`.
pub ABI_UNSUPPORTED_VECTOR_TYPES,
Warn,
"this function call or definition uses a vector type which is not enabled",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
reference: "issue #116558 <https://github.com/rust-lang/rust/issues/116558>",
};
}

declare_lint! {
/// The `wasm_c_abi` lint detects usage of the `extern "C"` ABI of wasm that is affected
/// by a planned ABI change that has the goal of aligning Rust with the standard C ABI
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_monomorphize/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ pub(crate) struct UnknownCguCollectionMode<'a> {
pub mode: &'a str,
}

#[derive(LintDiagnostic)]
#[derive(Diagnostic)]
#[diag(monomorphize_abi_error_disabled_vector_type)]
#[help]
pub(crate) struct AbiErrorDisabledVectorType<'a> {
#[primary_span]
#[label]
pub span: Span,
pub required_feature: &'a str,
Expand All @@ -82,9 +83,10 @@ pub(crate) struct AbiErrorDisabledVectorType<'a> {
pub is_call: bool,
}

#[derive(LintDiagnostic)]
#[derive(Diagnostic)]
#[diag(monomorphize_abi_error_unsupported_vector_type)]
pub(crate) struct AbiErrorUnsupportedVectorType<'a> {
#[primary_span]
#[label]
pub span: Span,
pub ty: Ty<'a>,
Expand Down
34 changes: 12 additions & 22 deletions compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_hir::{CRATE_HIR_ID, HirId};
use rustc_middle::mir::{self, Location, traversal};
use rustc_middle::ty::layout::LayoutCx;
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypingEnv};
use rustc_session::lint::builtin::{ABI_UNSUPPORTED_VECTOR_TYPES, WASM_C_ABI};
use rustc_session::lint::builtin::WASM_C_ABI;
use rustc_span::def_id::DefId;
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
use rustc_target::callconv::{ArgAbi, Conv, FnAbi, PassMode};
Expand Down Expand Up @@ -50,34 +50,24 @@ fn do_check_simd_vector_abi<'tcx>(
let feature = match feature_def.iter().find(|(bits, _)| size.bits() <= *bits) {
Some((_, feature)) => feature,
None => {
let (span, hir_id) = loc();
tcx.emit_node_span_lint(
ABI_UNSUPPORTED_VECTOR_TYPES,
hir_id,
let (span, _hir_id) = loc();
tcx.dcx().emit_err(errors::AbiErrorUnsupportedVectorType {
span,
errors::AbiErrorUnsupportedVectorType {
span,
ty: arg_abi.layout.ty,
is_call,
},
);
ty: arg_abi.layout.ty,
is_call,
});
continue;
}
};
if !have_feature(Symbol::intern(feature)) {
// Emit error.
let (span, hir_id) = loc();
tcx.emit_node_span_lint(
ABI_UNSUPPORTED_VECTOR_TYPES,
hir_id,
let (span, _hir_id) = loc();
tcx.dcx().emit_err(errors::AbiErrorDisabledVectorType {
span,
errors::AbiErrorDisabledVectorType {
span,
required_feature: feature,
ty: arg_abi.layout.ty,
is_call,
},
);
required_feature: feature,
ty: arg_abi.layout.ty,
is_call,
});
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[
(32768, "zvl32768b"),
(65536, "zvl65536b"),
];
// Always warn on SPARC, as the necessary target features cannot be enabled in Rust at the moment.
// Always error on SPARC, as the necessary target features cannot be enabled in Rust at the moment.
const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[/*(64, "vis")*/];

const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
Expand Down
7 changes: 5 additions & 2 deletions tests/assembly/simd-bitmask.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ pub unsafe extern "C" fn bitmask_m8x16(mask: m8x16) -> u16 {
simd_bitmask(mask)
}

// CHECK-LABEL: bitmask_m8x64
// x86-avx512-LABEL: bitmask_m8x64
#[no_mangle]
#[cfg(x86_avx512)]
pub unsafe extern "C" fn bitmask_m8x64(mask: m8x64) -> u64 {
// The simd_bitmask intrinsic already uses the most significant bit, so no shift is necessary.
// Note that x86 has no byte shift, llvm uses a word shift to move the least significant bit
Expand Down Expand Up @@ -128,8 +129,10 @@ pub unsafe extern "C" fn bitmask_m64x2(mask: m64x2) -> u8 {
simd_bitmask(mask)
}

// CHECK-LABEL: bitmask_m64x4
// x86-avx2-LABEL: bitmask_m64x4
// x86-avx512-LABEL: bitmask_m64x4
#[no_mangle]
#[cfg(any(x86_avx2, x86_avx512))]
pub unsafe extern "C" fn bitmask_m64x4(mask: m64x4) -> u8 {
// The simd_bitmask intrinsic already uses the most significant bit, so no shift is necessary.
//
Expand Down
7 changes: 5 additions & 2 deletions tests/assembly/simd-intrinsic-select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ pub unsafe extern "C" fn select_f64x2(mask: m64x2, a: f64x2, b: f64x2) -> f64x2
simd_select(mask, a, b)
}

// CHECK-LABEL: select_f64x4
// x86-avx2-LABEL: select_f64x4
// x86-avx512-LABEL: select_f64x4
#[no_mangle]
#[cfg(any(x86_avx2, x86_avx512))]
pub unsafe extern "C" fn select_f64x4(mask: m64x4, a: f64x4, b: f64x4) -> f64x4 {
// The parameter is a 256 bit vector which in the C abi is only valid for avx targets.
//
Expand All @@ -113,8 +115,9 @@ pub unsafe extern "C" fn select_f64x4(mask: m64x4, a: f64x4, b: f64x4) -> f64x4
simd_select(mask, a, b)
}

// CHECK-LABEL: select_f64x8
// x86-avx512-LABEL: select_f64x8
#[no_mangle]
#[cfg(x86_avx512)]
pub unsafe extern "C" fn select_f64x8(mask: m64x8, a: f64x8, b: f64x8) -> f64x8 {
// The parameter is a 256 bit vector which in the C abi is only valid for avx512 targets.
//
Expand Down
25 changes: 4 additions & 21 deletions tests/codegen/const-vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#![feature(repr_simd)]
#![feature(rustc_attrs)]
#![feature(simd_ffi)]
#![feature(arm_target_feature)]
#![allow(non_camel_case_types)]

// Setting up structs that can be used as const vectors
Expand All @@ -28,40 +29,22 @@ pub struct Simd<T, const N: usize>([T; N]);

extern "unadjusted" {
fn test_i8x2(a: i8x2);
}

extern "unadjusted" {
fn test_i8x2_two_args(a: i8x2, b: i8x2);
}

extern "unadjusted" {
fn test_i8x2_mixed_args(a: i8x2, c: i32, b: i8x2);
}

extern "unadjusted" {
fn test_i8x2_arr(a: i8x2);
}

extern "unadjusted" {
fn test_f32x2(a: f32x2);
}

extern "unadjusted" {
fn test_f32x2_arr(a: f32x2);
}

extern "unadjusted" {
fn test_simd(a: Simd<i32, 4>);
}

extern "unadjusted" {
fn test_simd_unaligned(a: Simd<i32, 3>);
}

// Ensure the packed variant of the simd struct does not become a const vector
// if the size is not a power of 2
// CHECK: %"Simd<i32, 3>" = type { [3 x i32] }

#[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
#[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
pub fn do_call() {
unsafe {
// CHECK: call void @test_i8x2(<2 x i8> <i8 32, i8 64>
Expand Down
2 changes: 1 addition & 1 deletion tests/codegen/regparm-inreg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// x86 only.

//@ add-core-stubs
//@ compile-flags: --target i686-unknown-linux-gnu -Cno-prepopulate-passes -Copt-level=3
//@ compile-flags: --target i686-unknown-linux-gnu -Cno-prepopulate-passes -Copt-level=3 -Ctarget-feature=+avx
Copy link
Member Author

Choose a reason for hiding this comment

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

@azhogin this test was using SIMD vector types without the appropriate target feature... I hope adding the target feature preserves the meaning of the test.

Copy link
Member

Choose a reason for hiding this comment

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

It does.

//@ needs-llvm-components: x86

//@ revisions:regparm0 regparm1 regparm2 regparm3
Expand Down
5 changes: 4 additions & 1 deletion tests/codegen/repr/transparent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// For LoongArch: see codegen/loongarch-abi

#![crate_type = "lib"]
#![feature(repr_simd, transparent_unions)]
#![feature(repr_simd, transparent_unions, arm_target_feature)]

use std::marker::PhantomData;

Expand Down Expand Up @@ -139,6 +139,9 @@ pub struct Vector(f32x4);

// CHECK: define{{.*}}<4 x float> @test_Vector(<4 x float> %_1)
#[no_mangle]
#[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
#[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
#[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
pub extern "C" fn test_Vector(_: Vector) -> Vector {
loop {}
}
Expand Down
Loading
Loading