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
8 changes: 7 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ jobs:
# - rust-gpu-version: bbb61f58b3d24f3f64745050eb214b90bf6dcce9
# glam-version: 0.30.7

# testing rustc 1.5 months later
# testing rustc 1.79.0, 1.5 months later
- rust-gpu-version: eea8998df9dc2fd8e7a65c5b5b7ae20c238a665a
glam-version: 0.29.3

Expand All @@ -280,6 +280,12 @@ jobs:
- rust-gpu-version: 30896871ba00e668029ccb724f1438202b284708
# after
- rust-gpu-version: 877bd8697a15f3e6d09446a5e1807e6237ca1dac

# rustc 1.97.0 removed "allows-weak-linkage" key
# before
- rust-gpu-version: a27c0363d391a54de1feb9ee6864ad9dff72d243
glam-version: 0.33.0
# after to be added later
runs-on: ubuntu-latest
env:
RUST_LOG: debug
Expand Down
2 changes: 1 addition & 1 deletion crates/cargo-gpu-install/src/install_toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ pub fn run_cmd(cmd: &mut Command) -> anyhow::Result<(String, String)> {
anyhow::bail!(
"Command `{}` failed with {}:\n-- stdout\n{stdout}\n-- stderr\n{stderr}",
fmt_cmd(),
&output.status,
output.status,
);
}
Ok((stdout, stderr))
Expand Down
2 changes: 1 addition & 1 deletion crates/cargo-gpu-install/src/spirv_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ impl SpirvSource {
Some(Self::Git { url, rev })
};
parse_git()
.with_context(|| format!("Failed to parse git url {}", &source.repr))?
.with_context(|| format!("Failed to parse git url {}", source.repr))?
}
(false, true) => Self::CratesIO(spirv_std_package.version.clone()),
(false, false) => {
Expand Down
56 changes: 35 additions & 21 deletions crates/rustc_codegen_spirv-types/src/target_spec.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::SpirvTarget;
#[allow(clippy::enum_glob_use)]
use TargetSpecVersion::*;
use semver::Version;
use std::ffi::OsString;
use std::path::Path;
Expand All @@ -9,20 +11,23 @@ use std::path::Path;
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum TargetSpecVersion {
/// doesn't support target spec files
Older,
/// Introduced in `489c3ee6fd63da3ca7cf2b15e1ee709d8e078aab` in the old v2 target spec way, later ported to here.
/// remove `os: unknown`, add `crt-static-respected: true`
Rustc_1_85_0,
/// rustc 1.76 has been tested to correctly parse modern target spec jsons.
/// Some later version requires them.
/// Some earlier version fails with them (notably our 0.9.0 release).
Rustc_1_76_0,
/// Introduced in `489c3ee6fd63da3ca7cf2b15e1ee709d8e078aab` in the old v2 target spec way, later ported to here.
/// remove `os: unknown`, add `crt-static-respected: true`
Rustc_1_85_0,
/// rustc 1.93 requires that the value of "target-pointer-width" is no longer a string but u16
Rustc_1_93_0,
/// rustc 1.94.0 destabilised json target specs, requiring `-Ztarget-spec-json`
/// see <https://github.com/Rust-GPU/rust-gpu/pull/545>
/// see <https://github.com/rust-lang/rust/pull/150151>
Rustc_1_94_0,
/// rustc 1.97.0 removed "allows-weak-linkage" key
Rustc_1_97_0,
}

#[derive(Clone, Debug, Default)]
Expand All @@ -49,11 +54,11 @@ impl TargetSpecVersion {
) -> std::io::Result<TargetSpec> {
let mut ret = TargetSpec::default();
let target_spec = Self::from_rustc_version(rustc_version);
if target_spec >= Self::Rustc_1_94_0 {
if target_spec >= Rustc_1_94_0 {
ret.extra_options.push("-Zjson-target-spec".into());
}

ret.target = if target_spec == Self::Older {
ret.target = if target_spec == Older {
target.target().into()
} else {
std::fs::create_dir_all(target_spec_folder)?;
Expand All @@ -67,33 +72,42 @@ impl TargetSpecVersion {
/// Returns the version of the target spec required for a certain rustc version. May return `None` if the version
/// is old enough to not need target specs.
pub fn from_rustc_version(rustc_version: Version) -> Self {
if rustc_version >= Version::new(1, 94, 0) {
Self::Rustc_1_94_0
if rustc_version >= Version::new(1, 97, 0) {
Rustc_1_97_0
} else if rustc_version >= Version::new(1, 94, 0) {
Rustc_1_94_0
} else if rustc_version >= Version::new(1, 93, 0) {
Self::Rustc_1_93_0
Rustc_1_93_0
} else if rustc_version >= Version::new(1, 85, 0) {
Self::Rustc_1_85_0
Rustc_1_85_0
} else if rustc_version >= Version::new(1, 76, 0) {
Self::Rustc_1_76_0
Rustc_1_76_0
} else {
Self::Older
Older
}
}

/// format the target spec json
pub fn format_spec(&self, target: &SpirvTarget) -> String {
pub fn format_spec(self, target: &SpirvTarget) -> String {
if matches!(self, Older) {
panic!("no target specs for older rustc versions")
}

let target_env = target.env();
let (extra, target_pointer_width) = match self {
TargetSpecVersion::Older => panic!("no target specs for older rustc versions"),
TargetSpecVersion::Rustc_1_76_0 => (r#""os": "unknown","#, "\"32\""),
TargetSpecVersion::Rustc_1_85_0 => (r#""crt-static-respected": true,"#, "\"32\""),
TargetSpecVersion::Rustc_1_93_0 | TargetSpecVersion::Rustc_1_94_0 => {
(r#""crt-static-respected": true,"#, "32")
}
let allows_weak_linkage = if self >= Rustc_1_97_0 {
""
} else {
r#""allows-weak-linkage": false,"#
};
let os_crt_static_respected = if self >= Rustc_1_85_0 {
r#""crt-static-respected": true,"#
} else {
r#""os": "unknown","#
};
let target_pointer_width = if self >= Rustc_1_93_0 { "32" } else { "\"32\"" };
format!(
r#"{{
"allows-weak-linkage": false,
{allows_weak_linkage}
"arch": "spirv",
"crt-objects-fallback": "false",
"crt-static-allows-dylibs": true,
Expand All @@ -113,7 +127,7 @@ impl TargetSpecVersion {
"std": null,
"tier": null
}},
{extra}
{os_crt_static_respected}
"panic-strategy": "abort",
"simd-types-indirect": false,
"target-pointer-width": {target_pointer_width}
Expand Down
4 changes: 2 additions & 2 deletions crates/rustc_codegen_spirv/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ use std::{env, fs, mem};
/// `cargo publish`. We need to figure out a way to do this properly, but let's hardcode it for now :/
//const REQUIRED_RUST_TOOLCHAIN: &str = include_str!("../../rust-toolchain.toml");
const REQUIRED_RUST_TOOLCHAIN: &str = r#"[toolchain]
channel = "nightly-2026-04-11"
channel = "nightly-2026-05-22"
components = ["rust-src", "rustc-dev", "llvm-tools"]
# commit_hash = 02c7f9bec0fd583160f8bcccb830216023b07bee"#;
# commit_hash = e96c36b6f76833388c519561d145492d2c08db4e"#;

fn rustc_output(arg: &str) -> Result<String, Box<dyn Error>> {
let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into());
Expand Down
14 changes: 9 additions & 5 deletions crates/rustc_codegen_spirv/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,15 @@ fn rewrite_c_abi_to_rust<'tcx>(
fn_sig: ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>>,
) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
fn_sig.map_bound(|outer| {
outer.map_bound(|mut inner| {
if let Abi::C { .. } = inner.abi {
inner.abi = Abi::Rust;
outer.map_bound(|inner: ty::FnSig<'_>| {
if let Abi::C { .. } = inner.abi() {
ty::FnSig {
fn_sig_kind: inner.fn_sig_kind.set_abi(Abi::Rust),
..inner
}
} else {
inner
}
inner
})
})
}
Expand Down Expand Up @@ -1081,7 +1085,7 @@ fn trans_glam_like_struct<'tcx>(
.non_enum_variant()
.fields
.iter()
.map(|f| f.ty(tcx, args))
.map(|f| f.ty(tcx, args).skip_norm_wip())
.dedup_with_count()
.exactly_one()
.map_err(|_e| {
Expand Down
4 changes: 4 additions & 0 deletions crates/rustc_codegen_spirv/src/builder/builder_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3088,6 +3088,10 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
bug!("Funclets are not supported")
}

fn get_funclet_cleanuppad(&self, _funclet: &Self::Funclet) -> Self::Value {
bug!("Funclets are not supported")
}

fn atomic_cmpxchg(
&mut self,
dst: Self::Value,
Expand Down
9 changes: 9 additions & 0 deletions crates/rustc_codegen_spirv/src/builder/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::custom_insts::CustomInst;
use crate::spirv_type::SpirvType;
use rspirv::dr::Operand;
use rspirv::spirv::GLOp;
use rustc_codegen_ssa::RetagInfo;
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::{BuilderMethods, IntrinsicCallBuilderMethods};
Expand Down Expand Up @@ -411,6 +412,14 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
// See `va_start` above.
val
}

fn retag_mem(&mut self, _place: Self::Value, _info: &RetagInfo<Self::Value>) {
bug!("retag not supported")
}

fn retag_reg(&mut self, _ptr: Self::Value, _info: &RetagInfo<Self::Value>) -> Self::Value {
bug!("retag not supported")
}
}

impl Builder<'_, '_> {
Expand Down
2 changes: 1 addition & 1 deletion crates/rustc_codegen_spirv/src/codegen_cx/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ impl<'tcx> CodegenCx<'tcx> {
// HACK(eddyb) the `ConstCodegenMethods` trait no longer guarantees the
// lifetime that `alloc` is interned for, but since it *is* interned,
// we can cheaply recover it (see also the `ty::Lift` infrastructure).
let alloc = self.tcx.lift(alloc).unwrap();
let alloc = self.tcx.lift(alloc);

let void_type = SpirvType::Void.def(DUMMY_SP, self);
self.def_constant(void_type, SpirvConst::ConstDataFromAlloc(alloc))
Expand Down
2 changes: 1 addition & 1 deletion crates/rustc_codegen_spirv/src/custom_insts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ lazy_static! {
/// achieved by hashing the `SCHEMA` constant from `def_custom_insts!` below
pub static ref CUSTOM_EXT_INST_SET: String = {
let schema_hash = {
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::stable_hash::StableHasher;
use rustc_hashes::Hash128;
use std::hash::Hash;

Expand Down
46 changes: 25 additions & 21 deletions crates/rustc_codegen_spirv/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// HACK(eddyb) start of `rustc_codegen_ssa` crate-level attributes (see `build.rs`).
#![feature(box_patterns)]
#![feature(deref_patterns)]
#![feature(file_buffered)]
#![feature(negative_impls)]
#![feature(string_from_utf8_lossy_owned)]
Expand Down Expand Up @@ -157,7 +157,6 @@ use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_errors::DiagCtxtHandle;
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::mir::pretty::write_mir_pretty;
use rustc_middle::mono::{MonoItem, MonoItemData};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{InstanceKind, TyCtxt};
Expand All @@ -166,25 +165,31 @@ use rustc_session::config::{self, OutputFilenames, OutputType};
use rustc_span::symbol::Symbol;
use std::any::Any;
use std::fs;
use std::io::Cursor;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use tracing::error;

fn dump_mir(tcx: TyCtxt<'_>, mono_items: &[(MonoItem<'_>, MonoItemData)], path: &Path) {
fs::create_dir_all(path.parent().unwrap()).unwrap();
let mut file = fs::File::create(path).unwrap();
fn dump_mir<'tcx>(
tcx: TyCtxt<'tcx>,
mono_items: &[(MonoItem<'tcx>, MonoItemData)],
path: &Path,
) -> std::io::Result<()> {
use rustc_middle::mir::pretty::MirWriter;
fs::create_dir_all(path.parent().unwrap())?;
let mut file = fs::File::create(path)?;
for &(mono_item, _) in mono_items {
if let MonoItem::Fn(instance) = mono_item
&& matches!(instance.def, InstanceKind::Item(_))
{
let mut mir = Cursor::new(Vec::new());
if write_mir_pretty(tcx, Some(instance.def_id()), &mut mir).is_ok() {
writeln!(file, "{}", String::from_utf8(mir.into_inner()).unwrap()).unwrap();
}
let mut w = Vec::new();
let writer = MirWriter::new(tcx);
writer.write_mir_fn(tcx.instance_mir(instance.def), &mut w)?;
file.write_all(w.as_slice())?;
writeln!(file)?;
}
}
Ok(())
}

#[derive(Clone)]
Expand Down Expand Up @@ -243,20 +248,21 @@ impl CodegenBackend for SpirvCodegenBackend {
.unwrap_or_else(|| sess.target.cpu.to_string())
}

fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>, crate_info: &CrateInfo) -> Box<dyn Any> {
Box::new(maybe_pqp_cg_ssa::base::codegen_crate(Self, tcx, crate_info))
fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any> {
Box::new(maybe_pqp_cg_ssa::base::codegen_crate(Self, tcx))
}

fn join_codegen(
&self,
ongoing_codegen: Box<dyn Any>,
sess: &Session,
_outputs: &OutputFilenames,
crate_info: &CrateInfo,
) -> (CompiledModules, FxIndexMap<WorkProductId, WorkProduct>) {
ongoing_codegen
.downcast::<OngoingCodegen<Self>>()
.expect("Expected OngoingCodegen, found Box<Any>")
.join(sess)
.join(sess, crate_info)
}

fn link(
Expand Down Expand Up @@ -324,16 +330,16 @@ impl WriteBackendMethods for SpirvCodegenBackend {
// entirety of `crate::linker` into this stage (lacking diagnostics may be
// an issue - it's surprising `CodegenBackend::link` has `Session` at all).
fn optimize_and_codegen_fat_lto(
_sess: &Session,
cgcx: &CodegenContext,
_prof: &SelfProfilerRef,
_shared_emitter: &SharedEmitter,
_tm_factory: TargetMachineFactoryFn<Self>,
_exported_symbols_for_lto: &[String],
_each_linked_rlib_for_lto: &[PathBuf],
_modules: Vec<FatLtoInput<Self>>,
) -> CompiledModule {
assert!(
cgcx.lto == rustc_session::config::Lto::Fat,
cgcx.lto == config::Lto::Fat,
"`optimize_and_codegen_fat_lto` should \
only be invoked due to `-Clto` (or equivalent)"
);
Expand Down Expand Up @@ -396,11 +402,9 @@ impl WriteBackendMethods for SpirvCodegenBackend {
let name = module.name;
let module_buffer = Self::serialize_module(module.module_llvm, false);

let path = cgcx.output_filenames.temp_path_for_cgu(
OutputType::Object,
&name,
cgcx.invocation_temp.as_deref(),
);
let path = cgcx
.output_filenames
.temp_path_for_cgu(OutputType::Object, &name);
fs::write(&path, module_buffer.as_bytes()).unwrap();

CompiledModule {
Expand Down Expand Up @@ -451,7 +455,7 @@ impl ExtraBackendMethods for SpirvCodegenBackend {
let mono_items = cgu.items_in_deterministic_order(cx.tcx);

if let Some(dir) = &cx.codegen_args.dump_mir {
dump_mir(tcx, mono_items.as_slice(), &dir.join(cgu_name.to_string()));
dump_mir(tcx, mono_items.as_slice(), &dir.join(cgu_name.to_string())).unwrap();
}

for &(mono_item, mono_item_data) in mono_items.iter() {
Expand Down
8 changes: 2 additions & 6 deletions crates/rustc_codegen_spirv/src/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,8 @@ pub fn link(

if outputs.outputs.should_codegen() {
let out_filename = out_filename(sess, crate_type, outputs, Symbol::intern(crate_name));
let out_filename_file_for_writing = out_filename.file_for_writing(
outputs,
OutputType::Exe,
crate_name,
sess.invocation_temp.as_deref(),
);
let out_filename_file_for_writing =
out_filename.file_for_writing(outputs, OutputType::Exe, crate_name);
match crate_type {
CrateType::Rlib => {
link_rlib(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub fn destructure_composites(function: &mut Function) {

// Transitive closure computation
let mut closed_rewrite_rules = rewrite_rules.clone();
for (_, value) in closed_rewrite_rules.iter_mut() {
for value in closed_rewrite_rules.values_mut() {
while let Some(next) = rewrite_rules.get(value) {
*value = *next;
}
Expand Down
Loading