From 00dcb665e7ede908ba11638e8230340f396674f8 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 11 May 2020 00:16:16 +0300 Subject: [PATCH] cmdline: Make target features individually overridable --- src/doc/rustc/src/codegen-options/index.md | 10 +++++++++- src/librustc_session/options.rs | 16 +++++++++++++++- src/test/codegen/target-feature-multiple.rs | 9 +++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 src/test/codegen/target-feature-multiple.rs diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index dbe281be7df74..c638f88057a52 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -464,7 +464,15 @@ machine. Each target has a default base CPU. Individual targets will support different features; this flag lets you control enabling or disabling a feature. Each feature should be prefixed with a `+` to -enable it or `-` to disable it. Separate multiple features with commas. +enable it or `-` to disable it. + +Features from multiple `-C target-feature` options are combined. \ +Multiple features can be specified in a single option by separating them +with commas - `-C target-feature=+x,-y`. \ +If some feature is specified more than once with both `+` and `-`, +then values passed later override values passed earlier. \ +For example, `-C target-feature=+x,-y,+z -Ctarget-feature=-x,+y` +is equivalent to `-C target-feature=-x,+y,+z`. To see the valid options and an example of use, run `rustc --print target-features`. diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index 4eabb55e6dfe7..ed7b2b3d58a7b 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -270,6 +270,7 @@ macro_rules! options { "one of supported relocation models (`rustc --print relocation-models`)"; pub const parse_tls_model: &str = "one of supported TLS models (`rustc --print tls-models`)"; + pub const parse_target_feature: &str = parse_string; } #[allow(dead_code)] @@ -636,6 +637,19 @@ macro_rules! options { } true } + + fn parse_target_feature(slot: &mut String, v: Option<&str>) -> bool { + match v { + Some(s) => { + if !slot.is_empty() { + slot.push_str(","); + } + slot.push_str(s); + true + } + None => false, + } + } } ) } @@ -731,7 +745,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, "use soft float ABI (*eabihf targets only) (default: no)"), target_cpu: Option = (None, parse_opt_string, [TRACKED], "select target processor (`rustc --print target-cpus` for details)"), - target_feature: String = (String::new(), parse_string, [TRACKED], + target_feature: String = (String::new(), parse_target_feature, [TRACKED], "target specific attributes. (`rustc --print target-features` for details). \ This feature is unsafe."), diff --git a/src/test/codegen/target-feature-multiple.rs b/src/test/codegen/target-feature-multiple.rs new file mode 100644 index 0000000000000..f71a9c3c58216 --- /dev/null +++ b/src/test/codegen/target-feature-multiple.rs @@ -0,0 +1,9 @@ +// only-x86_64 +// compile-flags: -C target-feature=+sse2,-avx,+avx2 -C target-feature=+avx,-avx2 + +#![crate_type = "lib"] + +#[no_mangle] +pub fn foo() { + // CHECK: attributes #0 = { {{.*}}"target-features"="+sse2,-avx,+avx2,+avx,-avx2"{{.*}} } +}