From 54107ec994d0484381d08709a53f078fb6278189 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Thu, 17 Mar 2022 22:52:32 +0100 Subject: [PATCH 1/2] Document the `target_feature_11` feature --- src/attributes/codegen.md | 47 ++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/src/attributes/codegen.md b/src/attributes/codegen.md index 900559db6..5aa807143 100644 --- a/src/attributes/codegen.md +++ b/src/attributes/codegen.md @@ -53,9 +53,8 @@ features. It uses the [_MetaListNameValueStr_] syntax with a single key of `enable` whose value is a string of comma-separated feature names to enable. ```rust -# #[cfg(target_feature = "avx2")] #[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 @@ -66,9 +65,35 @@ 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, except in +a context that supports the given features. For example: + +```rust +# #[target_feature(enable = "avx2")] +# fn foo_avx2() {} + +fn bar() { + // Calling `foo_avx2` here is unsafe, as we must ensure + // that AVX is available first. + unsafe { + foo_avx2(); + } +} + +#[target_feature(enable = "avx2")] +fn bar_avx2() { + // Calling `foo_avx2` here is safe. + foo_avx2(); + || foo_avx2(); +} +``` + +Like unsafe functions, functions marked with `target_feature` cannot be +assigned to a safe function pointer and do not implement `FnOnce`. + +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 @@ -76,10 +101,6 @@ 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 @@ -135,9 +156,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]. @@ -200,9 +218,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. From d00e6bbf5142e0e57071a82dd22d6613f2245508 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Thu, 2 Mar 2023 08:20:09 +0100 Subject: [PATCH 2/2] Address review comments --- src/attributes/codegen.md | 49 ++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/src/attributes/codegen.md b/src/attributes/codegen.md index 5aa807143..fb858e280 100644 --- a/src/attributes/codegen.md +++ b/src/attributes/codegen.md @@ -53,6 +53,7 @@ features. It uses the [_MetaListNameValueStr_] syntax with a single key of `enable` whose value is a string of comma-separated feature names to enable. ```rust +# #[cfg(target_feature = "avx2")] #[target_feature(enable = "avx2")] fn foo_avx2() {} ``` @@ -65,31 +66,57 @@ 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. -For this reason, a function marked with `target_feature` is unsafe, except in -a context that supports the given features. For example: +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 -# #[target_feature(enable = "avx2")] -# fn foo_avx2() {} +# #[cfg(target_feature = "avx2")] { +#[target_feature(enable = "avx")] +fn foo_avx() {} fn bar() { - // Calling `foo_avx2` here is unsafe, as we must ensure - // that AVX is available first. + // 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_avx2(); + 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_avx2` here is safe. - foo_avx2(); - || foo_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`. +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