diff options
| author | bors <bors@rust-lang.org> | 2024-08-28 22:54:55 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-08-28 22:54:55 +0000 |
| commit | acb4e8b6251f1d8da36f08e7a70fa23fc581839e (patch) | |
| tree | d34182dd7a2cb603a9aafa52839d64101c2dcc3f /tests/ui/target-feature/struct-target-features.rs | |
| parent | 100fde5246bf56f22fb5cc85374dd841296fce0e (diff) | |
| parent | 7eb4cfeaced28d49952e4ef54f8fe02258125854 (diff) | |
| download | rust-acb4e8b6251f1d8da36f08e7a70fa23fc581839e.tar.gz rust-acb4e8b6251f1d8da36f08e7a70fa23fc581839e.zip | |
Auto merge of #127537 - veluca93:struct_tf, r=BoxyUwU
Implement a first version of RFC 3525: struct target features
This PR is an attempt at implementing https://github.com/rust-lang/rfcs/pull/3525, behind a feature gate `struct_target_features`.
There's obviously a few tasks that ought to be done before this is merged; in no particular order:
- add proper error messages
- add tests
- create a tracking issue for the RFC
- properly serialize/deserialize the new target_features field in `rmeta` (assuming I even understood that correctly :-))
That said, as I am definitely not a `rustc` expert, I'd like to get some early feedback on the overall approach before fixing those things (and perhaps some pointers for `rmeta`...), hence this early PR :-)
Here's an example piece of code that I have been using for testing - with the new code, the calls to intrinsics get correctly inlined:
```rust
#![feature(struct_target_features)]
use std::arch::x86_64::*;
/*
// fails to compile
#[target_feature(enable = "avx")]
struct Invalid(u32);
*/
#[target_feature(enable = "avx")]
struct Avx {}
#[target_feature(enable = "sse")]
struct Sse();
/*
// fails to compile
extern "C" fn bad_fun(_: Avx) {}
*/
/*
// fails to compile
#[inline(always)]
fn inline_fun(_: Avx) {}
*/
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 main() {
/*
// fails to compile
Avx {};
*/
if is_x86_feature_detected!("avx") {
let avx = unsafe { Avx {} };
dosomething(&avx);
dosomething(&WithAvx { avx });
}
if is_x86_feature_detected!("sse") {
dosomething(&unsafe { Sse {} })
}
}
```
Tracking:
- https://github.com/rust-lang/rust/issues/129107
Diffstat (limited to 'tests/ui/target-feature/struct-target-features.rs')
| -rw-r--r-- | tests/ui/target-feature/struct-target-features.rs | 98 |
1 files changed, 98 insertions, 0 deletions
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 {} }) + } +} |
