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
1 change: 0 additions & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ rustflags = [
"-Wclippy::string_add_assign",
"-Wclippy::string_add",
"-Wclippy::string_lit_as_bytes",
"-Wclippy::string_to_string",
"-Wclippy::todo",
"-Wclippy::trait_duplication_in_bounds",
"-Wclippy::unimplemented",
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 11 additions & 3 deletions crates/rustc_codegen_spirv-types/src/target_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ pub enum TargetSpecVersion {
/// Some later version requires them.
/// Some earlier version fails with them (notably our 0.9.0 release).
Rustc_1_76_0,
/// rustc 1.93 requires that the value of "target-pointer-width" is no longer a string but u16
Rustc_1_93_0,
}

impl TargetSpecVersion {
Expand All @@ -39,7 +41,9 @@ 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) -> Option<Self> {
if rustc_version >= Version::new(1, 85, 0) {
if rustc_version >= Version::new(1, 93, 0) {
Some(Self::Rustc_1_93_0)
} else if rustc_version >= Version::new(1, 85, 0) {
Some(Self::Rustc_1_85_0)
} else if rustc_version >= Version::new(1, 76, 0) {
Some(Self::Rustc_1_76_0)
Expand All @@ -52,8 +56,12 @@ impl TargetSpecVersion {
pub fn format_spec(&self, target: &SpirvTarget) -> String {
let target_env = target.env();
let extra = match self {
TargetSpecVersion::Rustc_1_85_0 => r#""crt-static-respected": true,"#,
TargetSpecVersion::Rustc_1_76_0 => r#""os": "unknown","#,
_ => r#""crt-static-respected": true,"#,
};
let target_pointer_width = match self {
TargetSpecVersion::Rustc_1_76_0 | TargetSpecVersion::Rustc_1_85_0 => "\"32\"",
TargetSpecVersion::Rustc_1_93_0 => "32",
};
format!(
r#"{{
Expand All @@ -80,7 +88,7 @@ impl TargetSpecVersion {
{extra}
"panic-strategy": "abort",
"simd-types-indirect": false,
"target-pointer-width": "32"
"target-pointer-width": {target_pointer_width}
}}"#
)
}
Expand Down
1 change: 1 addition & 0 deletions crates/rustc_codegen_spirv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ tracing-tree = "0.4.0"

[dev-dependencies]
pretty_assertions = "1.0"
termcolor = "1.1.3"

# HACK(eddyb) can't re-introduce deps of `rustc_codegen_ssa`, for `pqp_cg_ssa`
# (see `build.rs`).
Expand Down
19 changes: 17 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-2025-06-30"
channel = "nightly-2025-10-28"
components = ["rust-src", "rustc-dev", "llvm-tools"]
# commit_hash = 35f6036521777bdc0dcea1f980be4c192962a168"#;
# commit_hash = adaa838976ff99a4f0661136322f64cb466b58a0"#;

fn rustc_output(arg: &str) -> Result<String, Box<dyn Error>> {
let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into());
Expand Down Expand Up @@ -198,6 +198,13 @@ mod win {",
for link_path in raw_dylib::",
);
}
src = src.replace(
"
for (link_path, as_needed) in raw_dylib::",
"
#[cfg(any())]
for (link_path, as_needed) in raw_dylib::",
);
if relative_path == Path::new("src/back/metadata.rs") {
// HACK(eddyb) remove `object` dependency.
src = src.replace(
Expand Down Expand Up @@ -237,6 +244,14 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {",
src = src.replace("alloca(field.size,", "typed_alloca(llfield_ty,");
}

// HACK(fee1-dead): our backend type number doesn't always match the type of the value. Should fix?
if relative_path == Path::new("src/mir/rvalue.rs") {
src = src.replace(
"debug_assert_eq!(bx.cx().val_ty(imm), from_backend_ty);",
"",
);
}

fs::write(out_path, src)?;
}
}
Expand Down
6 changes: 3 additions & 3 deletions crates/rustc_codegen_spirv/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ impl<'tcx> ConvSpirvType<'tcx> for TyAndLayout<'tcx> {
span = cx.tcx.def_span(adt.did());
}

let attrs = AggregatedSpirvAttributes::parse(cx, cx.tcx.get_attrs_unchecked(adt.did()));
let attrs = AggregatedSpirvAttributes::parse(cx, cx.tcx.get_all_attrs(adt.did()));

if let Some(intrinsic_type_attr) = attrs.intrinsic_type.map(|attr| attr.value)
&& let Ok(spirv_type) =
Expand Down Expand Up @@ -791,7 +791,7 @@ fn trans_intrinsic_type<'tcx>(
let sampled_type = match args.type_at(0).kind() {
TyKind::Int(int) => match int {
IntTy::Isize => {
SpirvType::Integer(cx.tcx.data_layout.pointer_size.bits() as u32, true)
SpirvType::Integer(cx.tcx.data_layout.pointer_size().bits() as u32, true)
.def(span, cx)
}
IntTy::I8 => SpirvType::Integer(8, true).def(span, cx),
Expand All @@ -802,7 +802,7 @@ fn trans_intrinsic_type<'tcx>(
},
TyKind::Uint(uint) => match uint {
UintTy::Usize => {
SpirvType::Integer(cx.tcx.data_layout.pointer_size.bits() as u32, false)
SpirvType::Integer(cx.tcx.data_layout.pointer_size().bits() as u32, false)
.def(span, cx)
}
UintTy::U8 => SpirvType::Integer(8, false).def(span, cx),
Expand Down
37 changes: 29 additions & 8 deletions crates/rustc_codegen_spirv/src/builder/builder_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1825,10 +1825,6 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
self.declare_func_local_var(self.type_array(self.type_i8(), size.bytes()), align)
}

fn dynamic_alloca(&mut self, _len: Self::Value, _align: Align) -> Self::Value {
self.fatal("dynamic alloca not supported yet")
}

fn load(&mut self, ty: Self::Type, ptr: Self::Value, _align: Align) -> Self::Value {
let (ptr, access_ty) = self.adjust_pointer_for_typed_access(ptr, ty);
let loaded_val = ptr.const_fold_load(self).unwrap_or_else(|| {
Expand Down Expand Up @@ -2796,6 +2792,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
_src_align: Align,
size: Self::Value,
flags: MemFlags,
_tt: Option<rustc_ast::expand::typetree::FncTree>,
) {
if flags != MemFlags::empty() {
self.err(format!(
Expand Down Expand Up @@ -2882,7 +2879,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
size: Self::Value,
flags: MemFlags,
) {
self.memcpy(dst, dst_align, src, src_align, size, flags);
self.memcpy(dst, dst_align, src, src_align, size, flags, None);
}

fn memset(
Expand Down Expand Up @@ -3128,6 +3125,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
dst: Self::Value,
src: Self::Value,
order: AtomicOrdering,
_ret_ptr: bool,
) -> Self::Value {
let ty = src.ty;

Expand Down Expand Up @@ -3253,6 +3251,10 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
// ignore
}

#[tracing::instrument(
level = "debug",
skip(self, callee_ty, _fn_attrs, fn_abi, callee, args, funclet)
)]
fn call(
&mut self,
callee_ty: Self::Type,
Expand All @@ -3263,9 +3265,6 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
funclet: Option<&Self::Funclet>,
instance: Option<ty::Instance<'tcx>>,
) -> Self::Value {
let span = tracing::span!(tracing::Level::DEBUG, "call");
let _enter = span.enter();

if funclet.is_some() {
self.fatal("TODO: Funclets are not supported");
}
Expand Down Expand Up @@ -3389,6 +3388,15 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
}
}

// HACK(fee1-dead): `MaybeUninit` uses a union which we don't have very good support yet. Replacing all calls to it
// with an `Undef` serves the same purpose and fixes compiler errors
if instance_def_id.is_some_and(|did| {
self.tcx
.is_diagnostic_item(rustc_span::sym::maybe_uninit_uninit, did)
}) {
return self.undef(result_type);
}

// Default: emit a regular function call
let args = args.iter().map(|arg| arg.def(self)).collect::<Vec<_>>();
self.emit()
Expand All @@ -3397,6 +3405,19 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
.with_type(result_type)
}

fn tail_call(
&mut self,
_llty: Self::Type,
_fn_attrs: Option<&CodegenFnAttrs>,
_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
_llfn: Self::Value,
_args: &[Self::Value],
_funclet: Option<&Self::Funclet>,
_instance: Option<ty::Instance<'tcx>>,
) {
todo!()
}

fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value {
self.intcast(val, dest_ty, false)
}
Expand Down
17 changes: 16 additions & 1 deletion crates/rustc_codegen_spirv/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ impl<'a, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'tcx> {
_direct_offset: Size,
// NB: each offset implies a deref (i.e. they're steps in a pointer chain).
_indirect_offsets: &[Size],
_fragment: Option<Range<Size>>,
_fragment: &Option<Range<Size>>,
) {
todo!()
}
Expand All @@ -203,6 +203,21 @@ impl<'a, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'tcx> {
fn set_var_name(&mut self, _value: Self::Value, _name: &str) {
todo!()
}

fn dbg_var_value(
&mut self,
_dbg_var: Self::DIVariable,
_dbg_loc: Self::DILocation,
_value: Self::Value,
_direct_offset: Size,
// NB: each offset implies a deref (i.e. they're steps in a pointer chain).
_indirect_offsets: &[Size],
// Byte range in the `dbg_var` covered by this fragment,
// if this is a fragment of a composite `DIVariable`.
_fragment: &Option<Range<Size>>,
) {
todo!()
}
}

impl<'a, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'tcx> {
Expand Down
2 changes: 1 addition & 1 deletion crates/rustc_codegen_spirv/src/builder_spirv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,7 @@ impl<'tcx> BuilderSpirv<'tcx> {
FileName::Real(name) => {
name.to_string_lossy(FileNameDisplayPreference::Remapped)
}
_ => sf.name.prefer_remapped_unconditionaly().to_string().into(),
_ => sf.name.prefer_remapped_unconditionally().to_string().into(),
};
let file_name = {
// FIXME(eddyb) it should be possible to arena-allocate a
Expand Down
29 changes: 20 additions & 9 deletions crates/rustc_codegen_spirv/src/codegen_cx/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ impl ConstCodegenMethods for CodegenCx<'_> {
self.const_uint_big(ty, i)
}
fn const_usize(&self, i: u64) -> Self::Value {
let ptr_size = self.tcx.data_layout.pointer_size.bits() as u32;
let ptr_size = self.tcx.data_layout.pointer_size().bits() as u32;
let t = SpirvType::Integer(ptr_size, false).def(DUMMY_SP, self);
self.constant_int(t, i.into())
}
Expand Down Expand Up @@ -246,7 +246,7 @@ impl ConstCodegenMethods for CodegenCx<'_> {
}
}
Scalar::Ptr(ptr, _) => {
let (prov, offset) = ptr.into_parts();
let (prov, offset) = ptr.prov_and_relative_offset();
let alloc_id = prov.alloc_id();
let (base_addr, _base_addr_space) = match self.tcx.global_alloc(alloc_id) {
GlobalAlloc::Memory(alloc) => {
Expand All @@ -263,7 +263,7 @@ impl ConstCodegenMethods for CodegenCx<'_> {
.try_read_from_const_alloc(alloc, pointee)
.unwrap_or_else(|| self.const_data_from_alloc(alloc));
let value = self.static_addr_of(init, alloc.inner().align, None);
(value, AddressSpace::DATA)
(value, AddressSpace::ZERO)
}
GlobalAlloc::Function { instance } => (
self.get_fn_addr(instance),
Expand Down Expand Up @@ -292,12 +292,24 @@ impl ConstCodegenMethods for CodegenCx<'_> {
.try_read_from_const_alloc(alloc, pointee)
.unwrap_or_else(|| self.const_data_from_alloc(alloc));
let value = self.static_addr_of(init, alloc.inner().align, None);
(value, AddressSpace::DATA)
(value, AddressSpace::ZERO)
}
GlobalAlloc::Static(def_id) => {
assert!(self.tcx.is_static(def_id));
assert!(!self.tcx.is_thread_local_static(def_id));
(self.get_static(def_id), AddressSpace::DATA)
(self.get_static(def_id), AddressSpace::ZERO)
}
GlobalAlloc::TypeId { .. } => {
return if offset.bytes() == 0 {
self.constant_null(ty)
} else {
let result = self.undef(ty);
self.zombie_no_span(
result.def_cx(self),
"pointer has non-null integer address",
);
result
};
}
};
self.const_bitcast(self.const_ptr_byte_offset(base_addr, offset), ty)
Expand Down Expand Up @@ -430,7 +442,7 @@ impl<'tcx> CodegenCx<'tcx> {
.fatal(format!("invalid size for float: {other}"));
}
}),
SpirvType::Pointer { .. } => Primitive::Pointer(AddressSpace::DATA),
SpirvType::Pointer { .. } => Primitive::Pointer(AddressSpace::ZERO),
_ => unreachable!(),
};

Expand All @@ -449,7 +461,7 @@ impl<'tcx> CodegenCx<'tcx> {
.inner()
.read_scalar(self, range, /* read_provenance */ true)
{
let (prov, _offset) = ptr.into_parts();
let (prov, _offset) = ptr.prov_and_relative_offset();
primitive = Primitive::Pointer(
self.tcx.global_alloc(prov.alloc_id()).address_space(self),
);
Expand Down Expand Up @@ -494,8 +506,7 @@ impl<'tcx> CodegenCx<'tcx> {

// HACK(eddyb) these should never happen when using
// `read_scalar`, but better not outright crash.
AllocError::ScalarSizeMismatch(_)
| AllocError::OverwritePartialPointer(_) => {
AllocError::ScalarSizeMismatch(_) => {
Err(format!("unrecognized `AllocError::{err:?}`"))
}
},
Expand Down
10 changes: 5 additions & 5 deletions crates/rustc_codegen_spirv/src/codegen_cx/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ use crate::spirv_type::SpirvType;
use itertools::Itertools;
use rspirv::spirv::{FunctionControl, LinkageType, StorageClass, Word};
use rustc_abi::Align;
use rustc_attr_data_structures::InlineAttr;
use rustc_codegen_ssa::traits::{PreDefineCodegenMethods, StaticCodegenMethods};
use rustc_hir::attrs::{InlineAttr, Linkage};
use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility};
use rustc_middle::mir::mono::{MonoItem, Visibility};
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
use rustc_middle::ty::{self, Instance, TypeVisitableExt, TypingEnv};
use rustc_span::Span;
Expand Down Expand Up @@ -133,7 +133,7 @@ impl<'tcx> CodegenCx<'tcx> {
self.set_linkage(fn_id, symbol_name.to_owned(), linkage);
}

let attrs = AggregatedSpirvAttributes::parse(self, self.tcx.get_attrs_unchecked(def_id));
let attrs = AggregatedSpirvAttributes::parse(self, self.tcx.get_all_attrs(def_id));
if let Some(entry) = attrs.entry.map(|attr| attr.value) {
// HACK(eddyb) early insert to let `shader_entry_stub` call this
// very function via `get_fn_addr`.
Expand Down Expand Up @@ -177,8 +177,8 @@ impl<'tcx> CodegenCx<'tcx> {
}

// Check if this is a From trait implementation
if let Some(impl_def_id) = self.tcx.impl_of_method(def_id)
&& let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id)
if let Some(impl_def_id) = self.tcx.impl_of_assoc(def_id)
&& let Some(trait_ref) = self.tcx.impl_opt_trait_ref(impl_def_id)
{
let trait_def_id = trait_ref.skip_binder().def_id;

Expand Down
Loading
Loading