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
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-09-25"
channel = "nightly-2026-10-28"
components = ["rust-src", "rustc-dev", "llvm-tools"]
# commit_hash = f7575a9da8e4a4fca3b5668d5a2ea7476db44b3f"#;
# commit_hash = 41089d07a0a2afc16adfe28a760d94d73d7298a4"#;

fn rustc_output(arg: &str) -> Result<String, Box<dyn Error>> {
let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into());
Expand Down
11 changes: 7 additions & 4 deletions crates/rustc_codegen_spirv/src/abi.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! This file is responsible for translation from rustc tys (`TyAndLayout`) to spir-v types. It's
//! surprisingly difficult.

use crate::attr::{AggregatedSpirvAttributes, IntrinsicType};
use crate::attr::{AggregatedSpirvAttributes, IntrinsicType, TyCtxtAttrExt};
use crate::codegen_cx::CodegenCx;
use crate::maybe_pqp_cg_ssa::traits::ConstCodegenMethods as _;
use crate::spirv_type::{SpirvType, name_type_id};
Expand All @@ -14,7 +14,6 @@ use rustc_abi::{
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::ErrorGuaranteed;
use rustc_index::Idx;
use rustc_middle::ty::consts::ConstExt;
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
use rustc_middle::ty::{
self, Const, CoroutineArgs, CoroutineArgsExt as _, FloatTy, IntTy, PolyFnSig, Ty, TyCtxt,
Expand Down Expand Up @@ -290,7 +289,9 @@ impl<'tcx> ConvSpirvType<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
let return_type = match self.ret.mode {
PassMode::Ignore => SpirvType::Void.def(span, cx),
PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.spirv_type(span, cx),
PassMode::Cast { .. } | PassMode::Indirect { .. } => span_bug!(
PassMode::Cast { .. }
| PassMode::Indirect { .. }
| PassMode::IndirectUnsized { .. } => span_bug!(
span,
"query hooks should've made this `PassMode` impossible: {:#?}",
self.ret
Expand All @@ -306,7 +307,9 @@ impl<'tcx> ConvSpirvType<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
argument_types.push(scalar_pair_element_backend_type(cx, span, arg.layout, 1));
continue;
}
PassMode::Cast { .. } | PassMode::Indirect { .. } => span_bug!(
PassMode::Cast { .. }
| PassMode::Indirect { .. }
| PassMode::IndirectUnsized { .. } => span_bug!(
span,
"query hooks should've made this `PassMode` impossible: {:#?}",
arg
Expand Down
37 changes: 32 additions & 5 deletions crates/rustc_codegen_spirv/src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
use crate::codegen_cx::CodegenCx;
use crate::symbols::Symbols;
use rspirv::spirv::{BuiltIn, ExecutionMode, ExecutionModel, StorageClass};
use rustc_ast::attr::AttributeExt;
use rustc_ast::{LitKind, MetaItemInner, MetaItemLit};
use rustc_attr_ir::Attribute;
use rustc_attr_ir::target::{MethodKind, Target};
use rustc_hir as hir;
use rustc_hir::def_id::LocalModId;
use rustc_hir::def_id::{DefId, LocalModId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{CRATE_HIR_ID, HirId};
use rustc_middle::hir::nested_filter;
Expand Down Expand Up @@ -577,7 +578,7 @@ where
} else {
// #[rust_gpu::spirv]
Err((
attr.span(),
attr.path_span().unwrap(),
"#[spirv(..)] attribute must have at least one argument"
.to_string(),
))
Expand All @@ -589,11 +590,11 @@ where
// #[rust_gpu::vector::v1]
Some(version) if *version == sym.v1 => {
Ok(SmallVec::from_iter([
Ok((attr.span(), SpirvAttribute::IntrinsicType(IntrinsicType::Vector)))
Ok((attr.path_span().unwrap(), SpirvAttribute::IntrinsicType(IntrinsicType::Vector)))
]))
},
_ => Err((
attr.span(),
attr.path_span().unwrap(),
"unknown `rust_gpu::vector` version, expected `rust_gpu::vector::v1`"
.to_string(),
)),
Expand All @@ -603,7 +604,7 @@ where
// #[rust_gpu::...] but not a know version
let spirv = sym.spirv_attr_with_version.as_str();
Err((
attr.span(),
attr.path_span().unwrap(),
format!("unknown `rust_gpu` attribute, expected `rust_gpu::{spirv}`. \
Do the versions of `spirv-std` and `rustc_codegen_spirv` match?"),
))
Expand Down Expand Up @@ -900,3 +901,29 @@ fn parse_entry_attrs(
}
Ok(entry)
}

pub trait TyCtxtAttrExt<'tcx>: Sized {
/// Removed in https://github.com/rust-lang/rust/pull/164744
fn get_attrs_by_path(
self,
did: DefId,
attr: &[Symbol],
) -> impl Iterator<Item = &'tcx Attribute>;
}

impl<'tcx> TyCtxtAttrExt<'tcx> for TyCtxt<'tcx> {
fn get_attrs_by_path(
self,
did: DefId,
attr: &[Symbol],
) -> impl Iterator<Item = &'tcx Attribute> {
let filter_fn = move |a: &&Attribute| a.path_matches(attr);
if let Some(did) = did.as_local() {
self.hir_attrs(self.local_def_id_to_hir_id(did))
.iter()
.filter(filter_fn)
} else {
self.attrs_for_def(did).iter().filter(filter_fn)
}
}
}
11 changes: 9 additions & 2 deletions crates/rustc_codegen_spirv/src/builder/builder_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ use rustc_codegen_ssa::traits::{
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{self, AtomicOrdering, Ty};
use rustc_span::Span;
use rustc_span::bug;
use rustc_span::{DUMMY_SP, Span};
use rustc_target::callconv::FnAbi;
use smallvec::SmallVec;
use std::iter::{self, empty};
Expand Down Expand Up @@ -1870,7 +1870,14 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
self.declare_func_local_var(ty, align)
}
fn alloca(&mut self, size: Size, align: Align) -> Self::Value {
self.declare_func_local_var(self.type_array(self.type_i8(), size.bytes()), align)
self.declare_func_local_var(
SpirvType::Array {
element: self.type_i8(),
count: self.constant_u64(DUMMY_SP, size.bytes()),
}
.def(DUMMY_SP, self),
align,
)
}

fn load(&mut self, ty: Self::Type, ptr: Self::Value, _align: Align) -> Self::Value {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
PassMode::Indirect { .. } => {
self.fatal("PassMode::Indirect not supported in codegen_buffer_load_intrinsic")
}
PassMode::IndirectUnsized { .. } => {
self.fatal("PassMode::Indirect not supported in codegen_buffer_load_intrinsic")
}
}

// Signature: fn load<T>(array: &[u32], index: u32) -> T;
Expand Down Expand Up @@ -379,6 +382,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
PassMode::Indirect { .. } => {
self.fatal("PassMode::Indirect not supported in codegen_buffer_store_intrinsic")
}
PassMode::IndirectUnsized { .. } => self
.fatal("PassMode::IndirectUnsized not supported in codegen_buffer_store_intrinsic"),
};
let expected_args = if is_pair { 5 } else { 4 };
if args.len() != expected_args {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ impl<'a, 'tcx> CodegenPanic<'a, 'tcx> for FormatArgsResult<'tcx> {
let force_warn = |span, msg| -> rustc_errors::Diag<'_> {
rustc_errors::Diag::new(
builder.tcx.dcx(),
rustc_errors::Level::ForceWarning,
rustc_errors::Level::Warning(None),
msg,
)
.with_span(span)
Expand Down
38 changes: 15 additions & 23 deletions crates/rustc_codegen_spirv/src/builder/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
}

sym::breakpoint => {
self.abort();
self.abort_immediate();
assert!(result.layout.ty.is_unit());
return IntrinsicResult::WroteIntoPlace;
}
Expand Down Expand Up @@ -156,16 +156,14 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
result
}

sym::sqrtf32 | sym::sqrtf64 | sym::sqrtf128 => {
self.gl_op(GLOp::Sqrt, ret_ty, [args[0].immediate()])
}
sym::powif32 | sym::powif64 | sym::powif128 => {
sym::sqrt => self.gl_op(GLOp::Sqrt, ret_ty, [args[0].immediate()]),
sym::powi => {
let float = self.sitofp(args[1].immediate(), args[0].immediate().ty);
self.gl_op(GLOp::Pow, ret_ty, [args[0].immediate(), float])
}
sym::sin => self.gl_op(GLOp::Sin, ret_ty, [args[0].immediate()]),
sym::cos => self.gl_op(GLOp::Cos, ret_ty, [args[0].immediate()]),
sym::powf32 | sym::powf64 | sym::powf128 => self.gl_op(
sym::powf => self.gl_op(
GLOp::Pow,
ret_ty,
[args[0].immediate(), args[1].immediate()],
Expand All @@ -181,7 +179,7 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
let ln = self.gl_op(GLOp::Log, ret_ty, [args[0].immediate()]);
self.fmul(mul, ln)
}
sym::fmaf32 | sym::fmaf64 | sym::fmaf128 => self.gl_op(
sym::fma => self.gl_op(
GLOp::Fma,
ret_ty,
[
Expand All @@ -206,21 +204,11 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
let sign = args[1].immediate();
self.copysign(val, sign)
}
sym::floorf32 | sym::floorf64 | sym::floorf128 => {
self.gl_op(GLOp::Floor, ret_ty, [args[0].immediate()])
}
sym::ceilf32 | sym::ceilf64 | sym::ceilf128 => {
self.gl_op(GLOp::Ceil, ret_ty, [args[0].immediate()])
}
sym::truncf32 | sym::truncf64 | sym::truncf128 => {
self.gl_op(GLOp::Trunc, ret_ty, [args[0].immediate()])
}
sym::round_ties_even_f32 | sym::round_ties_even_f64 | sym::round_ties_even_f128 => {
self.gl_op(GLOp::RoundEven, ret_ty, [args[0].immediate()])
}
sym::roundf32 | sym::roundf64 | sym::roundf128 => {
self.gl_op(GLOp::Round, ret_ty, [args[0].immediate()])
}
sym::floor => self.gl_op(GLOp::Floor, ret_ty, [args[0].immediate()]),
sym::ceil => self.gl_op(GLOp::Ceil, ret_ty, [args[0].immediate()]),
sym::trunc => self.gl_op(GLOp::Trunc, ret_ty, [args[0].immediate()]),
sym::round_ties_even => self.gl_op(GLOp::RoundEven, ret_ty, [args[0].immediate()]),
sym::round => self.gl_op(GLOp::Round, ret_ty, [args[0].immediate()]),

sym::rotate_left | sym::rotate_right => {
let is_left = name == sym::rotate_left;
Expand Down Expand Up @@ -376,7 +364,7 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
bug!("LLVM intrinsic call not supported in SPIR-V backend: {instance:?}")
}

fn abort(&mut self) {
fn abort_immediate(&mut self) {
self.abort_with_kind_and_message_debug_printf("abort", "intrinsics::abort() called", []);
}

Expand All @@ -389,6 +377,10 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
cond
}

fn ctpop(&mut self, val: Self::Value) -> Self::Value {
self.count_ones(val)
}

fn type_checked_load(
&mut self,
_llvtable: Self::Value,
Expand Down
8 changes: 6 additions & 2 deletions crates/rustc_codegen_spirv/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,9 @@ impl<'a, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'tcx> {
PassMode::Pair(..) => {
OperandValue::Pair(next(self, idx), next(self, idx)).store(self, dst);
}
PassMode::Cast { .. } | PassMode::Indirect { .. } => span_bug!(
PassMode::Cast { .. }
| PassMode::Indirect { .. }
| PassMode::IndirectUnsized { .. } => span_bug!(
self.span(),
"query hooks should've made this `PassMode` impossible: {:#?}",
arg_abi
Expand All @@ -299,7 +301,9 @@ impl<'a, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'tcx> {
.val
.store(self, dst);
}
PassMode::Cast { .. } | PassMode::Indirect { .. } => span_bug!(
PassMode::Cast { .. }
| PassMode::Indirect { .. }
| PassMode::IndirectUnsized { .. } => span_bug!(
self.span(),
"query hooks should've made this `PassMode` impossible: {:#?}",
arg_abi
Expand Down
2 changes: 1 addition & 1 deletion crates/rustc_codegen_spirv/src/codegen_cx/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::maybe_pqp_cg_ssa as rustc_codegen_ssa;

use super::{CodegenCx, FmtArgsCtor};
use crate::abi::ConvSpirvType;
use crate::attr::AggregatedSpirvAttributes;
use crate::attr::{AggregatedSpirvAttributes, TyCtxtAttrExt};
use crate::builder_spirv::{SpirvConst, SpirvFunctionCursor, SpirvValue, SpirvValueExt};
use crate::custom_decorations::{CustomDecoration, SrcLocDecoration};
use crate::spirv_type::SpirvType;
Expand Down
9 changes: 2 additions & 7 deletions crates/rustc_codegen_spirv/src/codegen_cx/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,8 @@ impl BaseTypeCodegenMethods for CodegenCx<'_> {
fn type_f128(&self) -> Self::Type {
SpirvType::Float(128).def(DUMMY_SP, self)
}

fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type {
SpirvType::Array {
element: ty,
count: self.constant_u64(DUMMY_SP, len),
}
.def(DUMMY_SP, self)
fn type_ppcf128(&self) -> Self::Type {
panic!("ppcf128 is unsupported")
}

fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::FunctionSignature {
Expand Down
7 changes: 4 additions & 3 deletions crates/rustc_codegen_spirv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@ use rustc_middle::mono::{MonoItem, MonoItemData};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{InstanceKind, TyCtxt};
use rustc_session::config::{self, OutputFilenames, OutputType};
use rustc_session::{CodegenBackendInit, EarlySession, IncrCompSession, Session};
use rustc_session::{
BorrowedIncrCompSession, CodegenBackendInit, EarlySession, IncrCompSession, Session,
};
use rustc_span::symbol::Symbol;
use std::any::Any;
use std::fs;
Expand Down Expand Up @@ -349,6 +351,7 @@ impl WriteBackendMethods for SpirvCodegenBackend {
fn run_thin_lto(
_cgcx: &CodegenContext,
_prof: &SelfProfilerRef,
_incr_comp_session: Option<&BorrowedIncrCompSession>,
_dcx: DiagCtxtHandle<'_>,
_exported_symbols_for_lto: &[String],
_each_linked_rlib_for_lto: &[PathBuf],
Expand Down Expand Up @@ -385,7 +388,6 @@ impl WriteBackendMethods for SpirvCodegenBackend {
.unwrap(),
name: thin_module.name().to_string(),
kind: ModuleKind::Regular,
thin_lto_buffer: None,
};
Self::optimize_common(cgcx, &mut module);
Self::codegen(cgcx, prof, shared_emitter, module, &cgcx.module_config)
Expand Down Expand Up @@ -498,7 +500,6 @@ impl ExtraBackendMethods for SpirvCodegenBackend {
name: cgu_name.to_string(),
module_llvm: cx.finalize_module(),
kind: ModuleKind::Regular,
thin_lto_buffer: None,
},
0,
)
Expand Down
2 changes: 1 addition & 1 deletion crates/rustc_codegen_spirv/src/linker/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ fn link_with_linker_opts(
unreachable!("failed to parse test rustc args")
}
};
let sopts = rustc_session::config::build_session_options(&mut early_dcx, &matches);
let sopts = rustc_session::config::build_session_options(&mut early_dcx, &matches, false);

let target = SpirvTarget::UNIVERSAL_1_0.rustc_target();
let sm_inputs = rustc_span::source_map::SourceMapInputs {
Expand Down
4 changes: 2 additions & 2 deletions crates/spirv-std/src/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ impl f32 {
#[inline]
#[rustc_allow_incoherent_impl]
pub fn powi(self, n: i32) -> f32 {
intrinsics::powif32(self, n)
intrinsics::powi(self, n)
}
}

Expand All @@ -22,7 +22,7 @@ impl f64 {
#[inline]
#[rustc_allow_incoherent_impl]
pub fn powi(self, n: i32) -> f64 {
intrinsics::powif64(self, n)
intrinsics::powi(self, n)
}
}

Expand Down
4 changes: 2 additions & 2 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[toolchain]
channel = "nightly-2026-09-25"
channel = "nightly-2026-10-28"
components = ["rust-src", "rustc-dev", "llvm-tools"]
# commit_hash = f7575a9da8e4a4fca3b5668d5a2ea7476db44b3f
# commit_hash = 41089d07a0a2afc16adfe28a760d94d73d7298a4

# Whenever changing the nightly channel, update the commit hash above, and
# change `REQUIRED_RUST_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` too.
Loading
Loading