From 22e8f1e4e2f9a3d00339aba6a4d7ee6d1d99bf8b Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Jun 2021 15:59:08 +0900 Subject: [PATCH 01/12] Add some basic tests --- .../rfc-2574-simd-ffi/simd-ffi-aarch64.rs | 45 ++++++++++++++ .../ui/rfcs/rfc-2574-simd-ffi/simd-ffi-arm.rs | 45 ++++++++++++++ .../ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs | 59 +++++++++++++++++++ .../target-feature-on-foreign-function.rs | 14 +++++ 4 files changed, 163 insertions(+) create mode 100644 src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-aarch64.rs create mode 100644 src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-arm.rs create mode 100644 src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs create mode 100644 src/test/ui/rfcs/rfc-2574-simd-ffi/target-feature-on-foreign-function.rs diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-aarch64.rs b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-aarch64.rs new file mode 100644 index 0000000000000..87e95bb5f0d4d --- /dev/null +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-aarch64.rs @@ -0,0 +1,45 @@ +// only-aarch64 + +#![feature(repr_simd)] +#![feature(simd_ffi)] +#![allow(non_camel_case_types)] +#![cfg(target_arch = "aarch64")] + +#[repr(simd)] +struct v1024(i128, i128, i128, i128, i128, i128, i128, i128); + +extern { + fn foo(x: v1024); //~ ERROR use of SIMD type `v1024` in FFI not supported by any target features + fn bar(x: i32, y: v1024); //~ ERROR use of SIMD type `v1024` in FFI not supported by any target features + fn baz(x: i32) -> v1024; //~ ERROR use of SIMD type `v1024` in FFI not supported by any target features + + fn qux_fail(x: v64); //~ ERROR use of SIMD type `v64` in FFI requires `#[target_feature(enable = "neon")]` + #[target_feature(enable = "neon")] + fn qux(x: v64); + + fn quux_fail(x: v64i); //~ ERROR use of SIMD type `v64i` in FFI requires `#[target_feature(enable = "neon")]` + #[target_feature(enable = "neon")] + fn quux(x: v64i); + + fn quuux_fail(x: v128); //~ ERROR use of SIMD type `v128` in FFI requires `#[target_feature(enable = "neon")]` + #[target_feature(enable = "neon")] + fn quuux(x: v128); + + fn quuuux_fail(x: v128i); //~ ERROR use of SIMD type `v128i` in FFI requires `#[target_feature(enable = "neon")]` + #[target_feature(enable = "neon")] + fn quuuux(x: v128); //~ ERROR use of SIMD type `v128i` in FFI not supported by any target features +} + +fn main() {} + +#[repr(simd)] +struct v128(i32, i32, i32, i32); + +#[repr(simd)] +struct v64(i32, i32); + +#[repr(simd)] +struct v128i(i64, i64); + +#[repr(simd)] +struct v64i(i64); diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-arm.rs b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-arm.rs new file mode 100644 index 0000000000000..07c2ab5435719 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-arm.rs @@ -0,0 +1,45 @@ +// only-arm + +#![feature(repr_simd)] +#![feature(simd_ffi)] +#![allow(non_camel_case_types)] +#![cfg(target_arch = "arm")] + +#[repr(simd)] +struct v1024(i128, i128, i128, i128, i128, i128, i128, i128); + +extern { + fn foo(x: v1024); //~ ERROR use of SIMD type `v1024` in FFI not supported by any target features + fn bar(x: i32, y: v1024); //~ ERROR use of SIMD type `v1024` in FFI not supported by any target features + fn baz(x: i32) -> v1024; //~ ERROR use of SIMD type `v1024` in FFI not supported by any target features + + fn qux_fail(x: v64); //~ ERROR use of SIMD type `v64` in FFI requires `#[target_feature(enable = "neon")]` + #[target_feature(enable = "neon")] + fn qux(x: v64); + + fn quux_fail(x: v64i); //~ ERROR use of SIMD type `v64i` in FFI not supported by any target features + #[target_feature(enable = "neon")] + fn quux_fail2(x: v64i); //~ ERROR use of SIMD type `v64i` in FFI not supported by any target features + + fn quuux_fail(x: v128); //~ ERROR use of SIMD type `v128` in FFI requires `#[target_feature(enable = "neon")]` + #[target_feature(enable = "neon")] + fn quuux(x: v128); + + fn quuuux_fail(x: v128i); //~ ERROR use of SIMD type `v128i` in FFI not supported by any target features + #[target_feature(enable = "neon")] + fn quuuux_fail2(x: v128i); //~ ERROR use of SIMD type `v128i` in FFI not supported by any target features +} + +fn main() {} + +#[repr(simd)] +struct v128(i32, i32, i32, i32); + +#[repr(simd)] +struct v64(i32, i32); + +#[repr(simd)] +struct v128i(i64, i64); + +#[repr(simd)] +struct v64i(i64); diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs new file mode 100644 index 0000000000000..8cf83cfcec5fd --- /dev/null +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs @@ -0,0 +1,59 @@ +// only-x86 + +#![feature(repr_simd)] +#![feature(simd_ffi)] +#![feature(avx512_target_feature)] +#![allow(non_camel_case_types)] +#![cfg(any(target_arch = "x86", target_arch = "x86_64"))] + +#[repr(simd)] +struct v1024(i128, i128, i128, i128, i128, i128, i128, i128); + +extern { + fn foo(x: v1024); //~ ERROR use of SIMD type `v1024` in FFI not supported by any target features + fn bar(x: i32, y: v1024); //~ ERROR use of SIMD type `v1024` in FFI not supported by any target features + fn baz(x: i32) -> v1024; //~ ERROR use of SIMD type `v1024` in FFI not supported by any target features + + fn qux_fail(x: v128); //~ ERROR use of SIMD type `v128` in FFI requires `#[target_feature(enable = "sse")]` + #[target_feature(enable = "sse")] + fn qux(x: v128); + #[target_feature(enable = "sse4.2")] + fn qux2(x: v128); + #[target_feature(enable = "ssse3")] + fn qux3(x: v128); + #[target_feature(enable = "avx")] + fn qux4(x: v128); + #[target_feature(enable = "avx2")] + fn qux5(x: v128); + #[target_feature(enable = "avx512f")] + fn qux6(x: v128); + + fn quux_fail(x: v256); //~ ERROR use of SIMD type `v256` in FFI requires `#[target_feature(enable = "avx")]` + #[target_feature(enable = "sse4.2")] + fn quux_fail2(x: v256); //~ ERROR use of SIMD type `v256` in FFI requires `#[target_feature(enable = "avx")]` + #[target_feature(enable = "avx")] + fn quux(x: v256); + #[target_feature(enable = "avx2")] + fn quux2(x: v256); + #[target_feature(enable = "avx512f")] + fn quux3(x: v256); + + fn quuux_fail(x: v512); //~ ERROR use of SIMD type `v512` in FFI requires `#[target_feature(enable = "avx512f")]` + #[target_feature(enable = "sse")] + fn quuux_fail2(x: v512); //~ ERROR use of SIMD type `v512` in FFI requires `#[target_feature(enable = "avx512f")]` + #[target_feature(enable = "avx2")] + fn quuux_fail3(x: v512); //~ ERROR use of SIMD type `v512` in FFI requires `#[target_feature(enable = "avx512f")]` + #[target_feature(enable = "avx512f")] + fn quuux(x: v512); +} + +fn main() {} + +#[repr(simd)] +struct v128(i128); + +#[repr(simd)] +struct v256(i128, i128); + +#[repr(simd)] +struct v512(i128, i128, i128, i128); diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/target-feature-on-foreign-function.rs b/src/test/ui/rfcs/rfc-2574-simd-ffi/target-feature-on-foreign-function.rs new file mode 100644 index 0000000000000..99a29bdbba9d6 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/target-feature-on-foreign-function.rs @@ -0,0 +1,14 @@ +// only-x86 +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +pub unsafe fn bar() { foo() } + +extern "C" { + // CHECK-LABEL: declare void @foo() + // CHECK-SAME: [[ATTRS:#[0-9]+]] + // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}"target-features"="+avx2"{{.*}} } + #[target_feature(enable = "avx2")] + pub fn foo(); +} From 4a22c0a8db1faecd258d9f706e19537eb06e441f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Jun 2021 16:07:57 +0900 Subject: [PATCH 02/12] Allow to apply `#[target_fature]` to foreign items --- compiler/rustc_passes/src/check_attr.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 71231830e99a7..a3487f20c4f4c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -368,11 +368,17 @@ impl CheckAttrVisitor<'tcx> { match target { Target::Fn | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, + + // Allow foreign items for SIMD FFI. + Target::ForeignFn | Target::ForeignMod | Target::ForeignTy | Target::ForeignStatic => { + true + } + // FIXME: #[target_feature] was previously erroneously allowed on statements and some // crates used this, so only emit a warning. Target::Statement => { self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { - lint.build("attribute should be applied to a function") + lint.build("`#[target_feature]` attribute should be applied to a function") .warn( "this was previously accepted by the compiler but is \ being phased out; it will become a hard error in \ @@ -394,7 +400,10 @@ impl CheckAttrVisitor<'tcx> { _ => { self.tcx .sess - .struct_span_err(attr.span, "attribute should be applied to a function") + .struct_span_err( + attr.span, + "`#[target_feature]` attribute should be applied to a function", + ) .span_label(*span, "not a function") .emit(); false From f3870304608abb79726a003493a39bb824ca62d1 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Jun 2021 16:45:01 +0900 Subject: [PATCH 03/12] Implement SIMD FFI checks --- compiler/rustc_typeck/src/collect.rs | 200 +++++++++++++++--- .../ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs | 2 +- .../rfc-2574-simd-ffi/simd-ffi-x86.stderr | 27 +++ .../target-feature-on-foreign-function.rs | 5 +- 4 files changed, 203 insertions(+), 31 deletions(-) create mode 100644 src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.stderr diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 1a4c2eb515584..f6a6ea3e10d2f 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2479,43 +2479,187 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( None, ); - // Feature gate SIMD types in FFI, since I am not sure that the - // ABIs are handled at all correctly. -huonw - if abi != abi::Abi::RustIntrinsic - && abi != abi::Abi::PlatformIntrinsic - && !tcx.features().simd_ffi - { - let check = |ast_ty: &hir::Ty<'_>, ty: Ty<'_>| { - if ty.is_simd() { - let snip = tcx - .sess - .source_map() - .span_to_snippet(ast_ty.span) - .map_or_else(|_| String::new(), |s| format!(" `{}`", s)); - tcx.sess - .struct_span_err( - ast_ty.span, - &format!( - "use of SIMD type{} in FFI is highly experimental and \ - may result in invalid code", - snip - ), - ) - .help("add `#![feature(simd_ffi)]` to the crate attributes to enable") - .emit(); - } - }; + // Using SIMD types in FFI signatures requires the signature + // to have appropriate `#[target_feature]`'s enabled. + if abi != abi::Abi::RustIntrinsic && abi != abi::Abi::PlatformIntrinsic { for (input, ty) in iter::zip(decl.inputs, fty.inputs().skip_binder()) { - check(&input, ty) + simd_ffi_check(tcx, def_id, &input, ty) } if let hir::FnRetTy::Return(ref ty) = decl.output { - check(&ty, fty.output().skip_binder()) + simd_ffi_check(tcx, def_id, &ty, fty.output().skip_binder()) } } fty } +/// Returns `Ok()` if the target-feature allows using the SIMD type on C FFI. +/// Otherwise, returns `Err(Some())` if the target_feature needs to be enabled or +/// or `Err(None)` if it's unsupported. +fn simd_ffi_feature_check( + target: &str, + simd_width: u64, + simd_elem_width: u64, + feature: String, +) -> Result<(), Option<&'static str>> { + match target { + t if t.contains("x86") => { + // FIXME: this needs to be architecture dependent and + // should probably belong somewhere else: + // * on mips: 16 => msa, + // * wasm: 16 => simd128 + match simd_width { + 8 if feature.contains("mmx") + || feature.contains("sse") + || feature.contains("ssse") + || feature.contains("avx") => + { + Ok(()) + } + 8 => Err(Some("mmx")), + 16 if feature.contains("sse") + || feature.contains("ssse") + || feature.contains("avx") => + { + Ok(()) + } + 16 => Err(Some("sse")), + 32 if feature.contains("avx") => Ok(()), + 32 => Err(Some("avx")), + 64 if feature.contains("avx512") => Ok(()), + 64 => Err(Some("acx512")), + _ => Err(None), + } + } + t if t.contains("arm") => { + match simd_width { + // 32-bit arm does not support vectors with 64-bit wide elements + 8 | 16 if simd_elem_width < 8 => { + if feature.contains("neon") { + Ok(()) + } else { + Err(Some("neon")) + } + } + _ => Err(None), + } + } + t if t.contains("aarch64") => match simd_width { + 8 | 16 => { + if feature.contains("neon") { + Ok(()) + } else { + Err(Some("neon")) + } + } + _ => Err(None), + }, + t if t.contains("powerpc") => { + match simd_width { + // 64-bit wide elements are only available in VSX: + 16 if simd_elem_width == 8 => { + if feature.contains("vsx") { + Ok(()) + } else { + Err(Some("vsx")) + } + } + 16 if simd_elem_width < 8 => { + if feature.contains("altivec") { + Ok(()) + } else { + Err(Some("altivec")) + } + } + _ => Err(None), + } + } + t if t.contains("mips") => match simd_width { + 16 => { + if feature.contains("msa") { + Ok(()) + } else { + Err(Some("msa")) + } + } + _ => Err(None), + }, + _ => Err(None), + } +} + +fn simd_ffi_check<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, + ast_ty: &hir::Ty<'_>, + ty: Ty<'tcx>, +) { + if !ty.is_simd() { + return; + } + + // The use of SIMD types in FFI is feature-gated: + if !tcx.features().simd_ffi { + tcx.sess + .struct_span_err( + ast_ty.span, + &format!( + "use of SIMD type `{}` in FFI is unstable", + tcx.hir().node_to_string(ast_ty.hir_id) + ), + ) + .help("add #![feature(simd_ffi)] to the crate attributes to enable") + .emit(); + return; + } + + // If rustdoc, then we don't type check SIMD on FFI because rustdoc requires + // being able to compile a target, with features of other targets enabled + // (e.g. `x86+neon`, yikes). + if tcx.sess.opts.actually_rustdoc { + return; + } + + let attrs = tcx.codegen_fn_attrs(def_id); + + // Skip LLVM intrinsics. + if let Some(link_name) = attrs.link_name { + if link_name.to_ident_string().starts_with("llvm.") { + return; + } + } + + let features = &attrs.target_features; + let simd_len = tcx + .layout_of(ty::ParamEnvAnd { param_env: ty::ParamEnv::empty(), value: ty }) + .unwrap() + .layout + .size + .bytes(); + let (simd_size, _) = ty.simd_size_and_type(tcx); + let simd_elem_width = simd_len / simd_size; + let target: &str = &tcx.sess.target.arch; + + for f in features { + if let Err(v) = simd_ffi_feature_check(target, simd_len, simd_elem_width, f.to_ident_string()) { + let type_str = tcx.hir().node_to_string(ast_ty.hir_id); + let msg = if let Some(f) = v { + format!( + "use of SIMD type `{}` in FFI requires `#[target_feature(enable = \"{}\")]`", + type_str, f, + ) + } else { + format!( + "use of SIMD type `{}` in FFI not supported by any target features", + type_str + ) + }; + tcx.sess.struct_span_err(ast_ty.span, &msg).emit(); + return; + } + } +} + fn is_foreign_item(tcx: TyCtxt<'_>, def_id: DefId) -> bool { match tcx.hir().get_if_local(def_id) { Some(Node::ForeignItem(..)) => true, diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs index 8cf83cfcec5fd..b9a74dbd64be2 100644 --- a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs @@ -1,4 +1,4 @@ -// only-x86 +// only-x86_64 #![feature(repr_simd)] #![feature(simd_ffi)] diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.stderr b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.stderr new file mode 100644 index 0000000000000..5b3f1f435871d --- /dev/null +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.stderr @@ -0,0 +1,27 @@ +error[E0391]: cycle detected when computing codegen attributes of `qux` + --> $DIR/simd-ffi-x86.rs:19:5 + | +LL | fn qux(x: v128); + | ^^^^^^^^^^^^^^^^ + | +note: ...which requires computing function signature of `qux`... + --> $DIR/simd-ffi-x86.rs:19:5 + | +LL | fn qux(x: v128); + | ^^^^^^^^^^^^^^^^ + = note: ...which again requires computing codegen attributes of `qux`, completing the cycle +note: cycle used when checking attributes in top-level module + --> $DIR/simd-ffi-x86.rs:3:1 + | +LL | / #![feature(repr_simd)] +LL | | #![feature(simd_ffi)] +LL | | #![feature(avx512_target_feature)] +LL | | #![allow(non_camel_case_types)] +... | +LL | | #[repr(simd)] +LL | | struct v512(i128, i128, i128, i128); + | |____________________________________^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/target-feature-on-foreign-function.rs b/src/test/ui/rfcs/rfc-2574-simd-ffi/target-feature-on-foreign-function.rs index 99a29bdbba9d6..04a66c2d28276 100644 --- a/src/test/ui/rfcs/rfc-2574-simd-ffi/target-feature-on-foreign-function.rs +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/target-feature-on-foreign-function.rs @@ -1,5 +1,6 @@ -// only-x86 -// compile-flags: -C no-prepopulate-passes +// only-x86_64 +// run-pass +// compile-flags: -C no-prepopulate-passes -C passes=name-anon-globals #![crate_type = "lib"] From d5471a733da881db84c8aa8ce2c6266452e50c75 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Jun 2021 18:09:38 +0900 Subject: [PATCH 04/12] Fix feature gate check --- compiler/rustc_typeck/src/collect.rs | 15 ++++++++--- .../simd-ffi-feature-gate.rs | 17 ++++++++++++ .../simd-ffi-feature-gate.stderr | 26 +++++++++++++++++++ .../target-feature-on-foreign-function.rs | 15 ----------- 4 files changed, 55 insertions(+), 18 deletions(-) create mode 100644 src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-feature-gate.rs create mode 100644 src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-feature-gate.stderr delete mode 100644 src/test/ui/rfcs/rfc-2574-simd-ffi/target-feature-on-foreign-function.rs diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index f6a6ea3e10d2f..2f9631338d39a 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2600,15 +2600,20 @@ fn simd_ffi_check<'tcx>( // The use of SIMD types in FFI is feature-gated: if !tcx.features().simd_ffi { + let snip = tcx + .sess + .source_map() + .span_to_snippet(ast_ty.span) + .map_or_else(|_| String::new(), |s| format!("{}", s)); tcx.sess .struct_span_err( ast_ty.span, &format!( "use of SIMD type `{}` in FFI is unstable", - tcx.hir().node_to_string(ast_ty.hir_id) + snip ), ) - .help("add #![feature(simd_ffi)] to the crate attributes to enable") + .help("add `#![feature(simd_ffi)]` to the crate attributes to enable") .emit(); return; } @@ -2642,7 +2647,11 @@ fn simd_ffi_check<'tcx>( for f in features { if let Err(v) = simd_ffi_feature_check(target, simd_len, simd_elem_width, f.to_ident_string()) { - let type_str = tcx.hir().node_to_string(ast_ty.hir_id); + let type_str = tcx + .sess + .source_map() + .span_to_snippet(ast_ty.span) + .map_or_else(|_| String::new(), |s| format!("{}", s)); let msg = if let Some(f) = v { format!( "use of SIMD type `{}` in FFI requires `#[target_feature(enable = \"{}\")]`", diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-feature-gate.rs b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-feature-gate.rs new file mode 100644 index 0000000000000..460dd5e95e0f8 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-feature-gate.rs @@ -0,0 +1,17 @@ +// only-x86_64 + +#![feature(repr_simd)] +#![feature(avx512_target_feature)] +#![allow(non_camel_case_types)] +#![cfg(any(target_arch = "x86", target_arch = "x86_64"))] + +#[repr(simd)] +struct v128(i128); + +extern { + fn foo(x: v128); //~ ERROR use of SIMD type `v128` in FFI is unstable + fn bar(x: i32, y: v128); //~ ERROR use of SIMD type `v128` in FFI is unstable + fn baz(x: i32) -> v128; //~ ERROR use of SIMD type `v128` in FFI is unstable +} + +fn main() {} diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-feature-gate.stderr b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-feature-gate.stderr new file mode 100644 index 0000000000000..e6fd2bfce71ec --- /dev/null +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-feature-gate.stderr @@ -0,0 +1,26 @@ +error: use of SIMD type `v128` in FFI is unstable + --> $DIR/simd-ffi-feature-gate.rs:12:15 + | +LL | fn foo(x: v128); + | ^^^^ + | + = help: add `#![feature(simd_ffi)]` to the crate attributes to enable + +error: use of SIMD type `v128` in FFI is unstable + --> $DIR/simd-ffi-feature-gate.rs:13:23 + | +LL | fn bar(x: i32, y: v128); + | ^^^^ + | + = help: add `#![feature(simd_ffi)]` to the crate attributes to enable + +error: use of SIMD type `v128` in FFI is unstable + --> $DIR/simd-ffi-feature-gate.rs:14:23 + | +LL | fn baz(x: i32) -> v128; + | ^^^^ + | + = help: add `#![feature(simd_ffi)]` to the crate attributes to enable + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/target-feature-on-foreign-function.rs b/src/test/ui/rfcs/rfc-2574-simd-ffi/target-feature-on-foreign-function.rs deleted file mode 100644 index 04a66c2d28276..0000000000000 --- a/src/test/ui/rfcs/rfc-2574-simd-ffi/target-feature-on-foreign-function.rs +++ /dev/null @@ -1,15 +0,0 @@ -// only-x86_64 -// run-pass -// compile-flags: -C no-prepopulate-passes -C passes=name-anon-globals - -#![crate_type = "lib"] - -pub unsafe fn bar() { foo() } - -extern "C" { - // CHECK-LABEL: declare void @foo() - // CHECK-SAME: [[ATTRS:#[0-9]+]] - // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}"target-features"="+avx2"{{.*}} } - #[target_feature(enable = "avx2")] - pub fn foo(); -} From 4702a9aa4593b05bd0f7c33cffe6cf987d478144 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Jun 2021 18:14:40 +0900 Subject: [PATCH 05/12] Only allow foreign functions for SIMD FFI --- compiler/rustc_passes/src/check_attr.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a3487f20c4f4c..704d02eb72f5a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -369,10 +369,8 @@ impl CheckAttrVisitor<'tcx> { Target::Fn | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, - // Allow foreign items for SIMD FFI. - Target::ForeignFn | Target::ForeignMod | Target::ForeignTy | Target::ForeignStatic => { - true - } + // Allow foreign functions for SIMD FFI. + Target::ForeignFn => true, // FIXME: #[target_feature] was previously erroneously allowed on statements and some // crates used this, so only emit a warning. From ad103228f94b4d145374447d430e889f4517b4dd Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Jun 2021 18:25:24 +0900 Subject: [PATCH 06/12] Fix cycle error --- compiler/rustc_typeck/src/collect.rs | 37 +++++++++---------- .../ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs | 2 +- .../rfc-2574-simd-ffi/simd-ffi-x86.stderr | 37 ++++++++----------- 3 files changed, 33 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 2f9631338d39a..a589d32127f4e 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2588,12 +2588,7 @@ fn simd_ffi_feature_check( } } -fn simd_ffi_check<'tcx>( - tcx: TyCtxt<'tcx>, - def_id: DefId, - ast_ty: &hir::Ty<'_>, - ty: Ty<'tcx>, -) { +fn simd_ffi_check<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ast_ty: &hir::Ty<'_>, ty: Ty<'tcx>) { if !ty.is_simd() { return; } @@ -2601,17 +2596,14 @@ fn simd_ffi_check<'tcx>( // The use of SIMD types in FFI is feature-gated: if !tcx.features().simd_ffi { let snip = tcx - .sess - .source_map() - .span_to_snippet(ast_ty.span) - .map_or_else(|_| String::new(), |s| format!("{}", s)); + .sess + .source_map() + .span_to_snippet(ast_ty.span) + .map_or_else(|_| String::new(), |s| format!("{}", s)); tcx.sess .struct_span_err( ast_ty.span, - &format!( - "use of SIMD type `{}` in FFI is unstable", - snip - ), + &format!("use of SIMD type `{}` in FFI is unstable", snip), ) .help("add `#![feature(simd_ffi)]` to the crate attributes to enable") .emit(); @@ -2646,12 +2638,14 @@ fn simd_ffi_check<'tcx>( let target: &str = &tcx.sess.target.arch; for f in features { - if let Err(v) = simd_ffi_feature_check(target, simd_len, simd_elem_width, f.to_ident_string()) { + if let Err(v) = + simd_ffi_feature_check(target, simd_len, simd_elem_width, f.to_ident_string()) + { let type_str = tcx - .sess - .source_map() - .span_to_snippet(ast_ty.span) - .map_or_else(|_| String::new(), |s| format!("{}", s)); + .sess + .source_map() + .span_to_snippet(ast_ty.span) + .map_or_else(|_| String::new(), |s| format!("{}", s)); let msg = if let Some(f) = v { format!( "use of SIMD type `{}` in FFI requires `#[target_feature(enable = \"{}\")]`", @@ -2952,7 +2946,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { codegen_fn_attrs.export_name = Some(s); } } else if tcx.sess.check_name(attr, sym::target_feature) { - if !tcx.is_closure(id) && tcx.fn_sig(id).unsafety() == hir::Unsafety::Normal { + if !tcx.is_closure(id) + && !tcx.is_foreign_item(id) + && tcx.fn_sig(id).unsafety() == hir::Unsafety::Normal + { if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc { // The `#[target_feature]` attribute is allowed on // WebAssembly targets on all functions, including safe diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs index b9a74dbd64be2..092e0b7c057d2 100644 --- a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs @@ -3,7 +3,7 @@ #![feature(repr_simd)] #![feature(simd_ffi)] #![feature(avx512_target_feature)] -#![allow(non_camel_case_types)] +#![allow(non_camel_case_types, improper_ctypes)] #![cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[repr(simd)] diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.stderr b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.stderr index 5b3f1f435871d..4da5fc9163b09 100644 --- a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.stderr +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.stderr @@ -1,27 +1,20 @@ -error[E0391]: cycle detected when computing codegen attributes of `qux` - --> $DIR/simd-ffi-x86.rs:19:5 +error: use of SIMD type `v256` in FFI requires `#[target_feature(enable = "avx")]` + --> $DIR/simd-ffi-x86.rs:33:22 | -LL | fn qux(x: v128); - | ^^^^^^^^^^^^^^^^ - | -note: ...which requires computing function signature of `qux`... - --> $DIR/simd-ffi-x86.rs:19:5 +LL | fn quux_fail2(x: v256); + | ^^^^ + +error: use of SIMD type `v512` in FFI requires `#[target_feature(enable = "acx512")]` + --> $DIR/simd-ffi-x86.rs:43:23 | -LL | fn qux(x: v128); - | ^^^^^^^^^^^^^^^^ - = note: ...which again requires computing codegen attributes of `qux`, completing the cycle -note: cycle used when checking attributes in top-level module - --> $DIR/simd-ffi-x86.rs:3:1 +LL | fn quuux_fail2(x: v512); + | ^^^^ + +error: use of SIMD type `v512` in FFI requires `#[target_feature(enable = "acx512")]` + --> $DIR/simd-ffi-x86.rs:45:23 | -LL | / #![feature(repr_simd)] -LL | | #![feature(simd_ffi)] -LL | | #![feature(avx512_target_feature)] -LL | | #![allow(non_camel_case_types)] -... | -LL | | #[repr(simd)] -LL | | struct v512(i128, i128, i128, i128); - | |____________________________________^ +LL | fn quuux_fail3(x: v512); + | ^^^^ -error: aborting due to previous error +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0391`. From d617ed4ac30d6103b1cf1410a2aa807d72f9b757 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Jun 2021 19:54:07 +0900 Subject: [PATCH 07/12] Catch incorrect uses of SIMD vectors --- compiler/rustc_typeck/src/collect.rs | 33 +++++++++++---- .../ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs | 25 +++++------ .../rfc-2574-simd-ffi/simd-ffi-x86.stderr | 42 +++++++++++++++++-- 3 files changed, 77 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index a589d32127f4e..71057d35eae5f 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2500,8 +2500,9 @@ fn simd_ffi_feature_check( target: &str, simd_width: u64, simd_elem_width: u64, - feature: String, + feature: Option, ) -> Result<(), Option<&'static str>> { + let feature = feature.unwrap_or_default(); match target { t if t.contains("x86") => { // FIXME: this needs to be architecture dependent and @@ -2527,7 +2528,7 @@ fn simd_ffi_feature_check( 32 if feature.contains("avx") => Ok(()), 32 => Err(Some("avx")), 64 if feature.contains("avx512") => Ok(()), - 64 => Err(Some("acx512")), + 64 => Err(Some("avx512")), _ => Err(None), } } @@ -2637,15 +2638,31 @@ fn simd_ffi_check<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ast_ty: &hir::Ty<'_>, let simd_elem_width = simd_len / simd_size; let target: &str = &tcx.sess.target.arch; + let type_str = tcx + .sess + .source_map() + .span_to_snippet(ast_ty.span) + .map_or_else(|_| String::new(), |s| format!("{}", s)); + + if features.is_empty() { + // Should **NOT** be `Ok()`. + let f = simd_ffi_feature_check(target, simd_len, simd_elem_width, None).unwrap_err(); + let msg = if let Some(f) = f { + format!( + "use of SIMD type `{}` in FFI requires `#[target_feature(enable = \"{}\")]`", + type_str, f, + ) + } else { + format!("use of SIMD type `{}` in FFI not supported by any target features", type_str) + }; + + tcx.sess.struct_span_err(ast_ty.span, &msg).emit(); + } + for f in features { if let Err(v) = - simd_ffi_feature_check(target, simd_len, simd_elem_width, f.to_ident_string()) + simd_ffi_feature_check(target, simd_len, simd_elem_width, Some(f.to_ident_string())) { - let type_str = tcx - .sess - .source_map() - .span_to_snippet(ast_ty.span) - .map_or_else(|_| String::new(), |s| format!("{}", s)); let msg = if let Some(f) = v { format!( "use of SIMD type `{}` in FFI requires `#[target_feature(enable = \"{}\")]`", diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs index 092e0b7c057d2..307ae79c2f339 100644 --- a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.rs @@ -1,3 +1,4 @@ +// only-x86 // only-x86_64 #![feature(repr_simd)] @@ -6,6 +7,15 @@ #![allow(non_camel_case_types, improper_ctypes)] #![cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[repr(simd)] +struct v128(i128); + +#[repr(simd)] +struct v256(i128, i128); + +#[repr(simd)] +struct v512(i128, i128, i128, i128); + #[repr(simd)] struct v1024(i128, i128, i128, i128, i128, i128, i128, i128); @@ -38,22 +48,13 @@ extern { #[target_feature(enable = "avx512f")] fn quux3(x: v256); - fn quuux_fail(x: v512); //~ ERROR use of SIMD type `v512` in FFI requires `#[target_feature(enable = "avx512f")]` + fn quuux_fail(x: v512); //~ ERROR use of SIMD type `v512` in FFI requires `#[target_feature(enable = "avx512")]` #[target_feature(enable = "sse")] - fn quuux_fail2(x: v512); //~ ERROR use of SIMD type `v512` in FFI requires `#[target_feature(enable = "avx512f")]` + fn quuux_fail2(x: v512); //~ ERROR use of SIMD type `v512` in FFI requires `#[target_feature(enable = "avx512")]` #[target_feature(enable = "avx2")] - fn quuux_fail3(x: v512); //~ ERROR use of SIMD type `v512` in FFI requires `#[target_feature(enable = "avx512f")]` + fn quuux_fail3(x: v512); //~ ERROR use of SIMD type `v512` in FFI requires `#[target_feature(enable = "avx512")]` #[target_feature(enable = "avx512f")] fn quuux(x: v512); } fn main() {} - -#[repr(simd)] -struct v128(i128); - -#[repr(simd)] -struct v256(i128, i128); - -#[repr(simd)] -struct v512(i128, i128, i128, i128); diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.stderr b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.stderr index 4da5fc9163b09..2c204b5e01ff9 100644 --- a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.stderr +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-x86.stderr @@ -1,20 +1,56 @@ +error: use of SIMD type `v1024` in FFI not supported by any target features + --> $DIR/simd-ffi-x86.rs:13:15 + | +LL | fn foo(x: v1024); + | ^^^^^ + +error: use of SIMD type `v1024` in FFI not supported by any target features + --> $DIR/simd-ffi-x86.rs:14:23 + | +LL | fn bar(x: i32, y: v1024); + | ^^^^^ + +error: use of SIMD type `v1024` in FFI not supported by any target features + --> $DIR/simd-ffi-x86.rs:15:23 + | +LL | fn baz(x: i32) -> v1024; + | ^^^^^ + +error: use of SIMD type `v128` in FFI requires `#[target_feature(enable = "sse")]` + --> $DIR/simd-ffi-x86.rs:17:20 + | +LL | fn qux_fail(x: v128); + | ^^^^ + +error: use of SIMD type `v256` in FFI requires `#[target_feature(enable = "avx")]` + --> $DIR/simd-ffi-x86.rs:31:21 + | +LL | fn quux_fail(x: v256); + | ^^^^ + error: use of SIMD type `v256` in FFI requires `#[target_feature(enable = "avx")]` --> $DIR/simd-ffi-x86.rs:33:22 | LL | fn quux_fail2(x: v256); | ^^^^ -error: use of SIMD type `v512` in FFI requires `#[target_feature(enable = "acx512")]` +error: use of SIMD type `v512` in FFI requires `#[target_feature(enable = "avx512")]` + --> $DIR/simd-ffi-x86.rs:41:22 + | +LL | fn quuux_fail(x: v512); + | ^^^^ + +error: use of SIMD type `v512` in FFI requires `#[target_feature(enable = "avx512")]` --> $DIR/simd-ffi-x86.rs:43:23 | LL | fn quuux_fail2(x: v512); | ^^^^ -error: use of SIMD type `v512` in FFI requires `#[target_feature(enable = "acx512")]` +error: use of SIMD type `v512` in FFI requires `#[target_feature(enable = "avx512")]` --> $DIR/simd-ffi-x86.rs:45:23 | LL | fn quuux_fail3(x: v512); | ^^^^ -error: aborting due to 3 previous errors +error: aborting due to 9 previous errors From 79ac2dce8f3ade99f037752bb37bb479fcf205f1 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Jun 2021 20:02:25 +0900 Subject: [PATCH 08/12] Add FXIME test --- .../simd-ffi-incorrect-type-use.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-incorrect-type-use.rs diff --git a/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-incorrect-type-use.rs b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-incorrect-type-use.rs new file mode 100644 index 0000000000000..d715d61c89fb9 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2574-simd-ffi/simd-ffi-incorrect-type-use.rs @@ -0,0 +1,20 @@ +// only-x86_64 +// check-pass <- FIXME, see the below comment. + +// The current stable rustc accepts this but it should fail. + +#![allow(improper_ctypes, improper_ctypes_definitions)] + +use std::arch::x86_64::__m128; + +extern "C" { + pub fn a(x: A); + pub fn b(x: B); +} + +#[repr(transparent)] pub struct A(__m128); +#[repr(C)] pub struct B(__m128); + +pub extern "C" fn foo(x: __m128) -> __m128 { x } + +fn main() {} From 23604466b795e15256c3d5ca383a7dca86963a32 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Jun 2021 20:11:14 +0900 Subject: [PATCH 09/12] Bless tests --- src/test/ui/attributes/multiple-invalid.stderr | 2 +- .../feature-gates/feature-gate-simd-ffi.stderr | 4 ++-- src/test/ui/macros/issue-68060.stderr | 2 +- .../ui/target-feature/invalid-attribute.stderr | 16 ++++++++-------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/test/ui/attributes/multiple-invalid.stderr b/src/test/ui/attributes/multiple-invalid.stderr index 9bd29f15dbcca..07502c077affc 100644 --- a/src/test/ui/attributes/multiple-invalid.stderr +++ b/src/test/ui/attributes/multiple-invalid.stderr @@ -7,7 +7,7 @@ LL | #[inline] LL | const FOO: u8 = 0; | ------------------ not a function or closure -error: attribute should be applied to a function +error: `#[target_feature]` attribute should be applied to a function --> $DIR/multiple-invalid.rs:6:1 | LL | #[target_feature(enable = "sse2")] diff --git a/src/test/ui/feature-gates/feature-gate-simd-ffi.stderr b/src/test/ui/feature-gates/feature-gate-simd-ffi.stderr index 8166b6baa286a..b5b48098b2dcd 100644 --- a/src/test/ui/feature-gates/feature-gate-simd-ffi.stderr +++ b/src/test/ui/feature-gates/feature-gate-simd-ffi.stderr @@ -1,4 +1,4 @@ -error: use of SIMD type `LocalSimd` in FFI is highly experimental and may result in invalid code +error: use of SIMD type `LocalSimd` in FFI is unstable --> $DIR/feature-gate-simd-ffi.rs:9:17 | LL | fn baz() -> LocalSimd; @@ -6,7 +6,7 @@ LL | fn baz() -> LocalSimd; | = help: add `#![feature(simd_ffi)]` to the crate attributes to enable -error: use of SIMD type `LocalSimd` in FFI is highly experimental and may result in invalid code +error: use of SIMD type `LocalSimd` in FFI is unstable --> $DIR/feature-gate-simd-ffi.rs:10:15 | LL | fn qux(x: LocalSimd); diff --git a/src/test/ui/macros/issue-68060.stderr b/src/test/ui/macros/issue-68060.stderr index 1b58cf9c4ede5..4a50883849f4f 100644 --- a/src/test/ui/macros/issue-68060.stderr +++ b/src/test/ui/macros/issue-68060.stderr @@ -1,4 +1,4 @@ -error: attribute should be applied to a function +error: `#[target_feature]` attribute should be applied to a function --> $DIR/issue-68060.rs:4:13 | LL | #[target_feature(enable = "")] diff --git a/src/test/ui/target-feature/invalid-attribute.stderr b/src/test/ui/target-feature/invalid-attribute.stderr index 8c8e24ccc55cc..04d6e5c40e1e2 100644 --- a/src/test/ui/target-feature/invalid-attribute.stderr +++ b/src/test/ui/target-feature/invalid-attribute.stderr @@ -34,7 +34,7 @@ LL | fn bar() {} = note: see issue #69098 for more information = help: add `#![feature(target_feature_11)]` to the crate attributes to enable -error: attribute should be applied to a function +error: `#[target_feature]` attribute should be applied to a function --> $DIR/invalid-attribute.rs:35:1 | LL | #[target_feature(enable = "sse2")] @@ -43,7 +43,7 @@ LL | LL | mod another {} | -------------- not a function -error: attribute should be applied to a function +error: `#[target_feature]` attribute should be applied to a function --> $DIR/invalid-attribute.rs:40:1 | LL | #[target_feature(enable = "sse2")] @@ -52,7 +52,7 @@ LL | LL | const FOO: usize = 7; | --------------------- not a function -error: attribute should be applied to a function +error: `#[target_feature]` attribute should be applied to a function --> $DIR/invalid-attribute.rs:45:1 | LL | #[target_feature(enable = "sse2")] @@ -61,7 +61,7 @@ LL | LL | struct Foo; | ----------- not a function -error: attribute should be applied to a function +error: `#[target_feature]` attribute should be applied to a function --> $DIR/invalid-attribute.rs:50:1 | LL | #[target_feature(enable = "sse2")] @@ -70,7 +70,7 @@ LL | LL | enum Bar {} | ----------- not a function -error: attribute should be applied to a function +error: `#[target_feature]` attribute should be applied to a function --> $DIR/invalid-attribute.rs:55:1 | LL | #[target_feature(enable = "sse2")] @@ -83,7 +83,7 @@ LL | | f2: u16, LL | | } | |_- not a function -error: attribute should be applied to a function +error: `#[target_feature]` attribute should be applied to a function --> $DIR/invalid-attribute.rs:63:1 | LL | #[target_feature(enable = "sse2")] @@ -98,7 +98,7 @@ error: cannot use `#[inline(always)]` with `#[target_feature]` LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ -error: attribute should be applied to a function +error: `#[target_feature]` attribute should be applied to a function --> $DIR/invalid-attribute.rs:86:5 | LL | #[target_feature(enable = "sse2")] @@ -110,7 +110,7 @@ LL | | bar(); LL | | } | |_____- not a function -error: attribute should be applied to a function +error: `#[target_feature]` attribute should be applied to a function --> $DIR/invalid-attribute.rs:94:5 | LL | #[target_feature(enable = "sse2")] From 564779c7d17441dab09b0bff9b197707fe828770 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 29 Jun 2021 07:54:01 +0900 Subject: [PATCH 10/12] Fix a test --- src/test/run-make-fulldeps/simd-ffi/simd.rs | 37 +++++++++++---------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/test/run-make-fulldeps/simd-ffi/simd.rs b/src/test/run-make-fulldeps/simd-ffi/simd.rs index d11cfd77c5bf9..69b2678271564 100644 --- a/src/test/run-make-fulldeps/simd-ffi/simd.rs +++ b/src/test/run-make-fulldeps/simd-ffi/simd.rs @@ -4,53 +4,56 @@ // cross-compiled standard libraries. #![feature(no_core, auto_traits)] #![no_core] -#![feature(repr_simd, simd_ffi, link_llvm_intrinsics, lang_items, rustc_attrs)] +#![feature( + mips_target_feature, + repr_simd, + simd_ffi, + link_llvm_intrinsics, + lang_items, + rustc_attrs +)] #[derive(Copy)] #[repr(simd)] -pub struct f32x4(f32, f32, f32, f32); +pub struct F32x4(f32, f32, f32, f32); extern "C" { #[link_name = "llvm.sqrt.v4f32"] - fn vsqrt(x: f32x4) -> f32x4; + fn vsqrt(x: F32x4) -> F32x4; } -pub fn foo(x: f32x4) -> f32x4 { +pub fn foo(x: F32x4) -> F32x4 { unsafe { vsqrt(x) } } #[derive(Copy)] #[repr(simd)] -pub struct i32x4(i32, i32, i32, i32); +pub struct I32x4(i32, i32, i32, i32); extern "C" { // _mm_sll_epi32 - #[cfg(any(target_arch = "x86", target_arch = "x86-64"))] + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[link_name = "llvm.x86.sse2.psll.d"] - fn integer(a: i32x4, b: i32x4) -> i32x4; + fn integer(a: I32x4, b: I32x4) -> I32x4; // vmaxq_s32 #[cfg(target_arch = "arm")] #[link_name = "llvm.arm.neon.vmaxs.v4i32"] - fn integer(a: i32x4, b: i32x4) -> i32x4; + fn integer(a: I32x4, b: I32x4) -> I32x4; // vmaxq_s32 #[cfg(target_arch = "aarch64")] #[link_name = "llvm.aarch64.neon.maxs.v4i32"] - fn integer(a: i32x4, b: i32x4) -> i32x4; + fn integer(a: I32x4, b: I32x4) -> I32x4; // just some substitute foreign symbol, not an LLVM intrinsic; so // we still get type checking, but not as detailed as (ab)using // LLVM. - #[cfg(not(any( - target_arch = "x86", - target_arch = "x86-64", - target_arch = "arm", - target_arch = "aarch64" - )))] - fn integer(a: i32x4, b: i32x4) -> i32x4; + #[cfg(target_arch = "mips")] + #[target_feature(enable = "msa")] + fn integer(a: I32x4, b: I32x4) -> I32x4; } -pub fn bar(a: i32x4, b: i32x4) -> i32x4 { +pub fn bar(a: I32x4, b: I32x4) -> I32x4 { unsafe { integer(a, b) } } From eb9ed3a746f7bd5c4afc854d9f5d8b3c1bc5dccc Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 29 Jun 2021 07:56:18 +0900 Subject: [PATCH 11/12] Add some notes about arguments --- compiler/rustc_typeck/src/collect.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 71057d35eae5f..ff4da0fef087c 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2496,6 +2496,9 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( /// Returns `Ok()` if the target-feature allows using the SIMD type on C FFI. /// Otherwise, returns `Err(Some())` if the target_feature needs to be enabled or /// or `Err(None)` if it's unsupported. +/// Some notes about arguments: +/// - `simd_len`: A vector register size as octet, i.e. vN in the tests. +/// - `simd_elem_width`: A width of each element as octet, e.g. v512 should be 16 on avx512. fn simd_ffi_feature_check( target: &str, simd_width: u64, From 50020062a52b1628b83c98540869cb85b8a709be Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 25 Jul 2021 02:53:14 +0900 Subject: [PATCH 12/12] Address review comments --- compiler/rustc_typeck/src/collect.rs | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index ff4da0fef087c..903f23998aac9 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2520,13 +2520,8 @@ fn simd_ffi_feature_check( { Ok(()) } - 8 => Err(Some("mmx")), - 16 if feature.contains("sse") - || feature.contains("ssse") - || feature.contains("avx") => - { - Ok(()) - } + 8 => Err(None), + 16 if feature.contains("sse") => Ok(()), 16 => Err(Some("sse")), 32 if feature.contains("avx") => Ok(()), 32 => Err(Some("avx")), @@ -2535,19 +2530,16 @@ fn simd_ffi_feature_check( _ => Err(None), } } - t if t.contains("arm") => { - match simd_width { - // 32-bit arm does not support vectors with 64-bit wide elements - 8 | 16 if simd_elem_width < 8 => { - if feature.contains("neon") { - Ok(()) - } else { - Err(Some("neon")) - } + t if t.contains("arm") => match simd_width { + 8 | 16 | 32 => { + if feature.contains("neon") { + Ok(()) + } else { + Err(Some("neon")) } - _ => Err(None), } - } + _ => Err(None), + }, t if t.contains("aarch64") => match simd_width { 8 | 16 => { if feature.contains("neon") {