about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorLuca Versari <veluca@google.com>2024-06-24 17:17:18 +0200
committerLuca Versari <veluca93@gmail.com>2024-08-28 09:54:23 +0200
commit7eb4cfeaced28d49952e4ef54f8fe02258125854 (patch)
tree3ce2201b99e4a8a38f9f131fada5132be4327e7d /tests
parent748c54848dc2964b7e133f945cabe5bc64079947 (diff)
downloadrust-7eb4cfeaced28d49952e4ef54f8fe02258125854.tar.gz
rust-7eb4cfeaced28d49952e4ef54f8fe02258125854.zip
Implement RFC 3525.
Diffstat (limited to 'tests')
-rw-r--r--tests/assembly/struct-target-features.rs37
-rw-r--r--tests/ui/feature-gates/feature-gate-struct-target-features.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-struct-target-features.stderr10
-rw-r--r--tests/ui/target-feature/struct-target-features.rs98
-rw-r--r--tests/ui/target-feature/struct-target-features.stderr47
5 files changed, 196 insertions, 0 deletions
diff --git a/tests/assembly/struct-target-features.rs b/tests/assembly/struct-target-features.rs
new file mode 100644
index 00000000000..cc86fbaa840
--- /dev/null
+++ b/tests/assembly/struct-target-features.rs
@@ -0,0 +1,37 @@
+//@ compile-flags: -O
+//@ assembly-output: emit-asm
+//@ only-x86_64
+
+#![crate_type = "lib"]
+#![feature(struct_target_features)]
+
+// Check that a struct_target_features type causes the compiler to effectively inline intrinsics.
+
+use std::arch::x86_64::*;
+
+#[target_feature(enable = "avx")]
+struct Avx {}
+
+#[target_feature(enable = "fma")]
+struct Fma {}
+
+pub fn add_simple(_: Avx, v: __m256) -> __m256 {
+    // CHECK-NOT: call
+    // CHECK: vaddps
+    unsafe { _mm256_add_ps(v, v) }
+}
+
+pub fn add_complex_type(_: (&Avx, ()), v: __m256) -> __m256 {
+    // CHECK-NOT: call
+    // CHECK: vaddps
+    unsafe { _mm256_add_ps(v, v) }
+}
+
+pub fn add_fma_combined(_: (&Avx, &Fma), v: __m256) -> (__m256, __m256) {
+    // CHECK-NOT: call
+    // CHECK-DAG: vaddps
+    let r1 = unsafe { _mm256_add_ps(v, v) };
+    // CHECK-DAG: vfmadd213ps
+    let r2 = unsafe { _mm256_fmadd_ps(v, v, v) };
+    (r1, r2)
+}
diff --git a/tests/ui/feature-gates/feature-gate-struct-target-features.rs b/tests/ui/feature-gates/feature-gate-struct-target-features.rs
new file mode 100644
index 00000000000..85494881146
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-struct-target-features.rs
@@ -0,0 +1,4 @@
+#[target_feature(enable = "avx")] //~ ERROR attribute should be applied to a function definition
+struct Avx {}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-struct-target-features.stderr b/tests/ui/feature-gates/feature-gate-struct-target-features.stderr
new file mode 100644
index 00000000000..1e18d3ee1e1
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-struct-target-features.stderr
@@ -0,0 +1,10 @@
+error: attribute should be applied to a function definition
+  --> $DIR/feature-gate-struct-target-features.rs:1:1
+   |
+LL | #[target_feature(enable = "avx")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | struct Avx {}
+   | ------------- not a function definition
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target-feature/struct-target-features.rs b/tests/ui/target-feature/struct-target-features.rs
new file mode 100644
index 00000000000..feb479b6dc8
--- /dev/null
+++ b/tests/ui/target-feature/struct-target-features.rs
@@ -0,0 +1,98 @@
+//@ only-x86_64
+#![feature(struct_target_features)]
+//~^ WARNING the feature `struct_target_features` is incomplete and may not be safe to use and/or cause compiler crashes
+#![feature(target_feature_11)]
+
+use std::arch::x86_64::*;
+
+#[target_feature(enable = "avx")]
+//~^ ERROR attribute should be applied to a function definition or unit struct
+struct Invalid(u32);
+
+#[target_feature(enable = "avx")]
+struct Avx {}
+
+#[target_feature(enable = "sse")]
+struct Sse();
+
+#[target_feature(enable = "avx")]
+fn avx() {}
+
+trait TFAssociatedType {
+    type Assoc;
+}
+
+impl TFAssociatedType for () {
+    type Assoc = Avx;
+}
+
+fn avx_self(_: <() as TFAssociatedType>::Assoc) {
+    avx();
+}
+
+fn avx_avx(_: Avx) {
+    avx();
+}
+
+extern "C" fn bad_fun(_: Avx) {}
+//~^ ERROR cannot use a struct with target features in a function with non-Rust ABI
+
+#[inline(always)]
+//~^ ERROR cannot use `#[inline(always)]` with `#[target_feature]`
+fn inline_fun(_: Avx) {}
+//~^ ERROR cannot use a struct with target features in a #[inline(always)] function
+
+trait Simd {
+    fn do_something(&self);
+}
+
+impl Simd for Avx {
+    fn do_something(&self) {
+        unsafe {
+            println!("{:?}", _mm256_setzero_ps());
+        }
+    }
+}
+
+impl Simd for Sse {
+    fn do_something(&self) {
+        unsafe {
+            println!("{:?}", _mm_setzero_ps());
+        }
+    }
+}
+
+struct WithAvx {
+    #[allow(dead_code)]
+    avx: Avx,
+}
+
+impl Simd for WithAvx {
+    fn do_something(&self) {
+        unsafe {
+            println!("{:?}", _mm256_setzero_ps());
+        }
+    }
+}
+
+#[inline(never)]
+fn dosomething<S: Simd>(simd: &S) {
+    simd.do_something();
+}
+
+fn avxfn(_: &Avx) {}
+
+fn main() {
+    Avx {};
+    //~^ ERROR initializing type with `target_feature` attr is unsafe and requires unsafe function or block [E0133]
+
+    if is_x86_feature_detected!("avx") {
+        let avx = unsafe { Avx {} };
+        avxfn(&avx);
+        dosomething(&avx);
+        dosomething(&WithAvx { avx });
+    }
+    if is_x86_feature_detected!("sse") {
+        dosomething(&unsafe { Sse {} })
+    }
+}
diff --git a/tests/ui/target-feature/struct-target-features.stderr b/tests/ui/target-feature/struct-target-features.stderr
new file mode 100644
index 00000000000..5ef863f504e
--- /dev/null
+++ b/tests/ui/target-feature/struct-target-features.stderr
@@ -0,0 +1,47 @@
+warning: the feature `struct_target_features` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/struct-target-features.rs:2:12
+   |
+LL | #![feature(struct_target_features)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #129107 <https://github.com/rust-lang/rust/issues/129107> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: attribute should be applied to a function definition or unit struct
+  --> $DIR/struct-target-features.rs:8:1
+   |
+LL | #[target_feature(enable = "avx")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | struct Invalid(u32);
+   | -------------------- not a function definition or a unit struct
+
+error: cannot use a struct with target features in a function with non-Rust ABI
+  --> $DIR/struct-target-features.rs:37:1
+   |
+LL | extern "C" fn bad_fun(_: Avx) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot use a struct with target features in a #[inline(always)] function
+  --> $DIR/struct-target-features.rs:42:1
+   |
+LL | fn inline_fun(_: Avx) {}
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot use `#[inline(always)]` with `#[target_feature]`
+  --> $DIR/struct-target-features.rs:40:1
+   |
+LL | #[inline(always)]
+   | ^^^^^^^^^^^^^^^^^
+
+error[E0133]: initializing type with `target_feature` attr is unsafe and requires unsafe function or block
+  --> $DIR/struct-target-features.rs:86:5
+   |
+LL |     Avx {};
+   |     ^^^^^^ initializing type with `target_feature` attr
+   |
+   = note: this struct can only be constructed if the corresponding `target_feature`s are available
+
+error: aborting due to 5 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0133`.