Skip to content

Commit 26d1202

Browse files
committed
target-feature: enable rust target features implied by target-cpu
Normally LLVM and rustc agree about what features are implied by target-cpu, but for NVPTX, LLVM considers sm_* and ptx* features to be exclusive, which makes sense for codegen purposes. But in Rust, we want to think of them as: sm_{sver} means that the target supports the hardware features of sver ptx{pver} means the driver supports PTX ISA pver Intrinsics usually require a minimum sm_{sver} and ptx{pver}. Prior to this commit, -Ctarget-cpu=sm_70 would activate only sm_70 and ptx60 (the minimum PTX version that supports sm_70, which maximizes driver compatibility). With this commit, it also activates all the implied target features (sm_20, ..., sm_62; ptx32, ..., ptx50).
1 parent 3185255 commit 26d1202

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

compiler/rustc_codegen_llvm/src/llvm_util.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -346,11 +346,12 @@ pub(crate) fn target_config(sess: &Session) -> TargetConfig {
346346
let target_machine = create_informational_target_machine(sess, true);
347347
// Compute which of the known target features are enabled in the 'base' target machine. We only
348348
// consider "supported" features; "forbidden" features are not reflected in `cfg` as of now.
349+
let mut cpu_implied_features: Vec<(bool, Symbol)> = Vec::new();
349350
let mut features: FxHashSet<Symbol> = sess
350351
.target
351352
.rust_target_features()
352353
.iter()
353-
.filter(|(feature, _, _)| {
354+
.filter(|(feature, _, implied)| {
354355
// skip checking special features, as LLVM may not understand them
355356
if RUSTC_SPECIAL_FEATURES.contains(feature) {
356357
return true;
@@ -365,6 +366,7 @@ pub(crate) fn target_config(sess: &Session) -> TargetConfig {
365366
return false;
366367
}
367368
}
369+
cpu_implied_features.extend(implied.iter().map(|f| (true, Symbol::intern(f))));
368370
true
369371
} else {
370372
false
@@ -373,14 +375,15 @@ pub(crate) fn target_config(sess: &Session) -> TargetConfig {
373375
.map(|(feature, _, _)| Symbol::intern(feature))
374376
.collect();
375377

376-
// Add enabled and remove disabled features.
377-
for (enabled, feature) in
378+
// Parse -Ctarget-feature=+feature1,-feature2
379+
let cg_target_features =
378380
sess.opts.cg.target_feature.split(',').filter_map(|s| match s.chars().next() {
379381
Some('+') => Some((true, Symbol::intern(&s[1..]))),
380382
Some('-') => Some((false, Symbol::intern(&s[1..]))),
381383
_ => None,
382-
})
383-
{
384+
});
385+
// Add features implied by -Ctarget-cpu followed by enabling/removing those specified by -Ctarget-feature
386+
for (enabled, feature) in cpu_implied_features.into_iter().chain(cg_target_features) {
384387
if enabled {
385388
// Also add all transitively implied features.
386389

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//@ assembly-output: ptx-linker
2+
//@ compile-flags: --crate-type cdylib -C target-cpu=sm_80 -Z unstable-options -Clinker-flavor=llbc
3+
//@ only-nvptx64
4+
//@ build-pass
5+
#![no_std]
6+
#![allow(dead_code)]
7+
8+
#[panic_handler]
9+
pub fn panic(_info: &core::panic::PanicInfo) -> ! {
10+
loop {}
11+
}
12+
13+
// -Ctarget-cpu=sm_80 directly enables sm_80 and ptx70
14+
#[cfg(not(all(target_feature = "sm_80", target_feature = "ptx70")))]
15+
compile_error!("direct target features not enabled");
16+
17+
// -Ctarget-cpu=sm_80 implies all earlier sm_* and ptx* features.
18+
#[cfg(not(all(
19+
target_feature = "sm_60",
20+
target_feature = "sm_70",
21+
target_feature = "ptx50",
22+
target_feature = "ptx60",
23+
)))]
24+
compile_error!("implied target features not enabled");
25+
26+
// -Ctarget-cpu=sm_80 implies all earlier sm_* and ptx* features.
27+
#[cfg(target_feature = "ptx71")]
28+
compile_error!("sm_80 requires only ptx70, but ptx71 enabled");

0 commit comments

Comments
 (0)