-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adjust
-Ctarget-cpu=native
handling in cg_llvm
When cg_llvm encounters the `-Ctarget-cpu=native` it computes an explciit set of features that applies to the target in order to correctly compile code for the host CPU (because e.g. `skylake` alone is not sufficient to tell if some of the instructions are available or not). However there were a couple of issues with how we did this. Firstly, the order in which features were overriden wasn't quite right – conceptually you'd expect `-Ctarget-cpu=native` option to override the features that are implicitly set by the target definition. However due to how other `-Ctarget-cpu` values are handled we must adopt the following order of priority: * Features from -Ctarget-cpu=*; are overriden by * Features implied by --target; are overriden by * Features from -Ctarget-feature; are overriden by * function specific features. Another problem was in that the function level `target-features` attribute would overwrite the entire set of the globally enabled features, rather than just the features the `#[target_feature(enable/disable)]` specified. With something like `-Ctarget-cpu=native` we'd end up in a situation wherein a function without `#[target_feature(enable)]` annotation would have a broader set of features compared to a function with one such attribute. This turned out to be a cause of heavy run-time regressions in some code using these function-level attributes in conjunction with `-Ctarget-cpu=native`, for example. With this PR rustc is more careful about specifying the entire set of features for functions that use `#[target_feature(enable/disable)]` or `#[instruction_set]` attributes. Sadly testing the original reproducer for this behaviour is quite impossible – we cannot rely on `-Ctarget-cpu=native` to be anything in particular on developer or CI machines.
- Loading branch information
Showing
7 changed files
with
155 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// assembly-output: emit-asm | ||
// needs-llvm-components: x86 | ||
// revisions: TWOFLAGS SINGLEFLAG | ||
// compile-flags: --target=x86_64-unknown-linux-gnu | ||
// [TWOFLAGS] compile-flags: -C target-feature=+rdrnd -C target-feature=+rdseed | ||
// [SINGLEFLAG] compile-flags: -C target-feature=+rdrnd,+rdseed | ||
|
||
// Target features set via flags aren't necessarily reflected in the IR, so the only way to test | ||
// them is to build code that requires the features to be enabled to work. | ||
// | ||
// In this particular test if `rdrnd,rdseed` somehow didn't make it to LLVM, the instruction | ||
// selection should crash. | ||
// | ||
// > LLVM ERROR: Cannot select: 0x7f00f400c010: i32,i32,ch = X86ISD::RDSEED 0x7f00f400bfa8:2 | ||
// > In function: foo | ||
// | ||
// See also src/test/codegen/target-feature-overrides.rs | ||
#![feature(no_core, lang_items, link_llvm_intrinsics, abi_unadjusted)] | ||
#![crate_type = "lib"] | ||
#![no_core] | ||
|
||
#[lang = "sized"] | ||
trait Sized {} | ||
#[lang = "copy"] | ||
trait Copy {} | ||
|
||
// Use of these requires target features to be enabled | ||
extern "unadjusted" { | ||
#[link_name = "llvm.x86.rdrand.32"] | ||
fn x86_rdrand32_step() -> (u32, i32); | ||
#[link_name = "llvm.x86.rdseed.32"] | ||
fn x86_rdseed32_step() -> (u32, i32); | ||
} | ||
|
||
#[no_mangle] | ||
pub unsafe fn foo() -> (u32, u32) { | ||
// CHECK-LABEL: foo: | ||
// CHECK: rdrand | ||
// CHECK: rdseed | ||
(x86_rdrand32_step().0, x86_rdseed32_step().0) | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// revisions: COMPAT INCOMPAT | ||
// needs-llvm-components: x86 | ||
// compile-flags: --target=x86_64-unknown-linux-gnu -Copt-level=3 | ||
// [COMPAT] compile-flags: -Ctarget-feature=+avx2,+avx | ||
// [INCOMPAT] compile-flags: -Ctarget-feature=-avx2,-avx | ||
|
||
// See also src/test/assembly/target-feature-multiple.rs | ||
#![feature(no_core, lang_items)] | ||
#![crate_type = "lib"] | ||
#![no_core] | ||
|
||
|
||
#[lang = "sized"] | ||
trait Sized {} | ||
#[lang = "copy"] | ||
trait Copy {} | ||
|
||
extern "C" { | ||
fn peach() -> u32; | ||
} | ||
|
||
#[inline] | ||
#[target_feature(enable = "avx")] | ||
#[no_mangle] | ||
pub unsafe fn apple() -> u32 { | ||
// CHECK-LABEL: @apple() | ||
// CHECK-SAME: [[APPLEATTRS:#[0-9]+]] { | ||
// CHECK: {{.*}}call{{.*}}@peach | ||
peach() | ||
} | ||
|
||
// target features same as global (not reflected or overriden in IR) | ||
#[no_mangle] | ||
pub unsafe fn banana() -> u32 { | ||
// CHECK-LABEL: @banana() | ||
// CHECK-SAME: [[BANANAATTRS:#[0-9]+]] { | ||
// COMPAT: {{.*}}call{{.*}}@peach | ||
// INCOMPAT: {{.*}}call{{.*}}@apple | ||
apple() // Compatible for inline in COMPAT revision and can't be inlined in INCOMPAT | ||
} | ||
|
||
// CHECK: attributes [[APPLEATTRS]] | ||
// COMPAT-SAME: "target-features"="+avx2,+avx,+avx" | ||
// INCOMPAT-SAME: "target-features"="-avx2,-avx,+avx" | ||
// CHECK: attributes [[BANANAATTRS]] | ||
// CHECK-NOT: target-features | ||
// CHECK-SAME: } |