Add test to ensure implied target features work with asm, and fix failing tests

This commit is contained in:
Caleb Zulawski 2024-07-26 10:04:27 -04:00
parent 74653b61a6
commit 22c5952944
6 changed files with 44 additions and 49 deletions

View File

@ -1,7 +1,7 @@
use rustc_ast::ast; use rustc_ast::ast;
use rustc_attr::InstructionSetAttr; use rustc_attr::InstructionSetAttr;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
@ -99,12 +99,14 @@ pub fn from_target_feature(
})); }));
} }
// Add implied features // Add both explicit and implied target features, using a set to deduplicate
let mut target_features_set = UnordSet::new();
for feature in added_target_features.iter() { for feature in added_target_features.iter() {
target_features target_features_set
.extend(tcx.implied_target_features(*feature).clone().into_sorted_stable_ord()); .extend_unord(tcx.implied_target_features(*feature).clone().into_items());
} }
target_features.extend(added_target_features) target_features_set.extend(added_target_features);
target_features.extend(target_features_set.into_sorted_stable_ord())
} }
/// Computes the set of target features used in a function for the purposes of /// Computes the set of target features used in a function for the purposes of

View File

@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed
--> $DIR/const_fn_target_feature.rs:11:24 --> $DIR/const_fn_target_feature.rs:11:24
| |
LL | const B: () = unsafe { avx2_fn() }; LL | const B: () = unsafe { avx2_fn() };
| ^^^^^^^^^ calling a function that requires unavailable target features: avx2 | ^^^^^^^^^ calling a function that requires unavailable target features: avx, avx2, sse4.1, sse4.2
error: aborting due to 1 previous error error: aborting due to 1 previous error

View File

