Skip to content
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

Document the target_feature_11 feature #1181

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
72 changes: 58 additions & 14 deletions src/attributes/codegen.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ features. It uses the [_MetaListNameValueStr_] syntax with a single key of
```rust
# #[cfg(target_feature = "avx2")]
LeSeulArtichaut marked this conversation as resolved.
Show resolved Hide resolved
#[target_feature(enable = "avx2")]
unsafe fn foo_avx2() {}
fn foo_avx2() {}
```

Each [target architecture] has a set of features that may be enabled. It is an
Expand All @@ -66,20 +66,68 @@ It is [undefined behavior] to call a function that is compiled with a feature
that is not supported on the current platform the code is running on, *except*
if the platform explicitly documents this to be safe.

Functions marked with `target_feature` are not inlined into a context that
does not support the given features. The `#[inline(always)]` attribute may not
be used with a `target_feature` attribute.
For this reason, a function marked with `target_feature` is unsafe to call,
except inside a function that has at least the exact same `target_feature`
enabled. For example:

```rust
# #[cfg(target_feature = "avx2")] {
#[target_feature(enable = "avx")]
fn foo_avx() {}

fn bar() {
// Calling `foo_avx` here is unsafe, as we must ensure that AVX is
// available first, even if `avx` is enabled by default on the target
// platform or manually enabled as compiler flags.
unsafe {
foo_avx();
}
}

#[target_feature(enable = "avx")]
fn bar_avx() {
// Calling `foo_avx` here is safe.
foo_avx();
|| foo_avx();
}

#[target_feature(enable = "avx2")]
fn bar_avx2() {
// Calling `foo_avx` here is unsafe because `bar_avx2` doesn't enable `avx`
// specifically, even though in practice `avx2` implies `avx`.
unsafe {
foo_avx();
}
}
# }
```

Like unsafe functions, functions marked with `target_feature` cannot be
assigned to a safe function pointer and do not implement `FnOnce`. They can
however be assigned to unsafe function pointers:

```rust
# #[cfg(target_feature = "avx2")] {
# #[target_feature(enable = "avx2")]
# fn foo_avx2() {}

// `unsafe` is required here.
static MY_FN_PTR: unsafe fn () -> () = foo_avx2;
# }
```

`#[target_feature]` may not be applied to safe trait method implementations.

Functions marked with `target_feature` are not inlined into a context unless
it supports the given features. The `#[inline(always)]` attribute may not
be used with `target_feature`.

### Available features

The following is a list of the available feature names.

#### `x86` or `x86_64`

Executing code with unsupported features is undefined behavior on this platform.
Hence this platform requires that `#[target_feature]` is only applied to [`unsafe`
functions][unsafe function].

Feature | Implicitly Enables | Description
------------|--------------------|-------------------
`aes` | `sse2` | [AES] — Advanced Encryption Standard
Expand Down Expand Up @@ -135,9 +183,6 @@ Feature | Implicitly Enables | Description

#### `aarch64`

This platform requires that `#[target_feature]` is only applied to [`unsafe`
functions][unsafe function].

Further documentation on these features can be found in the [ARM Architecture
Reference Manual], or elsewhere on [developer.arm.com].

Expand Down Expand Up @@ -200,9 +245,8 @@ Feature | Implicitly Enables | Feature Name

#### `wasm32` or `wasm64`

`#[target_feature]` may be used with both safe and
[`unsafe` functions][unsafe function] on Wasm platforms. It is impossible to
cause undefined behavior via the `#[target_feature]` attribute because
`#[target_feature]` may be called from a safe context on Wasm platforms. It is
impossible to cause undefined behavior via the `#[target_feature]` attribute because
attempting to use instructions unsupported by the Wasm engine will fail at load
time without the risk of being interpreted in a way different from what the
compiler expected.
Expand Down