Skip to content
Draft
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 @@ -45,7 +45,6 @@ rustflags = [
"-Wclippy::flat_map_option",
"-Wclippy::float_cmp_const",
"-Wclippy::fn_params_excessive_bools",
"-Wclippy::from_iter_instead_of_collect",
"-Wclippy::if_let_mutex",
"-Wclippy::implicit_clone",
"-Wclippy::imprecise_flops",
Expand Down
32 changes: 30 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-05-22"
channel = "nightly-2026-07-03"
components = ["rust-src", "rustc-dev", "llvm-tools"]
# commit_hash = e96c36b6f76833388c519561d145492d2c08db4e"#;
# commit_hash = c397dae808f70caebab1fc4e11b3edf7e59f58c7"#;

fn rustc_output(arg: &str) -> Result<String, Box<dyn Error>> {
let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into());
Expand Down Expand Up @@ -256,6 +256,34 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {",
);
}

// HACK(firestar99): Undo code cleanup that prevents passing ScalarPairs as `PassMode::Direct`
// https://github.com/rust-lang/rust/commit/dfc475d018c780475ea962f15d86cfa05a50a148
if relative_path == Path::new("src/mir/mod.rs") {
src = src.replace(
"
debug_assert!(bx.is_backend_immediate(arg.layout));
return local(OperandRef {
val: OperandValue::Immediate(llarg),
layout: arg.layout,
move_annotation: None,
});",
"
return local(OperandRef::from_immediate_or_packed_pair(
bx, llarg, arg.layout,
));",
);
src = src.replace("fx.fill_function_debug_context(&mut start_bx);", "");
}
if relative_path == Path::new("src/mir/block.rs") {
src = src.replace(
r#"
PassMode::Direct(_) => (op.immediate(), arg.layout.align.abi, false),
PassMode::Ignore | PassMode::Pair(..) => unreachable!("handled above"),"#,
"\
_ => (op.immediate_or_packed_pair(bx), arg.layout.align.abi, false),",
);
}

fs::write(out_path, src)?;
}
}
Expand Down
10 changes: 8 additions & 2 deletions crates/rustc_codegen_spirv/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,10 @@ impl<'tcx> ConvSpirvType<'tcx> for TyAndLayout<'tcx> {
// Note: We can't use auto_struct_layout here because the spirv types here might be undefined due to
// recursive pointer types.
let a_offset = Size::ZERO;
let b_offset = a.primitive().size(cx).align_to(b.primitive().align(cx).abi);
let b_offset = a
.primitive()
.size(cx)
.align_to(b.primitive().default_align(cx).abi);
let a = trans_scalar(cx, span, *self, a, a_offset);
let b = trans_scalar(cx, span, *self, b, b_offset);
let size = if self.is_unsized() {
Expand Down Expand Up @@ -471,7 +474,10 @@ pub fn scalar_pair_element_backend_type<'tcx>(
};
let offset = match index {
0 => Size::ZERO,
1 => a.primitive().size(cx).align_to(b.primitive().align(cx).abi),
1 => a
.primitive()
.size(cx)
.align_to(b.primitive().default_align(cx).abi),
_ => unreachable!(),
};
trans_scalar(cx, span, ty, [a, b][index], offset)
Expand Down
11 changes: 8 additions & 3 deletions crates/rustc_codegen_spirv/src/builder/builder_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1854,7 +1854,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
self.bitcast(loaded_val, ty)
}

fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value {
fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value, _align: Align) -> Self::Value {
// TODO: Implement this
let result = self.load(ty, ptr, Align::from_bytes(0).unwrap());
self.zombie(result.def(self), "volatile load is not supported yet");
Expand Down Expand Up @@ -1909,7 +1909,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
let b_offset = a
.primitive()
.size(self)
.align_to(b.primitive().align(self).abi);
.align_to(b.primitive().default_align(self).abi);

let mut load = |i, scalar: Scalar, align| {
let llptr = if i == 0 {
Expand Down Expand Up @@ -1993,7 +1993,8 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
align: Align,
flags: MemFlags,
) -> Self::Value {
if flags != MemFlags::empty() {
let allowed_flags = MemFlags::CAPTURES_READ_ONLY;
if !(flags & !allowed_flags).is_empty() {
self.err(format!("store_with_flags is not supported yet: {flags:?}"));
}
self.store(val, ptr, align)
Expand Down Expand Up @@ -3484,4 +3485,8 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
fn alloca_with_ty(&mut self, _layout: TyAndLayout<'tcx>) -> Self::Value {
bug!("scalable alloca is not supported in SPIR-V backend")
}

fn vscale(&mut self, _ty: Self::Type) -> Self::Value {
self.fatal("scalable vectors not supported");
}
}
40 changes: 21 additions & 19 deletions crates/rustc_codegen_spirv/src/builder/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ use crate::custom_insts::CustomInst;
use crate::spirv_type::SpirvType;
use rspirv::dr::Operand;
use rspirv::spirv::GlslStd450Op as GLOp;
use rustc_abi::Align;
use rustc_codegen_ssa::RetagInfo;
use rustc_codegen_ssa::mir::IntrinsicResult;
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
use rustc_codegen_ssa::traits::{BuilderMethods, IntrinsicCallBuilderMethods};
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{FnDef, Instance, Ty, TyKind, TypingEnv};
Expand Down Expand Up @@ -64,9 +66,14 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
&mut self,
instance: Instance<'tcx>,
args: &[OperandRef<'tcx, Self::Value>],
result: PlaceRef<'tcx, Self::Value>,
result_layout: ty::layout::TyAndLayout<'tcx>,
result_place: Option<PlaceValue<Self::Value>>,
_span: Span,
) -> Result<(), ty::Instance<'tcx>> {
) -> IntrinsicResult<'tcx, Self::Value> {
let result = PlaceRef {
val: result_place.unwrap(),
layout: result_layout,
};
let callee_ty = instance.ty(self.tcx, TypingEnv::fully_monomorphized());

let (def_id, fn_args) = match *callee_ty.kind() {
Expand Down Expand Up @@ -95,17 +102,18 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
sym::breakpoint => {
self.abort();
assert!(result.layout.ty.is_unit());
return Ok(());
return IntrinsicResult::WroteIntoPlace;
}

sym::volatile_load | sym::unaligned_volatile_load => {
let ptr = args[0].immediate();
let layout = self.layout_of(fn_args.type_at(0));
let load = self.volatile_load(layout.spirv_type(self.span(), self), ptr);
let load =
self.volatile_load(layout.spirv_type(self.span(), self), ptr, Align::ONE);
if !result.layout.is_zst() {
self.store(load, result.val.llval, result.val.align);
}
return Ok(());
return IntrinsicResult::WroteIntoPlace;
}

sym::prefetch_read_data
Expand All @@ -114,7 +122,7 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
| sym::prefetch_write_instruction => {
// ignore
assert!(result.layout.ty.is_unit());
return Ok(());
return IntrinsicResult::WroteIntoPlace;
}

sym::saturating_add => {
Expand Down Expand Up @@ -352,7 +360,10 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {

_ => {
// Call the fallback body instead of generating the intrinsic code
return Err(ty::Instance::new_raw(instance.def_id(), instance.args));
return IntrinsicResult::Fallback(Instance::new_raw(
instance.def_id(),
instance.args,
));
}
};

Expand All @@ -368,7 +379,7 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
.val
.store(self, result);
}
Ok(())
IntrinsicResult::WroteIntoPlace
}

fn codegen_llvm_intrinsic_call(
Expand Down Expand Up @@ -402,16 +413,7 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
todo!()
}

fn va_start(&mut self, val: Self::Value) -> Self::Value {
// SPIR-V backend has no variadic ABI support; keep the placeholder
// operand unchanged so MIR lowering can proceed without crashing.
val
}

fn va_end(&mut self, val: Self::Value) -> Self::Value {
// See `va_start` above.
val
}
fn va_start(&mut self, _val: Self::Value) {}

fn retag_mem(&mut self, _place: Self::Value, _info: &RetagInfo<Self::Value>) {
bug!("retag not supported")
Expand Down
68 changes: 53 additions & 15 deletions crates/rustc_codegen_spirv/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub mod libm_intrinsics;
mod spirv_asm;

pub use ext_inst::ExtInst;
use rustc_span::DUMMY_SP;
use rustc_span::{BytePos, DUMMY_SP, SourceFile, Symbol};
pub use spirv_asm::InstructionTable;

// HACK(eddyb) avoids rewriting all of the imports (see `lib.rs` and `build.rs`).
Expand Down Expand Up @@ -185,24 +185,15 @@ impl<'a, 'tcx> DebugInfoBuilderMethods<'_> for Builder<'a, 'tcx> {
_indirect_offsets: &[Size],
_fragment: &Option<Range<Size>>,
) {
todo!()
}

fn set_dbg_loc(&mut self, _: Self::DILocation) {
todo!()
}
fn set_dbg_loc(&mut self, _: Self::DILocation) {}

fn clear_dbg_loc(&mut self) {
todo!()
}
fn clear_dbg_loc(&mut self) {}

fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) {
todo!()
}
fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) {}