@ -34,6 +34,7 @@ fn foo() {
#[target_feature(enable = "sse2")] #[target_feature(enable = "sse2")]
fn bar() { fn bar() {
sse2();
avx_bmi2(); avx_bmi2();
//~^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe //~^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe
Quux.avx_bmi2(); Quux.avx_bmi2();
@ -43,7 +44,6 @@ fn bar() {
#[target_feature(enable = "avx")] #[target_feature(enable = "avx")]
fn baz() { fn baz() {
sse2(); sse2();
//~^ ERROR call to function `sse2` with `#[target_feature]` is unsafe
avx_bmi2(); avx_bmi2();
//~^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe //~^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe
Quux.avx_bmi2(); Quux.avx_bmi2();
@ -54,7 +54,8 @@ fn baz() {
#[target_feature(enable = "bmi2")] #[target_feature(enable = "bmi2")]
fn qux() { fn qux() {
sse2(); sse2();
//~^ ERROR call to function `sse2` with `#[target_feature]` is unsafe avx_bmi2();
Quux.avx_bmi2();
} }
const _: () = sse2(); const _: () = sse2();
@ -64,8 +65,6 @@ fn qux() {
//~^ ERROR call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe //~^ ERROR call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe
#[deny(unsafe_op_in_unsafe_fn)] #[deny(unsafe_op_in_unsafe_fn)]
#[target_feature(enable = "avx")]
#[target_feature(enable = "bmi2")]
unsafe fn needs_unsafe_block() { unsafe fn needs_unsafe_block() {
sse2(); sse2();
//~^ ERROR call to function `sse2` with `#[target_feature]` is unsafe //~^ ERROR call to function `sse2` with `#[target_feature]` is unsafe

View File

@ -4,8 +4,8 @@ error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and req
LL | sse2(); LL | sse2();
| ^^^^^^ call to function with `#[target_feature]` | ^^^^^^ call to function with `#[target_feature]`
| |
= help: in order for the call to be safe, the context requires the following additional target feature: sse2 = help: in order for the call to be safe, the context requires the following additional target features: sse and sse2
= note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` = note: the sse and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:29:5 --> $DIR/safe-calls.rs:29:5
@ -13,7 +13,8 @@ error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and
LL | avx_bmi2(); LL | avx_bmi2();
| ^^^^^^^^^^ call to function with `#[target_feature]` | ^^^^^^^^^^ call to function with `#[target_feature]`
| |
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 = help: in order for the call to be safe, the context requires the following additional target features: avx, sse, sse2, sse3, sse4.1, sse4.2, ssse3, and bmi2
= note: the sse and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:31:5 --> $DIR/safe-calls.rs:31:5
@ -21,32 +22,24 @@ error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsa
LL | Quux.avx_bmi2(); LL | Quux.avx_bmi2();
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
| |
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 = help: in order for the call to be safe, the context requires the following additional target features: avx, sse, sse2, sse3, sse4.1, sse4.2, ssse3, and bmi2
= note: the sse and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:37:5 --> $DIR/safe-calls.rs:38:5
| |
LL | avx_bmi2(); LL | avx_bmi2();
| ^^^^^^^^^^ call to function with `#[target_feature]` | ^^^^^^^^^^ call to function with `#[target_feature]`
| |
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 = help: in order for the call to be safe, the context requires the following additional target features: avx, sse3, sse4.1, sse4.2, ssse3, and bmi2
error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:39:5 --> $DIR/safe-calls.rs:40:5
| |
LL | Quux.avx_bmi2(); LL | Quux.avx_bmi2();
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
| |
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 = help: in order for the call to be safe, the context requires the following additional target features: avx, sse3, sse4.1, sse4.2, ssse3, and bmi2
error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:45:5
|
LL | sse2();
| ^^^^^^ call to function with `#[target_feature]`
|
= help: in order for the call to be safe, the context requires the following additional target feature: sse2
= note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:47:5 --> $DIR/safe-calls.rs:47:5
@ -65,52 +58,43 @@ LL | Quux.avx_bmi2();
= help: in order for the call to be safe, the context requires the following additional target feature: bmi2 = help: in order for the call to be safe, the context requires the following additional target feature: bmi2
error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:56:5 --> $DIR/safe-calls.rs:61:15
|
LL | sse2();
| ^^^^^^ call to function with `#[target_feature]`
|
= help: in order for the call to be safe, the context requires the following additional target feature: sse2
= note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:60:15
| |
LL | const _: () = sse2(); LL | const _: () = sse2();
| ^^^^^^ call to function with `#[target_feature]` | ^^^^^^ call to function with `#[target_feature]`
| |
= help: in order for the call to be safe, the context requires the following additional target feature: sse2 = help: in order for the call to be safe, the context requires the following additional target features: sse and sse2
= note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` = note: the sse and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
error[E0133]: call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:63:15 --> $DIR/safe-calls.rs:64:15
| |
LL | const _: () = sse2_and_fxsr(); LL | const _: () = sse2_and_fxsr();
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
| |
= help: in order for the call to be safe, the context requires the following additional target features: sse2 and fxsr = help: in order for the call to be safe, the context requires the following additional target features: sse, sse2, and fxsr
= note: the fxsr and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]` = note: the fxsr, sse, and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block
--> $DIR/safe-calls.rs:70:5 --> $DIR/safe-calls.rs:69:5
| |
LL | sse2(); LL | sse2();
| ^^^^^^ call to function with `#[target_feature]` | ^^^^^^ call to function with `#[target_feature]`
| |
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668> = note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
= help: in order for the call to be safe, the context requires the following additional target feature: sse2 = help: in order for the call to be safe, the context requires the following additional target features: sse and sse2
= note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` = note: the sse and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
note: an unsafe function restricts its caller, but its body is safe by default note: an unsafe function restricts its caller, but its body is safe by default
--> $DIR/safe-calls.rs:69:1 --> $DIR/safe-calls.rs:68:1
| |
LL | unsafe fn needs_unsafe_block() { LL | unsafe fn needs_unsafe_block() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: the lint level is defined here note: the lint level is defined here
--> $DIR/safe-calls.rs:66:8 --> $DIR/safe-calls.rs:67:8
| |
LL | #[deny(unsafe_op_in_unsafe_fn)] LL | #[deny(unsafe_op_in_unsafe_fn)]
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 12 previous errors error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0133`. For more information about this error, try `rustc --explain E0133`.

View File

@ -0,0 +1,10 @@
//@ only-x86_64
//@ build-pass
#![allow(dead_code)]
#[target_feature(enable = "avx2")]
unsafe fn demo(v: std::arch::x86_64::__m256i) {
std::arch::asm!("/* {v} */", v = in(ymm_reg) v);
}
fn main() {}

View File

@ -1,5 +1,5 @@
//@ only-x86_64 //@ only-x86_64
//@ run-pass //@ build-pass
#![feature(target_feature_11)] #![feature(target_feature_11)]
#![allow(dead_code)] #![allow(dead_code)]