Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,11 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
s => Some(LLVMFeature::new(s)),
}
}
Arch::Nvptx64 => match s {
"sm_88" | "ptx90" if major < 22 => None,
s if s.starts_with("sm_110") && major < 22 => None,
s => Some(LLVMFeature::new(s)),
},
_ => Some(LLVMFeature::new(s)),
}
}
Expand Down
46 changes: 37 additions & 9 deletions compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,15 +418,43 @@ pub fn target_spec_to_backend_features<'a>(
) {
let mut rust_features = vec![];

// This check handles SM versions that defaults (by LLVM) to unsupported (by Rust) PTX ISA versions.
// sm_70, sm_72 and sm_75 defaults to PTX ISA versions with major version 6, while sm_80 default to 7.0
if sess.target.arch == Arch::Nvptx64
&& matches!(
sess.opts.cg.target_cpu.as_deref(),
None | Some("sm_70") | Some("sm_72") | Some("sm_75")
)
{
rust_features.push((true, "ptx70"));
if sess.target.arch == Arch::Nvptx64 {
// Starting with LLVM 22, the NVPTX backend still infers the minimum
// required PTX version from the selected CPU when none is selected
// explicitly, but no longer reflects that in the enabled subtarget
// features. If a PTX version below the required minimum is selected
// explicitly, LLVM errors.
// To keep cfg evaluation consistent and avoid LLVM errors, always
// select an explicit PTX version: whichever is higher between
// - Rust's minimum required PTX version, and
// - the CPU's minimum required PTX version.
let min_ptx = match sess.opts.cg.target_cpu.as_deref() {
Some("sm_86") => "ptx71",
Some("sm_87") => "ptx74",
Some("sm_88") => "ptx90",
Some("sm_90") => "ptx78",
Some("sm_90a") => "ptx80",
Some("sm_100") => "ptx86",
Some("sm_100f") => "ptx88",
Some("sm_100a") => "ptx86",
Some("sm_101") => "ptx86",
Some("sm_101f") => "ptx88",
Some("sm_101a") => "ptx86",
Some("sm_103") => "ptx88",
Some("sm_103f") => "ptx88",
Some("sm_103a") => "ptx88",
Some("sm_110") => "ptx90",
Some("sm_110f") => "ptx90",
Some("sm_110a") => "ptx90",
Some("sm_120") => "ptx87",
Some("sm_120f") => "ptx88",
Some("sm_120a") => "ptx87",
Some("sm_121") => "ptx88",
Some("sm_121f") => "ptx88",
Some("sm_121a") => "ptx88",
_ => "ptx70",
};
rust_features.push((true, min_ptx));
}

// Compute implied features
Expand Down
49 changes: 44 additions & 5 deletions compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,25 +606,62 @@ const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[

const NVPTX_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
// tidy-alphabetical-start
("sm_20", Forbidden { reason: "unsupported compute capability", hard_error: true }, &[]),
("sm_21", Forbidden { reason: "unsupported compute capability", hard_error: true }, &[]),
("sm_30", Forbidden { reason: "unsupported compute capability", hard_error: true }, &[]),
("sm_32", Forbidden { reason: "unsupported compute capability", hard_error: true }, &[]),
("sm_35", Forbidden { reason: "unsupported compute capability", hard_error: true }, &[]),
("sm_37", Forbidden { reason: "unsupported compute capability", hard_error: true }, &[]),
("sm_50", Forbidden { reason: "unsupported compute capability", hard_error: true }, &[]),
("sm_52", Forbidden { reason: "unsupported compute capability", hard_error: true }, &[]),
("sm_53", Forbidden { reason: "unsupported compute capability", hard_error: true }, &[]),
("sm_60", Forbidden { reason: "unsupported compute capability", hard_error: true }, &[]),
("sm_61", Forbidden { reason: "unsupported compute capability", hard_error: true }, &[]),
("sm_62", Forbidden { reason: "unsupported compute capability", hard_error: true }, &[]),
("sm_70", Unstable(sym::nvptx_target_feature), &[]),
("sm_72", Unstable(sym::nvptx_target_feature), &["sm_70"]),
("sm_75", Unstable(sym::nvptx_target_feature), &["sm_72"]),
("sm_80", Unstable(sym::nvptx_target_feature), &["sm_75"]),
("sm_86", Unstable(sym::nvptx_target_feature), &["sm_80"]),
("sm_87", Unstable(sym::nvptx_target_feature), &["sm_86"]),
("sm_89", Unstable(sym::nvptx_target_feature), &["sm_87"]),
("sm_88", Unstable(sym::nvptx_target_feature), &["sm_87"]),
("sm_89", Unstable(sym::nvptx_target_feature), &["sm_88"]),
("sm_90", Unstable(sym::nvptx_target_feature), &["sm_89"]),
("sm_90a", Unstable(sym::nvptx_target_feature), &["sm_90"]),
// tidy-alphabetical-end
// tidy-alphabetical-start
("sm_100", Unstable(sym::nvptx_target_feature), &["sm_90"]),
("sm_100a", Unstable(sym::nvptx_target_feature), &["sm_100"]),
("sm_100a", Unstable(sym::nvptx_target_feature), &["sm_100f"]),
("sm_100f", Unstable(sym::nvptx_target_feature), &["sm_100"]),
("sm_101", Unstable(sym::nvptx_target_feature), &["sm_100"]),
("sm_101a", Unstable(sym::nvptx_target_feature), &["sm_101"]),
("sm_120", Unstable(sym::nvptx_target_feature), &["sm_101"]),
("sm_120a", Unstable(sym::nvptx_target_feature), &["sm_120"]),
("sm_101a", Unstable(sym::nvptx_target_feature), &["sm_101f"]),
("sm_101f", Unstable(sym::nvptx_target_feature), &["sm_101"]),
("sm_103", Unstable(sym::nvptx_target_feature), &["sm_100"]),
("sm_103a", Unstable(sym::nvptx_target_feature), &["sm_103f"]),
("sm_103f", Unstable(sym::nvptx_target_feature), &["sm_103", "sm_100f"]),
("sm_110", Unstable(sym::nvptx_target_feature), &["sm_103"]),
("sm_110a", Unstable(sym::nvptx_target_feature), &["sm_110f"]),
("sm_110f", Unstable(sym::nvptx_target_feature), &["sm_110"]),
("sm_120", Unstable(sym::nvptx_target_feature), &["sm_110"]),
("sm_120a", Unstable(sym::nvptx_target_feature), &["sm_120f"]),
("sm_120f", Unstable(sym::nvptx_target_feature), &["sm_120"]),
("sm_121", Unstable(sym::nvptx_target_feature), &["sm_120"]),
("sm_121a", Unstable(sym::nvptx_target_feature), &["sm_121f"]),
("sm_121f", Unstable(sym::nvptx_target_feature), &["sm_121", "sm_120f"]),
// tidy-alphabetical-end
// tidy-alphabetical-start
("ptx32", Forbidden { reason: "unsupported PTX version", hard_error: true }, &[]),
("ptx40", Forbidden { reason: "unsupported PTX version", hard_error: true }, &[]),
("ptx41", Forbidden { reason: "unsupported PTX version", hard_error: true }, &[]),
("ptx42", Forbidden { reason: "unsupported PTX version", hard_error: true }, &[]),
("ptx43", Forbidden { reason: "unsupported PTX version", hard_error: true }, &[]),
("ptx50", Forbidden { reason: "unsupported PTX version", hard_error: true }, &[]),
("ptx60", Forbidden { reason: "unsupported PTX version", hard_error: true }, &[]),
("ptx61", Forbidden { reason: "unsupported PTX version", hard_error: true }, &[]),
("ptx62", Forbidden { reason: "unsupported PTX version", hard_error: true }, &[]),
("ptx63", Forbidden { reason: "unsupported PTX version", hard_error: true }, &[]),
("ptx64", Forbidden { reason: "unsupported PTX version", hard_error: true }, &[]),
("ptx65", Forbidden { reason: "unsupported PTX version", hard_error: true }, &[]),
("ptx70", Unstable(sym::nvptx_target_feature), &[]),
("ptx71", Unstable(sym::nvptx_target_feature), &["ptx70"]),
("ptx72", Unstable(sym::nvptx_target_feature), &["ptx71"]),
Expand All @@ -642,6 +679,8 @@ const NVPTX_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("ptx85", Unstable(sym::nvptx_target_feature), &["ptx84"]),
("ptx86", Unstable(sym::nvptx_target_feature), &["ptx85"]),
("ptx87", Unstable(sym::nvptx_target_feature), &["ptx86"]),
("ptx88", Unstable(sym::nvptx_target_feature), &["ptx87"]),
("ptx90", Unstable(sym::nvptx_target_feature), &["ptx88"]),
// tidy-alphabetical-end
];

Expand Down
15 changes: 15 additions & 0 deletions tests/ui/check-cfg/target_feature.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE");
`ptx85`
`ptx86`
`ptx87`
`ptx88`
`ptx90`
`quadword-atomics`
`rand`
`ras`
Expand Down Expand Up @@ -294,16 +296,29 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE");
`sm4`
`sm_100`
`sm_100a`
`sm_100f`
`sm_101`
`sm_101a`
`sm_101f`
`sm_103`
`sm_103a`
`sm_103f`
`sm_110`
`sm_110a`
`sm_110f`
`sm_120`
`sm_120a`
`sm_120f`
`sm_121`
`sm_121a`
`sm_121f`
`sm_70`
`sm_72`
`sm_75`
`sm_80`
`sm_86`
`sm_87`
`sm_88`
`sm_89`
`sm_90`
`sm_90a`
Expand Down
36 changes: 19 additions & 17 deletions tests/ui/target-feature/implied-features-nvptx.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
//@ assembly-output: emit-asm
//@ compile-flags: --crate-type cdylib -C target-cpu=sm_80
//@ only-nvptx64
//@ build-pass
#![no_std]
//@ compile-flags: --target=nvptx64-nvidia-cuda --crate-type cdylib -C target-cpu=sm_90
//@ needs-llvm-components: nvptx
//@ check-pass
//@ ignore-backends: gcc
#![feature(no_core, rustc_attrs)]
#![no_core]
#![allow(dead_code)]

#[panic_handler]
pub fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
#[rustc_builtin_macro]
#[macro_export]
macro_rules! compile_error {
($msg:expr $(,)?) => {{ /* compiler built-in */ }};
}

// -Ctarget-cpu=sm_80 directly enables sm_80 and ptx70
#[cfg(not(all(target_feature = "sm_80", target_feature = "ptx70")))]
// -Ctarget-cpu=sm_90 directly enables sm_90 and ptx78
#[cfg(not(all(target_feature = "sm_90", target_feature = "ptx78")))]
compile_error!("direct target features not enabled");

// -Ctarget-cpu=sm_80 implies all earlier sm_* and ptx* features.
// -Ctarget-cpu=sm_90 implies all earlier sm_* and ptx* features.
#[cfg(not(all(
target_feature = "sm_60",
target_feature = "sm_70",
target_feature = "ptx50",
target_feature = "ptx60",
target_feature = "sm_80",
target_feature = "ptx71",
target_feature = "ptx74",
)))]
compile_error!("implied target features not enabled");

// -Ctarget-cpu=sm_80 implies all earlier sm_* and ptx* features.
#[cfg(target_feature = "ptx71")]
compile_error!("sm_80 requires only ptx70, but ptx71 enabled");
// -Ctarget-cpu=sm_90 implies all earlier sm_* and ptx* features.
#[cfg(target_feature = "ptx80")]
compile_error!("sm_90 requires only ptx78, but ptx80 enabled");
Loading