fn set_var_name(&mut self, _value: Self::Value, _name: &str) {
todo!()
}
fn set_var_name(&mut self, _value: Self::Value, _name: &str) {}

fn dbg_var_value(
&mut self,
Expand All @@ -216,7 +207,54 @@ impl<'a, 'tcx> DebugInfoBuilderMethods<'_> for Builder<'a, 'tcx> {
// if this is a fragment of a composite `DIVariable`.
_fragment: &Option<Range<Size>>,
) {
todo!()
}

fn dbg_scope_fn(
&mut self,
_instance: Instance<'_>,
_fn_abi: &FnAbi<'_, Ty<'_>>,
_maybe_definition_llfn: Option<Self::Function>,
) -> Self::DIScope {
}

fn dbg_create_lexical_block(
&mut self,
_pos: BytePos,
_parent_scope: Self::DIScope,
) -> Self::DIScope {
}

fn dbg_location_clone_with_discriminator(
&mut self,
_loc: Self::DILocation,
_discriminator: u32,
) -> Option<Self::DILocation> {
None
}

fn dbg_loc(
&mut self,
_scope: Self::DIScope,
_inlined_at: Option<Self::DILocation>,
_span: Span,
) -> Self::DILocation {
}

fn extend_scope_to_file(
&mut self,
_scope_metadata: Self::DIScope,
_file: &SourceFile,
) -> Self::DIScope {
}

fn create_dbg_var(
&mut self,
_variable_name: Symbol,
_variable_type: Ty<'_>,
_scope_metadata: Self::DIScope,
_variable_kind: rustc_codegen_ssa::mir::debuginfo::VariableKind,
_span: Span,
) -> Self::DIVariable {
}
}

Expand Down
16 changes: 14 additions & 2 deletions crates/rustc_codegen_spirv/src/codegen_cx/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use crate::spirv_type::SpirvType;
use itertools::Itertools as _;
use rspirv::spirv::Word;
use rustc_abi::{self as abi, AddressSpace, Float, HasDataLayout, Integer, Primitive, Size};
use rustc_codegen_ssa::traits::{ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods};
use rustc_codegen_ssa::traits::{
ConstCodegenMethods, MiscCodegenMethods, PacMetadata, StaticCodegenMethods,
};
use rustc_middle::mir::interpret::{AllocError, ConstAllocation, GlobalAlloc, Scalar, alloc_range};
use rustc_middle::ty::layout::LayoutOf;
use rustc_span::{DUMMY_SP, Span};
Expand Down Expand Up @@ -226,6 +228,16 @@ impl ConstCodegenMethods for CodegenCx<'_> {
self.builder.lookup_const_scalar(v)
}

fn scalar_to_backend_with_pac(
&self,
cv: Scalar,
layout: rustc_abi::Scalar,
ty: Self::Type,
_pac: Option<PacMetadata>,
) -> Self::Value {
self.scalar_to_backend(cv, layout, ty)
}

fn scalar_to_backend(
&self,
scalar: Scalar,
Expand Down Expand Up @@ -268,7 +280,7 @@ impl ConstCodegenMethods for CodegenCx<'_> {
(value, AddressSpace::ZERO)
}
GlobalAlloc::Function { instance } => (
self.get_fn_addr(instance),
self.get_fn_addr(instance, None),
self.data_layout().instruction_address_space,
),
GlobalAlloc::VTable(vty, dyn_ty) => {
Expand Down
2 changes: 1 addition & 1 deletion crates/rustc_codegen_spirv/src/codegen_cx/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl<'tcx> CodegenCx<'tcx> {
self.get_fn(entry_instance).ty,
None,
Some(entry_fn_abi),
self.get_fn_addr(entry_instance),
self.get_fn_addr(entry_instance, None),
&call_args,
None,
None,
Expand Down
Loading
Loading