about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2025-02-18 17:17:16 +0100
committerRalf Jung <post@ralfj.de>2025-02-20 12:40:58 +0100
commit83fd16f6258f3ae6fb6c8d6cf06eb4f8c654333e (patch)
tree13201e916be9e6065e1283705468ebbbdead850c /compiler
parent79b2360d985d325741e066e7b6070ed465b785df (diff)
downloadrust-83fd16f6258f3ae6fb6c8d6cf06eb4f8c654333e.tar.gz
rust-83fd16f6258f3ae6fb6c8d6cf06eb4f8c654333e.zip
vectorcall ABI: error if sse2 is not available
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_monomorphize/messages.ftl14
-rw-r--r--compiler/rustc_monomorphize/src/errors.rs13
-rw-r--r--compiler/rustc_monomorphize/src/mono_checks/abi_check.rs13
3 files changed, 38 insertions, 2 deletions
diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl
index a83c18cda0e..bdeab12ab50 100644
--- a/compiler/rustc_monomorphize/messages.ftl
+++ b/compiler/rustc_monomorphize/messages.ftl
@@ -22,6 +22,20 @@ monomorphize_abi_error_unsupported_vector_type =
     *[false] defined
   } here
 
+monomorphize_abi_required_target_feature =
+  this function {$is_call ->
+    [true] call
+    *[false] definition
+  } uses ABI "{$abi}" which requires the `{$required_feature}` target feature, which is not enabled{$is_call ->
+    [true] {" "}in the caller
+    *[false] {""}
+  }
+  .label = function {$is_call ->
+    [true] called
+    *[false] defined
+  } here
+  .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`)
+
 monomorphize_couldnt_dump_mono_stats =
     unexpected error occurred while dumping monomorphization stats: {$error}
 
diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs
index 1cfcd52b666..8dafbbca905 100644
--- a/compiler/rustc_monomorphize/src/errors.rs
+++ b/compiler/rustc_monomorphize/src/errors.rs
@@ -90,3 +90,16 @@ pub(crate) struct AbiErrorUnsupportedVectorType<'a> {
     /// Whether this is a problem at a call site or at a declaration.
     pub is_call: bool,
 }
+
+#[derive(Diagnostic)]
+#[diag(monomorphize_abi_required_target_feature)]
+#[help]
+pub(crate) struct AbiRequiredTargetFeature<'a> {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub required_feature: &'a str,
+    pub abi: &'a str,
+    /// Whether this is a problem at a call site or at a declaration.
+    pub is_call: bool,
+}
diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
index b5a7a810379..4c8dd933317 100644
--- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
+++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
@@ -29,12 +29,12 @@ fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool {
 fn do_check_abi<'tcx>(
     tcx: TyCtxt<'tcx>,
     abi: &FnAbi<'tcx, Ty<'tcx>>,
-    target_feature_def: DefId,
+    def_id: DefId,
     is_call: bool,
     span: impl Fn() -> Span,
 ) {
     let feature_def = tcx.sess.target.features_for_correct_vector_abi();
-    let codegen_attrs = tcx.codegen_fn_attrs(target_feature_def);
+    let codegen_attrs = tcx.codegen_fn_attrs(def_id);
     let have_feature = |feat: Symbol| {
         tcx.sess.unstable_target_features.contains(&feat)
             || codegen_attrs.target_features.iter().any(|x| x.name == feat)
@@ -77,6 +77,15 @@ fn do_check_abi<'tcx>(
             }
         }
     }
+    // The `vectorcall` ABI is special in that it requires SSE2 no matter which types are being passed.
+    if abi.conv == Conv::X86VectorCall && !have_feature(sym::sse2) {
+        tcx.dcx().emit_err(errors::AbiRequiredTargetFeature {
+            span: span(),
+            required_feature: "sse2",
+            abi: "vectorcall",
+            is_call,
+        });
+    }
 }
 
 /// Checks that the ABI of a given instance of a function does not contain vector-passed arguments