From e7d0b6d9bf1ca05942e167e93fcf1eb6348ff144 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 7 Jul 2025 08:08:04 +0300 Subject: [PATCH 01/38] compiletests: future-proof `issue-46` against MIR optimizations. --- tests/compiletests/ui/lang/issue-46.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/compiletests/ui/lang/issue-46.rs b/tests/compiletests/ui/lang/issue-46.rs index 99a0835a95..fc64dd01d7 100644 --- a/tests/compiletests/ui/lang/issue-46.rs +++ b/tests/compiletests/ui/lang/issue-46.rs @@ -2,7 +2,7 @@ use spirv_std::spirv; -#[derive(Default)] +#[derive(Copy, Clone, Default)] struct Foo { bar: bool, baz: [[u32; 2]; 1], @@ -13,3 +13,20 @@ pub fn main() { let x = [[1; 2]; 1]; let y = [Foo::default(); 1]; } + +// HACK(eddyb) future-proofing against `[expr; 1]` -> `[expr]` +// MIR optimization (https://github.com/rust-lang/rust/pull/135322). +fn force_repeat_one() -> ([[u32; 2]; ONE], [Foo; ONE]) { + ([[1; 2]; ONE], [Foo::default(); ONE]) +} + +#[spirv(fragment)] +pub fn main_future_proof( + #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] out: &mut [[u32; 2]; 2], +) { + let (x, y) = force_repeat_one::<1>(); + + // NOTE(eddyb) further guard against optimizations by using `x` and `y`. + out[0] = x[0]; + out[1] = y[0].baz[0]; +} From c2ebd1aaa5ef6c0bf18ed68db8bcbfa8a8eedff7 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 7 May 2025 19:42:00 +0300 Subject: [PATCH 02/38] builder: always `pointercast` first before attempting to merge `OpAccessChain`s. --- .../src/builder/builder_methods.rs | 56 ++++++++++++------- .../ui/dis/panic_builtin_bounds_check.stderr | 50 +++++++++++------ 2 files changed, 70 insertions(+), 36 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index 5521aa973c..cae01bd8e5 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -854,12 +854,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // --- End Recovery Path --- + // FIXME(eddyb) the comments below might not make much sense, because this + // used to be in the "fallback path" before being moved to before merging. + // + // Before emitting the AccessChain, explicitly cast the base pointer `ptr` to + // ensure its pointee type matches the input `ty`. This is required because the + // SPIR-V `AccessChain` instruction implicitly uses the size of the base + // pointer's pointee type when applying the *first* index operand (our + // `ptr_base_index`). If `ty` and `original_pointee_ty` mismatched and we + // reached this fallback, this cast ensures SPIR-V validity. + trace!("maybe_inbounds_gep fallback path calling pointercast"); + // Cast ptr to point to `ty`. + // HACK(eddyb) temporary workaround for untyped pointers upstream. + // FIXME(eddyb) replace with untyped memory SPIR-V + `qptr` or similar. + let ptr = self.pointercast(ptr, self.type_ptr_to(ty)); + // Get the ID of the (potentially newly casted) pointer. + let ptr_id = ptr.def(self); + // HACK(eddyb) updated pointee type of `ptr` post-`pointercast`. + let original_pointee_ty = ty; + // --- Attempt GEP Merging Path --- // Check if the base pointer `ptr` itself was the result of a previous // AccessChain instruction. Merging is only attempted if the input type `ty` // matches the pointer's actual underlying pointee type `original_pointee_ty`. // If they differ, merging could be invalid. + // HACK(eddyb) always attempted now, because we `pointercast` first, which: + // - is noop when `ty == original_pointee_ty` pre-`pointercast` (old condition) + // - may generate (potentially mergeable) new `AccessChain`s in other cases let maybe_original_access_chain = if ty == original_pointee_ty { // Search the current function's instructions... // FIXME(eddyb) this could get ridiculously expensive, at the very least @@ -908,12 +930,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // 2. The *last* index of the original AccessChain is a constant. // 3. The *first* index (`ptr_base_index`) of the *current* GEP is a constant. // Merging usually involves adding these two constant indices. + // + // FIXME(eddyb) the above comment seems inaccurate, there is no reason + // why runtime indices couldn't be added together just like constants + // (and in fact this is needed nowadays for all array indexing). let can_merge = if let Some(&last_original_idx_id) = original_indices.last() { - // Check if both the last original index and the current base index are constant scalars. - self.builder - .lookup_const_scalar(last_original_idx_id.with_type(ptr_base_index.ty)) - .is_some() - && self.builder.lookup_const_scalar(ptr_base_index).is_some() + // HACK(eddyb) see the above comment, this bypasses the const + // check below, without tripping a clippy warning etc. + let always_merge = true; + always_merge || { + // Check if both the last original index and the current base index are constant scalars. + self.builder + .lookup_const_scalar(last_original_idx_id.with_type(ptr_base_index.ty)) + .is_some() + && self.builder.lookup_const_scalar(ptr_base_index).is_some() + } } else { // Original access chain had no indices to merge with. false @@ -966,21 +997,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // This path is taken if neither the Recovery nor the Merging path succeeded or applied. // It performs a more direct translation of the GEP request. - // HACK(eddyb): Workaround for potential upstream issues where pointers might lack precise type info. - // FIXME(eddyb): Ideally, this should use untyped memory features if available/necessary. - - // Before emitting the AccessChain, explicitly cast the base pointer `ptr` to - // ensure its pointee type matches the input `ty`. This is required because the - // SPIR-V `AccessChain` instruction implicitly uses the size of the base - // pointer's pointee type when applying the *first* index operand (our - // `ptr_base_index`). If `ty` and `original_pointee_ty` mismatched and we - // reached this fallback, this cast ensures SPIR-V validity. - trace!("maybe_inbounds_gep fallback path calling pointercast"); - // Cast ptr to point to `ty`. - let ptr = self.pointercast(ptr, self.type_ptr_to(ty)); - // Get the ID of the (potentially newly casted) pointer. - let ptr_id = ptr.def(self); - trace!( "emitting access chain via fallback path with pointer type: {}", self.debug_type(final_spirv_ptr_type) diff --git a/tests/compiletests/ui/dis/panic_builtin_bounds_check.stderr b/tests/compiletests/ui/dis/panic_builtin_bounds_check.stderr index d2066bab76..5a0a23a6fb 100644 --- a/tests/compiletests/ui/dis/panic_builtin_bounds_check.stderr +++ b/tests/compiletests/ui/dis/panic_builtin_bounds_check.stderr @@ -6,27 +6,45 @@ OpEntryPoint Fragment %2 "main" OpExecutionMode %2 OriginUpperLeft %3 = OpString "/n[Rust panicked at $DIR/panic_builtin_bounds_check.rs:25:5]/n index out of bounds: the len is %u but the index is %u/n in main()/n" %4 = OpString "$DIR/panic_builtin_bounds_check.rs" -%5 = OpTypeVoid -%6 = OpTypeFunction %5 -%7 = OpTypeBool +OpDecorate %5 ArrayStride 4 +%6 = OpTypeVoid +%7 = OpTypeFunction %6 %8 = OpTypeInt 32 0 -%9 = OpConstant %8 5 -%10 = OpConstant %8 4 -%11 = OpUndef %8 -%2 = OpFunction %5 None %6 -%12 = OpLabel +%9 = OpConstant %8 4 +%5 = OpTypeArray %8 %9 +%10 = OpTypePointer Function %5 +%11 = OpConstant %8 0 +%12 = OpConstant %8 1 +%13 = OpConstant %8 2 +%14 = OpConstant %8 3 +%15 = OpTypeBool +%16 = OpConstant %8 5 +%17 = OpUndef %8 +%18 = OpTypePointer Function %8 +%2 = OpFunction %6 None %7 +%19 = OpLabel +OpLine %4 30 4 +%20 = OpVariable %10 Function +OpLine %4 30 23 +%21 = OpCompositeConstruct %5 %11 %12 %13 %14 OpLine %4 25 4 -%13 = OpULessThan %7 %9 %10 +OpStore %20 %21 +%22 = OpULessThan %15 %16 %9 OpNoLine -OpSelectionMerge %14 None -OpBranchConditional %13 %15 %16 -%15 = OpLabel -OpBranch %14 -%16 = OpLabel +OpSelectionMerge %23 None +OpBranchConditional %22 %24 %25 +%24 = OpLabel +OpBranch %23 +%25 = OpLabel OpLine %4 25 4 -%17 = OpExtInst %5 %1 1 %3 %11 %9 +%26 = OpExtInst %6 %1 1 %3 %17 %16 OpNoLine OpReturn -%14 = OpLabel +%23 = OpLabel +OpLine %4 25 4 +%27 = OpIAdd %8 %11 %16 +%28 = OpInBoundsAccessChain %18 %20 %27 +%29 = OpLoad %8 %28 +OpNoLine OpReturn OpFunctionEnd From dd767a6061e9c492124edd976e93b5b28657711b Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 7 Jul 2025 08:21:57 +0300 Subject: [PATCH 03/38] builder: backport `rust-lang/rust#134117` (`[0, i]` -> `[i]` for array GEPs). --- .../src/builder/builder_methods.rs | 77 +++++++++++++++++++ tests/compiletests/ui/lang/issue-46.stderr | 8 ++ .../storage_class/typed-buffer-simple.stderr | 8 ++ 3 files changed, 93 insertions(+) create mode 100644 tests/compiletests/ui/lang/issue-46.stderr create mode 100644 tests/compiletests/ui/storage_class/typed-buffer-simple.stderr diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index cae01bd8e5..e62a48390b 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -655,6 +655,68 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // https://github.com/gpuweb/gpuweb/issues/33 let (&ptr_base_index, indices) = combined_indices.split_first().unwrap(); + // HACK(eddyb) this effectively removes any real support for GEPs with + // any `indices` (beyond `ptr_base_index`), which should now be the case + // across `rustc_codegen_ssa` (see also comment inside `inbounds_gep`). + // FIXME(eddyb) are the warning + fallback path even work keeping? + if !indices.is_empty() { + // HACK(eddyb) Cargo silences warnings in dependencies. + let force_warn = |span, msg| -> rustc_errors::Diag<'_, ()> { + rustc_errors::Diag::new( + self.tcx.dcx(), + rustc_errors::Level::ForceWarning(None), + msg, + ) + .with_span(span) + }; + force_warn( + self.span(), + format!( + "[RUST-GPU BUG] `inbounds_gep` or `gep` called with \ + {} combined indices (expected only 1)", + combined_indices.len(), + ), + ) + .emit(); + + let indexed_base_ptr = self.maybe_inbounds_gep(ty, ptr, &[ptr_base_index], is_inbounds); + let indexed_base_ptr_id = indexed_base_ptr.def(self); + assert_ty_eq!(self, indexed_base_ptr.ty, self.type_ptr_to(ty)); + + let mut final_pointee = ty; + for &index in indices { + final_pointee = match self.lookup_type(final_pointee) { + SpirvType::Adt { field_types, .. } => { + field_types[self + .builder + .lookup_const_scalar(index) + .expect("non-const struct index for GEP") + as usize] + } + SpirvType::Array { element, .. } + | SpirvType::RuntimeArray { element } + | SpirvType::Vector { element, .. } + | SpirvType::Matrix { element, .. } => element, + + _ => self.fatal(format!( + "GEP not implemented for indexing into type {}", + self.debug_type(final_pointee) + )), + }; + } + let final_spirv_ptr_type = self.type_ptr_to(final_pointee); + + let indices_ids: Vec<_> = indices.iter().map(|index| index.def(self)).collect(); + + return self.emit_access_chain( + final_spirv_ptr_type, + indexed_base_ptr_id, + None, + indices_ids, + is_inbounds, + ); + } + // Determine if this GEP operation is effectively byte-level addressing. // This check is based on the *provided* input type `ty`. If `ty` is i8 or u8, // it suggests the caller intends to perform byte-offset calculations, @@ -1972,6 +2034,21 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { ptr: Self::Value, indices: &[Self::Value], ) -> Self::Value { + // HACK(eddyb) effectively a backport of this `gep [0, i]` -> `gep [i]` + // PR: https://github.com/rust-lang/rust/pull/134117 to even earlier + // nightlies - and that PR happens to remove the last GEP that can be + // emitted with any "structured" (struct/array) indices, beyond the + // "first index" (which acts as `<*T>::offset` aka "pointer arithmetic"). + if let &[ptr_base_index, structured_index] = indices { + if self.builder.lookup_const_scalar(ptr_base_index) == Some(0) { + if let SpirvType::Array { element, .. } | SpirvType::RuntimeArray { element, .. } = + self.lookup_type(ty) + { + return self.maybe_inbounds_gep(element, ptr, &[structured_index], true); + } + } + } + self.maybe_inbounds_gep(ty, ptr, indices, true) } diff --git a/tests/compiletests/ui/lang/issue-46.stderr b/tests/compiletests/ui/lang/issue-46.stderr new file mode 100644 index 0000000000..baaa29572b --- /dev/null +++ b/tests/compiletests/ui/lang/issue-46.stderr @@ -0,0 +1,8 @@ +error: error:0:0 - Result type (OpTypeArray) does not match the type that results from indexing into the composite (OpTypeArray). + %67 = OpCompositeExtract %_arr_uint_uint_2 %49 0 0 + | + = note: spirv-val failed + = note: module `$TEST_BUILD_DIR/lang/issue-46.spv1.3` + +error: aborting due to 1 previous error + diff --git a/tests/compiletests/ui/storage_class/typed-buffer-simple.stderr b/tests/compiletests/ui/storage_class/typed-buffer-simple.stderr new file mode 100644 index 0000000000..f46577983d --- /dev/null +++ b/tests/compiletests/ui/storage_class/typed-buffer-simple.stderr @@ -0,0 +1,8 @@ +error: error:0:0 - OpInBoundsAccessChain result type (OpTypeInt) does not match the type that results from indexing into the base (OpTypeArray). + %33 = OpInBoundsAccessChain %_ptr_StorageBuffer_uint %28 %uint_0 + | + = note: spirv-val failed + = note: module `$TEST_BUILD_DIR/storage_class/typed-buffer-simple.spv1.3` + +error: aborting due to 1 previous error + From 72a38c84c92f5a41594b4d33e42366df70511502 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 7 Jul 2025 08:58:45 +0300 Subject: [PATCH 04/38] builder: special-case `0`-byte-offset GEPs as pointer casts. --- crates/rustc_codegen_spirv/src/builder/builder_methods.rs | 8 ++++++++ tests/compiletests/ui/lang/issue-46.stderr | 8 -------- .../ui/storage_class/typed-buffer-simple.stderr | 8 -------- 3 files changed, 8 insertions(+), 16 deletions(-) delete mode 100644 tests/compiletests/ui/lang/issue-46.stderr delete mode 100644 tests/compiletests/ui/storage_class/typed-buffer-simple.stderr diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index e62a48390b..40dd9a502f 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -817,6 +817,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // If we successfully calculated a constant byte offset for the first index... if let Some(const_ptr_offset_bytes) = const_ptr_offset_bytes { + // HACK(eddyb) an offset of `0` is always a noop, and `pointercast` + // gets to use `SpirvValueKind::LogicalPtrCast`, which can later + // be "undone" (by `strip_ptrcasts`), allowing more flexibility + // downstream (instead of overeagerly "shrinking" the pointee). + if const_ptr_offset_bytes == 0 { + return self.pointercast(ptr, final_spirv_ptr_type); + } + // Try to reconstruct a more "structured" access chain based on the *original* // pointee type of the pointer (`original_pointee_ty`) and the calculated byte offset. // This is useful if the input `ty` was generic (like u8) but the pointer actually diff --git a/tests/compiletests/ui/lang/issue-46.stderr b/tests/compiletests/ui/lang/issue-46.stderr deleted file mode 100644 index baaa29572b..0000000000 --- a/tests/compiletests/ui/lang/issue-46.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: error:0:0 - Result type (OpTypeArray) does not match the type that results from indexing into the composite (OpTypeArray). - %67 = OpCompositeExtract %_arr_uint_uint_2 %49 0 0 - | - = note: spirv-val failed - = note: module `$TEST_BUILD_DIR/lang/issue-46.spv1.3` - -error: aborting due to 1 previous error - diff --git a/tests/compiletests/ui/storage_class/typed-buffer-simple.stderr b/tests/compiletests/ui/storage_class/typed-buffer-simple.stderr deleted file mode 100644 index f46577983d..0000000000 --- a/tests/compiletests/ui/storage_class/typed-buffer-simple.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: error:0:0 - OpInBoundsAccessChain result type (OpTypeInt) does not match the type that results from indexing into the base (OpTypeArray). - %33 = OpInBoundsAccessChain %_ptr_StorageBuffer_uint %28 %uint_0 - | - = note: spirv-val failed - = note: module `$TEST_BUILD_DIR/storage_class/typed-buffer-simple.spv1.3` - -error: aborting due to 1 previous error - From b1f086105dbe5719391f5b563529f7ca4c640879 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 7 Jul 2025 09:11:40 +0300 Subject: [PATCH 05/38] builder: move GEP handling into a simpler `ptr_offset_strided` method. --- .../src/builder/builder_methods.rs | 473 +++++------------- 1 file changed, 132 insertions(+), 341 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index 40dd9a502f..a19b462440 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -620,13 +620,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { && leaf_size_range.contains(&ty_size) && leaf_ty.map_or(true, |leaf_ty| leaf_ty == ty) { - trace!("returning type: {:?}", self.debug_type(ty)); - trace!("returning indices with len: {:?}", indices.len()); + trace!("successful recovery leaf type: {:?}", self.debug_type(ty)); + trace!("successful recovery indices: {:?}", indices); return Some((indices, ty)); } } } + // NOTE(eddyb) see `ptr_offset_strided`, which this now forwards to. #[instrument(level = "trace", skip(self), fields(ty = ?self.debug_type(ty), ptr, combined_indices = ?combined_indices.iter().map(|x| (self.debug_type(x.ty), x.kind)).collect::>(), is_inbounds))] fn maybe_inbounds_gep( &mut self, @@ -655,6 +656,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // https://github.com/gpuweb/gpuweb/issues/33 let (&ptr_base_index, indices) = combined_indices.split_first().unwrap(); + let indexed_base_ptr = self.ptr_offset_strided(ptr, ty, ptr_base_index, is_inbounds); + // HACK(eddyb) this effectively removes any real support for GEPs with // any `indices` (beyond `ptr_base_index`), which should now be the case // across `rustc_codegen_ssa` (see also comment inside `inbounds_gep`). @@ -679,7 +682,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) .emit(); - let indexed_base_ptr = self.maybe_inbounds_gep(ty, ptr, &[ptr_base_index], is_inbounds); let indexed_base_ptr_id = indexed_base_ptr.def(self); assert_ty_eq!(self, indexed_base_ptr.ty, self.type_ptr_to(ty)); @@ -717,368 +719,157 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); } - // Determine if this GEP operation is effectively byte-level addressing. - // This check is based on the *provided* input type `ty`. If `ty` is i8 or u8, - // it suggests the caller intends to perform byte-offset calculations, - // which might allow for more flexible type recovery later. - let is_byte_gep = matches!(self.lookup_type(ty), SpirvType::Integer(8, _)); - trace!("Is byte GEP (based on input type): {}", is_byte_gep); - - // --- Calculate the final pointee type based on the GEP operation --- - - // This loop does the type traversal according to the `indices` (excluding the - // base offset index). It starts with the initial element type `ty` and - // iteratively applies each index to determine the type of the element being - // accessed at each step. The result is the type that the *final* pointer, - // generated by the SPIR-V `AccessChain`` instruction, *must* point to according - // to the SPIR-V specification and the provided `indices`. - let mut calculated_pointee_type = ty; - for index_val in indices { - // Lookup the current aggregate type we are indexing into. - calculated_pointee_type = match self.lookup_type(calculated_pointee_type) { - // If it's a struct (ADT), the index must be a constant. Use it to get - // the field type. - SpirvType::Adt { field_types, .. } => { - let const_index = self - .builder - .lookup_const_scalar(*index_val) - .expect("Non-constant struct index for GEP") - as usize; - // Get the type of the specific field. - field_types[const_index] - } - // If it's an array, vector, or matrix, indexing yields the element type. - SpirvType::Array { element, .. } - | SpirvType::RuntimeArray { element } - | SpirvType::Vector { element, .. } - | SpirvType::Matrix { element, .. } => element, - // Special case: If we started with a byte GEP (`is_byte_gep` is true) and - // we are currently indexing into a byte type, the result is still a byte type. - // This prevents errors if `indices` contains non-zero values when `ty` is u8/i8. - SpirvType::Integer(8, signedness) if is_byte_gep => { - // Define the resulting byte type as it might not exist yet). - SpirvType::Integer(8, signedness).def(self.span(), self) - } - // Any other type cannot be indexed into via GEP. - _ => self.fatal(format!( - "GEP not implemented for indexing into type {}", - self.debug_type(calculated_pointee_type) - )), - }; - } - // Construct the SPIR-V pointer type that points to the final calculated pointee - // type. This is the *required* result type for the SPIR-V `AccessChain` - // instruction. - let final_spirv_ptr_type = self.type_ptr_to(calculated_pointee_type); - trace!( - "Calculated final SPIR-V pointee type: {}", - self.debug_type(calculated_pointee_type) - ); - trace!( - "Calculated final SPIR-V ptr type: {}", - self.debug_type(final_spirv_ptr_type) - ); - - // Ensure all the `indices` (excluding the base offset index) are defined in the - // SPIR-V module and get their corresponding SPIR-V IDs. These IDs will be used - // as operands in the AccessChain instruction. - let gep_indices_ids: Vec<_> = indices.iter().map(|index| index.def(self)).collect(); - - // --- Prepare the base pointer --- - - // Remove any potentially redundant pointer casts applied to the input `ptr`. - // GEP operations should ideally work on the "underlying" pointer. - let ptr = ptr.strip_ptrcasts(); - // Get the SPIR-V ID for the (potentially stripped) base pointer. - let ptr_id = ptr.def(self); - // Determine the actual pointee type of the base pointer `ptr` *after* stripping casts. - // This might differ from the input `ty` if `ty` was less specific (e.g., u8). - let original_pointee_ty = match self.lookup_type(ptr.ty) { - SpirvType::Pointer { pointee } => pointee, - other => self.fatal(format!("gep called on non-pointer type: {other:?}")), - }; + indexed_base_ptr + } - // --- Recovery Path --- + /// Array-indexing-like pointer arithmetic, i.e. `(ptr: *T).offset(index)` + /// (or `wrapping_offset` instead of `offset`, for `is_inbounds = false`), + /// where `T` is given by `stride_elem_ty` (named so for extra clarity). + /// + /// This can produce legal SPIR-V by using 3 strategies: + /// 1. `pointercast` for a constant offset of `0` + /// - itself can succeed via `recover_access_chain_from_offset` + /// - even if a specific cast is unsupported, legal SPIR-V can still be + /// obtained, if all downstream uses rely on e.g. `strip_ptrcasts` + /// - also used before the merge strategy (3.), to improve its chances + /// 2. `recover_access_chain_from_offset` for constant offsets + /// (e.g. from `ptradd`/`inbounds_ptradd` used to access `struct` fields) + /// 3. merging onto an array `OpAccessChain` with the same `stride_elem_ty` + /// (possibly `&array[0]` from `pointercast` doing `*[T; N]` -> `*T`) + #[instrument(level = "trace", skip(self), fields(ptr, stride_elem_ty = ?self.debug_type(stride_elem_ty), index, is_inbounds))] + fn ptr_offset_strided( + &mut self, + ptr: SpirvValue, + stride_elem_ty: Word, + index: SpirvValue, + is_inbounds: bool, + ) -> SpirvValue { + // Precompute a constant `index * stride` (i.e. effective pointer offset) + // if possible, as both strategies 1 and 2 rely on knowing this value. + let const_offset = self.builder.lookup_const_scalar(index).and_then(|idx| { + let idx_u64 = u64::try_from(idx).ok()?; + let stride = self.lookup_type(stride_elem_ty).sizeof(self)?; + Some(idx_u64 * stride) + }); - // Try to calculate the byte offset implied by the *first* index - // (`ptr_base_index`) if it's a compile-time constant. This uses the size of the - // *input type* `ty`. - let const_ptr_offset_bytes = self - .builder - .lookup_const_scalar(ptr_base_index) // Check if ptr_base_index is constant scalar - .and_then(|idx| { - let idx_u64 = u64::try_from(idx).ok()?; - // Get the size of the input type `ty` - self.lookup_type(ty) - .sizeof(self) - // Calculate offset in bytes - .map(|size| idx_u64.saturating_mul(size.bytes())) - }); - - // If we successfully calculated a constant byte offset for the first index... - if let Some(const_ptr_offset_bytes) = const_ptr_offset_bytes { - // HACK(eddyb) an offset of `0` is always a noop, and `pointercast` - // gets to use `SpirvValueKind::LogicalPtrCast`, which can later - // be "undone" (by `strip_ptrcasts`), allowing more flexibility - // downstream (instead of overeagerly "shrinking" the pointee). - if const_ptr_offset_bytes == 0 { - return self.pointercast(ptr, final_spirv_ptr_type); - } + // Strategy 1: an offset of `0` is always a noop, and `pointercast` + // gets to use `SpirvValueKind::LogicalPtrCast`, which can later + // be "undone" (by `strip_ptrcasts`), allowing more flexibility + // downstream (instead of overeagerly "shrinking" the pointee). + if const_offset == Some(Size::ZERO) { + trace!("ptr_offset_strided: strategy 1 picked: offset 0 => pointer cast"); + + // FIXME(eddyb) could this just `return ptr;`? what even breaks? + return self.pointercast(ptr, self.type_ptr_to(stride_elem_ty)); + } + + // Strategy 2: try recovering an `OpAccessChain` from a constant offset. + if let Some(const_offset) = const_offset { + // Remove any (redundant) pointer casts applied to the input `ptr`, + // to obtain the "most original" pointer (which ideally will be e.g. + // a whole `OpVariable`, or the result of a previous `OpAccessChain`). + let original_ptr = ptr.strip_ptrcasts(); + let original_pointee_ty = match self.lookup_type(original_ptr.ty) { + SpirvType::Pointer { pointee } => pointee, + other => self.fatal(format!("pointer arithmetic on non-pointer type {other:?}")), + }; - // Try to reconstruct a more "structured" access chain based on the *original* - // pointee type of the pointer (`original_pointee_ty`) and the calculated byte offset. - // This is useful if the input `ty` was generic (like u8) but the pointer actually - // points to a structured type (like a struct). `recover_access_chain_from_offset` - // attempts to find a sequence of constant indices (`base_indices`) into - // `original_pointee_ty` that matches the `const_ptr_offset_bytes`. - if let Some((base_indices, base_pointee_ty)) = self.recover_access_chain_from_offset( - // Start from the pointer's actual underlying type + if let Some((const_indices, leaf_pointee_ty)) = self.recover_access_chain_from_offset( original_pointee_ty, - // The target byte offset - Size::from_bytes(const_ptr_offset_bytes), - // Allowed range (not strictly needed here?) + const_offset, Some(Size::ZERO)..=None, - // Don't require alignment None, ) { - // Recovery successful! Found a structured path (`base_indices`) to the target offset. trace!( - "`recover_access_chain_from_offset` returned Some with base_pointee_ty: {}", - self.debug_type(base_pointee_ty) + "ptr_offset_strided: strategy 2 picked: offset {const_offset:?} \ + => access chain w/ {const_indices:?}" ); - // Determine the result type for the `AccessChain` instruction we might - // emit. By default, use the `final_spirv_ptr_type` strictly calculated - // earlier from `ty` and `indices`. - // - // If this is a byte GEP *and* the recovered type happens to be a byte - // type, we can use the pointer type derived from the *recovered* type - // (`base_pointee_ty`). This helps preserve type information when - // recovery works for byte addressing. - let result_wrapper_type = if !is_byte_gep - || matches!(self.lookup_type(base_pointee_ty), SpirvType::Integer(8, _)) - { - trace!( - "Using strictly calculated type for wrapper: {}", - // Use type based on input `ty` + `indices` - self.debug_type(calculated_pointee_type) - ); - final_spirv_ptr_type - } else { - trace!( - "Byte GEP allowing recovered type for wrapper: {}", - // Use type based on recovery result - self.debug_type(base_pointee_ty) - ); - self.type_ptr_to(base_pointee_ty) - }; - - // Check if we can directly use the recovered path combined with the - // remaining indices. This is possible if: - // 1. The input type `ty` matches the type found by recovery - // (`base_pointee_ty`). This means the recovery didn't fundamentally - // change the type interpretation needed for the *next* steps - // (`indices`). - // OR - // 2. There are no further indices (`gep_indices_ids` is empty). In this - // case, the recovery path already leads to the final destination. - if ty == base_pointee_ty || gep_indices_ids.is_empty() { - // Combine the recovered constant indices with the remaining dynamic/constant indices. - let combined_indices = base_indices - .into_iter() - // Convert recovered `u32` indices to constant SPIR-V IDs. - .map(|idx| self.constant_u32(self.span(), idx).def(self)) - // Chain the original subsequent indices (`indices`). - .chain(gep_indices_ids.iter().copied()) - .collect(); + let leaf_ptr_ty = self.type_ptr_to(leaf_pointee_ty); + let original_ptr_id = original_ptr.def(self); + let const_indices_ids = const_indices + .into_iter() + .map(|idx| self.constant_u32(self.span(), idx).def(self)) + .collect(); - trace!( - "emitting access chain via recovery path with wrapper type: {}", - self.debug_type(result_wrapper_type) - ); - // Emit a single AccessChain using the original pointer `ptr_id` and the fully combined index list. - // Note: We don't pass `ptr_base_index` here because its effect is incorporated into `base_indices`. - return self.emit_access_chain( - result_wrapper_type, // The chosen result pointer type - ptr_id, // The original base pointer ID - None, // No separate base index needed - combined_indices, // The combined structured + original indices - is_inbounds, // Preserve original inbounds request - ); - } else { - // Recovery happened, but the recovered type `base_pointee_ty` doesn't match the input `ty`, - // AND there are more `indices` to process. Using the `base_indices` derived from - // `original_pointee_ty` would be incorrect for interpreting the subsequent `indices` - // which were intended to operate relative to `ty`. Fall back to the standard path. - trace!( - "Recovery type mismatch ({}) vs ({}) and GEP indices exist, falling back", - self.debug_type(ty), - self.debug_type(base_pointee_ty) - ); - } - } else { - // `recover_access_chain_from_offset` couldn't find a structured path for the constant offset. - trace!("`recover_access_chain_from_offset` returned None, falling back"); + return self.emit_access_chain( + leaf_ptr_ty, + original_ptr_id, + None, + const_indices_ids, + is_inbounds, + ); } } - // --- End Recovery Path --- - - // FIXME(eddyb) the comments below might not make much sense, because this - // used to be in the "fallback path" before being moved to before merging. - // - // Before emitting the AccessChain, explicitly cast the base pointer `ptr` to - // ensure its pointee type matches the input `ty`. This is required because the - // SPIR-V `AccessChain` instruction implicitly uses the size of the base - // pointer's pointee type when applying the *first* index operand (our - // `ptr_base_index`). If `ty` and `original_pointee_ty` mismatched and we - // reached this fallback, this cast ensures SPIR-V validity. - trace!("maybe_inbounds_gep fallback path calling pointercast"); - // Cast ptr to point to `ty`. - // HACK(eddyb) temporary workaround for untyped pointers upstream. - // FIXME(eddyb) replace with untyped memory SPIR-V + `qptr` or similar. - let ptr = self.pointercast(ptr, self.type_ptr_to(ty)); - // Get the ID of the (potentially newly casted) pointer. + // Strategy 3: try merging onto an `OpAccessChain` of matching type, + // and this starts by `pointercast`-ing to that type for two reasons: + // - this is the only type a merged `OpAccessChain` could produce + // - `pointercast` can itself produce a new `OpAccessChain` in the + // right circumstances (e.g. `&array[0]` for `*[T; N]` -> `*T`) + let ptr = self.pointercast(ptr, self.type_ptr_to(stride_elem_ty)); let ptr_id = ptr.def(self); - // HACK(eddyb) updated pointee type of `ptr` post-`pointercast`. - let original_pointee_ty = ty; - - // --- Attempt GEP Merging Path --- - - // Check if the base pointer `ptr` itself was the result of a previous - // AccessChain instruction. Merging is only attempted if the input type `ty` - // matches the pointer's actual underlying pointee type `original_pointee_ty`. - // If they differ, merging could be invalid. - // HACK(eddyb) always attempted now, because we `pointercast` first, which: - // - is noop when `ty == original_pointee_ty` pre-`pointercast` (old condition) - // - may generate (potentially mergeable) new `AccessChain`s in other cases - let maybe_original_access_chain = if ty == original_pointee_ty { - // Search the current function's instructions... - // FIXME(eddyb) this could get ridiculously expensive, at the very least - // it could use `.rev()`, hoping the base pointer was recently defined? - let search_result = { - let emit = self.emit(); - let module = emit.module_ref(); - emit.selected_function().and_then(|func_idx| { - module.functions.get(func_idx).and_then(|func| { - // Find the instruction that defined our base pointer `ptr_id`. - func.all_inst_iter() - .find(|inst| inst.result_id == Some(ptr_id)) - .and_then(|ptr_def_inst| { - // Check if that instruction was an `AccessChain` or `InBoundsAccessChain`. - if matches!( - ptr_def_inst.class.opcode, - Op::AccessChain | Op::InBoundsAccessChain - ) { - // If yes, extract its base pointer and its indices. - let base_ptr = ptr_def_inst.operands[0].unwrap_id_ref(); - let indices = ptr_def_inst.operands[1..] - .iter() - .map(|op| op.unwrap_id_ref()) - .collect::>(); - Some((base_ptr, indices)) - } else { - // The instruction defining ptr was not an `AccessChain`. - None - } - }) - }) + + let maybe_original_access_chain = { + let emit = self.emit(); + let module = emit.module_ref(); + let current_func_blocks = emit + .selected_function() + .and_then(|func_idx| Some(&module.functions.get(func_idx)?.blocks[..])) + .unwrap_or_default(); + + // NOTE(eddyb) reverse search (`rfind`) used in the hopes that the + // instruction producing the value with ID `ptr_id` is more likely to + // have been added more recently to the function, even though there's + // still a risk of this causing a whole-function traversal. + // + // FIXME(eddyb) consider tracking that via e.g. `SpirvValueKind`. + current_func_blocks + .iter() + .flat_map(|b| &b.instructions) + .rfind(|inst| inst.result_id == Some(ptr_id)) + .filter(|inst| { + matches!(inst.class.opcode, Op::AccessChain | Op::InBoundsAccessChain) + }) + .map(|inst| { + let base_ptr = inst.operands[0].unwrap_id_ref(); + let indices = inst.operands[1..] + .iter() + .map(|op| op.unwrap_id_ref()) + .collect::>(); + (base_ptr, indices) }) - }; - search_result - } else { - // Input type `ty` doesn't match the pointer's actual type, cannot safely merge. - None }; + if let Some((original_ptr, original_indices)) = maybe_original_access_chain { + trace!("ptr_offset_strided: strategy 3 picked: merging access chains"); - // If we found that `ptr` was defined by a previous `AccessChain`... - if let Some((original_ptr, mut original_indices)) = maybe_original_access_chain { - trace!("has original access chain, attempting to merge GEPs"); + let mut merged_indices = original_indices; - // Check if merging is possible. Requires: - // 1. The original AccessChain had at least one index. - // 2. The *last* index of the original AccessChain is a constant. - // 3. The *first* index (`ptr_base_index`) of the *current* GEP is a constant. - // Merging usually involves adding these two constant indices. - // - // FIXME(eddyb) the above comment seems inaccurate, there is no reason - // why runtime indices couldn't be added together just like constants - // (and in fact this is needed nowadays for all array indexing). - let can_merge = if let Some(&last_original_idx_id) = original_indices.last() { - // HACK(eddyb) see the above comment, this bypasses the const - // check below, without tripping a clippy warning etc. - let always_merge = true; - always_merge || { - // Check if both the last original index and the current base index are constant scalars. - self.builder - .lookup_const_scalar(last_original_idx_id.with_type(ptr_base_index.ty)) - .is_some() - && self.builder.lookup_const_scalar(ptr_base_index).is_some() - } - } else { - // Original access chain had no indices to merge with. - false - }; - - if can_merge { - let last_original_idx_id = original_indices.last_mut().unwrap(); - // Add the current `ptr_base_index` to the last index of the original chain. - // The result becomes the new last index. - *last_original_idx_id = self - .add( - // Ensure types match for add. - last_original_idx_id.with_type(ptr_base_index.ty), - ptr_base_index, - ) - // Define the result of the addition. - .def(self); - // Append the remaining indices (`indices`) from the current GEP operation. - original_indices.extend(gep_indices_ids); + let last_index_id = merged_indices.last_mut().unwrap(); + *last_index_id = self.add(last_index_id.with_type(index.ty), index).def(self); - trace!( - "emitting merged access chain with pointer to type: {}", - self.debug_type(calculated_pointee_type) - ); - // Emit a *single* AccessChain using the *original* base pointer and the *merged* index list. - // The result type *must* be the `final_spirv_ptr_type` calculated earlier based on the full chain of operations. - return self.emit_access_chain( - final_spirv_ptr_type, // Use the strictly calculated final type. - original_ptr, // Base pointer from the *original* AccessChain. - None, // No separate base index; it's merged. - original_indices, // The combined list of indices. - is_inbounds, // Preserve original inbounds request. - ); - } else { - // Cannot merge because one or both relevant indices are not constant, - // or the original chain was empty. - trace!( - "Last index or base offset is not constant, or no last index, cannot merge." - ); - } - } else { - // The base pointer `ptr` was not the result of an AccessChain, or merging - // wasn't attempted due to type mismatch. - trace!("no original access chain to merge with"); + return self.emit_access_chain(ptr.ty, original_ptr, None, merged_indices, is_inbounds); } - // --- End GEP Merging Path --- - - // --- Fallback / Default Path --- - // This path is taken if neither the Recovery nor the Merging path succeeded or applied. - // It performs a more direct translation of the GEP request. + // None of the legalizing strategies above applied, so this operation + // isn't really supported (and will error if actually used from a shader). + // + // FIXME(eddyb) supersede via SPIR-T pointer legalization (e.g. `qptr`). + trace!("ptr_offset_strided: falling back to (illegal) `OpPtrAccessChain`"); - trace!( - "emitting access chain via fallback path with pointer type: {}", - self.debug_type(final_spirv_ptr_type) + let result_ptr = if is_inbounds { + self.emit() + .in_bounds_ptr_access_chain(ptr.ty, None, ptr_id, index.def(self), vec![]) + } else { + self.emit() + .ptr_access_chain(ptr.ty, None, ptr_id, index.def(self), vec![]) + } + .unwrap(); + self.zombie( + result_ptr, + "cannot offset a pointer to an arbitrary element", ); - // Emit the `AccessChain` instruction. - self.emit_access_chain( - final_spirv_ptr_type, // Result *must* be a pointer to the final calculated type. - ptr_id, // Use the (potentially casted) base pointer ID. - Some(ptr_base_index), // Provide the first index separately. - gep_indices_ids, // Provide the rest of the indices. - is_inbounds, // Preserve original inbounds request. - ) + result_ptr.with_type(ptr.ty) } #[instrument( From 35ad4b2ea5742625d81954a8e58cff070ae139ca Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 7 Jul 2025 10:27:18 +0300 Subject: [PATCH 06/38] WIP: builder: castless noop in `ptr_offset_strided`. --- .../src/builder/builder_methods.rs | 47 ++++++++++++++++--- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index a19b462440..43851a242a 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -759,8 +759,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if const_offset == Some(Size::ZERO) { trace!("ptr_offset_strided: strategy 1 picked: offset 0 => pointer cast"); - // FIXME(eddyb) could this just `return ptr;`? what even breaks? - return self.pointercast(ptr, self.type_ptr_to(stride_elem_ty)); + // FIXME(eddyb) replace docs to remove mentions of pointer casting. + return ptr; } // Strategy 2: try recovering an `OpAccessChain` from a constant offset. @@ -3261,6 +3261,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { Bitcast(ID, ID), CompositeExtract(ID, ID, u32), InBoundsAccessChain(ID, ID, u32), + InBoundsAccessChain2(ID, ID, u32, u32), Store(ID, ID), Load(ID, ID), CopyMemory(ID, ID), @@ -3317,6 +3318,13 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { Inst::Unsupported(inst.class.opcode) } } + (Op::InBoundsAccessChain, Some(r), &[p, i, j]) => { + if let [Some(i), Some(j)] = [i, j].map(const_as_u32) { + Inst::InBoundsAccessChain2(r, p, i, j) + } else { + Inst::Unsupported(inst.class.opcode) + } + } (Op::Store, None, &[p, v]) => Inst::Store(p, v), (Op::Load, Some(r), &[p]) => Inst::Load(r, p), (Op::CopyMemory, None, &[a, b]) => Inst::CopyMemory(a, b), @@ -3508,20 +3516,45 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { let rev_copies_to_rt_args_array_src_ptrs: SmallVec<[_; 4]> = (0..rt_args_count).rev().map(|rt_arg_idx| { - let copy_to_rt_args_array_insts = try_rev_take(4).ok_or_else(|| { + let mut copy_to_rt_args_array_insts = try_rev_take(3).ok_or_else(|| { FormatArgsNotRecognized( "[fmt::rt::Argument; N] copy: ran out of instructions".into(), ) })?; + + // HACK(eddyb) account for both the split and combined + // access chain cases that `inbounds_gep` can now cause. + if let Inst::InBoundsAccessChain(dst_field_ptr, dst_base_ptr, 0) = + copy_to_rt_args_array_insts[0] + { + if let Some(mut prev_insts) = try_rev_take(1) { + assert_eq!(prev_insts.len(), 1); + let prev_inst = prev_insts.pop().unwrap(); + + match prev_inst { + Inst::InBoundsAccessChain( + array_elem_ptr, + array_ptr, + idx, + ) if dst_base_ptr == array_elem_ptr => { + copy_to_rt_args_array_insts[0] = + Inst::InBoundsAccessChain2(dst_field_ptr, array_ptr, idx, 0); + } + _ => { + // HACK(eddyb) don't lose the taken `prev_inst`. + copy_to_rt_args_array_insts.insert(0, prev_inst); + } + } + } + } + match copy_to_rt_args_array_insts[..] { [ - Inst::InBoundsAccessChain(array_slot, array_base, array_idx), - Inst::InBoundsAccessChain(dst_field_ptr, dst_base_ptr, 0), + Inst::InBoundsAccessChain2(dst_field_ptr, dst_array_base_ptr, array_idx, 0), Inst::InBoundsAccessChain(src_field_ptr, src_base_ptr, 0), Inst::CopyMemory(copy_dst, copy_src), - ] if array_base == rt_args_array_ptr_id + ] if dst_array_base_ptr == rt_args_array_ptr_id && array_idx as usize == rt_arg_idx - && dst_base_ptr == array_slot && (copy_dst, copy_src) == (dst_field_ptr, src_field_ptr) => { Ok(src_base_ptr) From a37eb49f759e45754b706d6e0dd7cd0c3bfc0ded Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 15 Oct 2024 15:53:20 +0300 Subject: [PATCH 07/38] builder: use the Rust types of `asm!` operands to protect against untyped pointers. --- .../src/builder/spirv_asm.rs | 78 ++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs b/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs index 91da22473d..50aa2184a4 100644 --- a/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs +++ b/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs @@ -2,6 +2,7 @@ use crate::maybe_pqp_cg_ssa as rustc_codegen_ssa; use super::Builder; +use crate::abi::ConvSpirvType; use crate::builder_spirv::{BuilderCursor, SpirvValue}; use crate::codegen_cx::CodegenCx; use crate::spirv_type::SpirvType; @@ -12,13 +13,18 @@ use rspirv::spirv::{ GroupOperation, ImageOperands, KernelProfilingInfo, LoopControl, MemoryAccess, MemorySemantics, Op, RayFlags, SelectionControl, StorageClass, Word, }; +use rustc_abi::{BackendRepr, Primitive}; use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; +use rustc_codegen_ssa::mir::operand::OperandValue; use rustc_codegen_ssa::mir::place::PlaceRef; -use rustc_codegen_ssa::traits::{AsmBuilderMethods, InlineAsmOperandRef}; +use rustc_codegen_ssa::traits::{ + AsmBuilderMethods, BackendTypes, BuilderMethods, InlineAsmOperandRef, +}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::{bug, ty::Instance}; use rustc_span::{DUMMY_SP, Span}; use rustc_target::asm::{InlineAsmRegClass, InlineAsmRegOrRegClass, SpirVInlineAsmRegClass}; +use smallvec::SmallVec; pub struct InstructionTable { table: FxHashMap<&'static str, &'static rspirv::grammar::Instruction<'static>>, @@ -33,6 +39,35 @@ impl InstructionTable { } } +// HACK(eddyb) `InlineAsmOperandRef` lacks `#[derive(Clone)]` +fn inline_asm_operand_ref_clone<'tcx, B: BackendTypes + ?Sized>( + operand: &InlineAsmOperandRef<'tcx, B>, +) -> InlineAsmOperandRef<'tcx, B> { + use InlineAsmOperandRef::*; + + match operand { + &In { reg, value } => In { reg, value }, + &Out { reg, late, place } => Out { reg, late, place }, + &InOut { + reg, + late, + in_value, + out_place, + } => InOut { + reg, + late, + in_value, + out_place, + }, + Const { string } => Const { + string: string.clone(), + }, + &SymFn { instance } => SymFn { instance }, + &SymStatic { def_id } => SymStatic { def_id }, + &Label { label } => Label { label }, + } +} + impl<'a, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'tcx> { /* Example asm and the template it compiles to: asm!( @@ -70,6 +105,45 @@ impl<'a, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'tcx> { if !unsupported_options.is_empty() { self.err(format!("asm flags not supported: {unsupported_options:?}")); } + + // HACK(eddyb) get more accurate pointers types, for pointer operands, + // from the Rust types available in their respective `OperandRef`s. + let mut operands: SmallVec<[_; 8]> = + operands.iter().map(inline_asm_operand_ref_clone).collect(); + for operand in &mut operands { + let (in_value, out_place) = match operand { + InlineAsmOperandRef::In { value, .. } => (Some(value), None), + InlineAsmOperandRef::InOut { + in_value, + out_place, + .. + } => (Some(in_value), out_place.as_mut()), + InlineAsmOperandRef::Out { place, .. } => (None, place.as_mut()), + + InlineAsmOperandRef::Const { .. } + | InlineAsmOperandRef::SymFn { .. } + | InlineAsmOperandRef::SymStatic { .. } + | InlineAsmOperandRef::Label { .. } => (None, None), + }; + + if let Some(in_value) = in_value { + if let (BackendRepr::Scalar(scalar), OperandValue::Immediate(in_value_spv)) = + (in_value.layout.backend_repr, &mut in_value.val) + { + if let Primitive::Pointer(_) = scalar.primitive() { + let in_value_precise_type = in_value.layout.spirv_type(self.span(), self); + *in_value_spv = self.pointercast(*in_value_spv, in_value_precise_type); + } + } + } + if let Some(out_place) = out_place { + let out_place_precise_type = out_place.layout.spirv_type(self.span(), self); + let out_place_precise_ptr_type = self.type_ptr_to(out_place_precise_type); + out_place.val.llval = + self.pointercast(out_place.val.llval, out_place_precise_ptr_type); + } + } + // vec of lines, and each line is vec of tokens let mut tokens = vec![vec![]]; for piece in template { @@ -131,7 +205,7 @@ impl<'a, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'tcx> { let mut id_map = FxHashMap::default(); let mut defined_ids = FxHashSet::default(); let mut id_to_type_map = FxHashMap::default(); - for operand in operands { + for operand in &operands { if let InlineAsmOperandRef::In { reg: _, value } = operand { let value = value.immediate(); id_to_type_map.insert(value.def(self), value.ty); From 5c91d2b370c4af5ff0116a1cde95f209c3d1d175 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 7 May 2025 23:14:07 +0300 Subject: [PATCH 08/38] intrinsics: use `GLOp::RoundEven` for `round_ties_even`. --- crates/rustc_codegen_spirv/src/builder/intrinsics.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs index 5b4d3680af..02fd1e998e 100644 --- a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs +++ b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs @@ -198,8 +198,10 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> { sym::floorf32 | sym::floorf64 => self.gl_op(GLOp::Floor, ret_ty, [args[0].immediate()]), sym::ceilf32 | sym::ceilf64 => self.gl_op(GLOp::Ceil, ret_ty, [args[0].immediate()]), sym::truncf32 | sym::truncf64 => self.gl_op(GLOp::Trunc, ret_ty, [args[0].immediate()]), + sym::rintf32 | sym::rintf64 => { + self.gl_op(GLOp::RoundEven, ret_ty, [args[0].immediate()]) + } // TODO: Correctness of all these rounds - sym::rintf32 | sym::rintf64 => self.gl_op(GLOp::Round, ret_ty, [args[0].immediate()]), sym::nearbyintf32 | sym::nearbyintf64 | sym::roundf32 | sym::roundf64 => { self.gl_op(GLOp::Round, ret_ty, [args[0].immediate()]) } From fa4dca4385d5da751c9a8e41dce33635c3c19342 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 6 May 2025 18:21:25 +0300 Subject: [PATCH 09/38] rustup: update to `nightly-2024-12-01`. --- crates/rustc_codegen_spirv/build.rs | 4 +-- rust-toolchain.toml | 4 +-- .../ui/dis/ptr_copy.normal.stderr | 36 +++++++++---------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index c7cafd699f..2c22ea664a 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-2024-11-22" +channel = "nightly-2024-12-01" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = b19329a37cedf2027517ae22c87cf201f93d776e"#; +# commit_hash = 7442931d49b199ad0a1cc0f8ca54e327b5139b66"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 551cee7f67..777aaf74b0 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2024-11-22" +channel = "nightly-2024-12-01" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = b19329a37cedf2027517ae22c87cf201f93d776e +# commit_hash = 7442931d49b199ad0a1cc0f8ca54e327b5139b66 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. diff --git a/tests/compiletests/ui/dis/ptr_copy.normal.stderr b/tests/compiletests/ui/dis/ptr_copy.normal.stderr index e376de2e58..39796faa46 100644 --- a/tests/compiletests/ui/dis/ptr_copy.normal.stderr +++ b/tests/compiletests/ui/dis/ptr_copy.normal.stderr @@ -1,13 +1,13 @@ error: cannot memcpy dynamically sized data - --> $CORE_SRC/intrinsics/mod.rs:4158:9 + --> $CORE_SRC/intrinsics/mod.rs:4421:9 | -4158 | copy(src, dst, count) +4421 | copy(src, dst, count) | ^^^^^^^^^^^^^^^^^^^^^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4134:21 + --> $CORE_SRC/intrinsics/mod.rs:4398:21 | -4134 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { +4398 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { | ^^^^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 @@ -28,27 +28,27 @@ note: called by `main` error: cannot cast between pointer types from `*f32` to `*struct () { }` - --> $CORE_SRC/intrinsics/mod.rs:4146:9 + --> $CORE_SRC/intrinsics/mod.rs:4409:9 | -4146 | / ub_checks::assert_unsafe_precondition!( -4147 | | check_language_ub, -4148 | | "ptr::copy requires that both pointer arguments are aligned and non-null", -4149 | | ( +4409 | / ub_checks::assert_unsafe_precondition!( +4410 | | check_language_ub, +4411 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +4412 | | ( ... | -4156 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4157 | | ); +4419 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +4420 | | ); | |_________^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4146:9 + --> $CORE_SRC/intrinsics/mod.rs:4409:9 | -4146 | / ub_checks::assert_unsafe_precondition!( -4147 | | check_language_ub, -4148 | | "ptr::copy requires that both pointer arguments are aligned and non-null", -4149 | | ( +4409 | / ub_checks::assert_unsafe_precondition!( +4410 | | check_language_ub, +4411 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +4412 | | ( ... | -4156 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4157 | | ); +4419 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +4420 | | ); | |_________^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 From ed50c4009a4f9f877751af2da11ef39cd0d5ed76 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 2 May 2025 18:05:46 +0300 Subject: [PATCH 10/38] Update target specs (remove os=unknown, add crt-static-respected). --- .../target-specs/spirv-unknown-opengl4.0.json | 2 +- .../target-specs/spirv-unknown-opengl4.1.json | 2 +- .../target-specs/spirv-unknown-opengl4.2.json | 2 +- .../target-specs/spirv-unknown-opengl4.3.json | 2 +- .../target-specs/spirv-unknown-opengl4.5.json | 2 +- .../target-specs/spirv-unknown-spv1.0.json | 2 +- .../target-specs/spirv-unknown-spv1.1.json | 2 +- .../target-specs/spirv-unknown-spv1.2.json | 2 +- .../target-specs/spirv-unknown-spv1.3.json | 2 +- .../target-specs/spirv-unknown-spv1.4.json | 2 +- .../target-specs/spirv-unknown-spv1.5.json | 2 +- .../target-specs/spirv-unknown-spv1.6.json | 2 +- .../target-specs/spirv-unknown-vulkan1.0.json | 2 +- .../target-specs/spirv-unknown-vulkan1.1.json | 2 +- .../target-specs/spirv-unknown-vulkan1.1spv1.4.json | 2 +- .../target-specs/spirv-unknown-vulkan1.2.json | 2 +- .../target-specs/spirv-unknown-vulkan1.3.json | 2 +- .../target-specs/spirv-unknown-vulkan1.4.json | 2 +- crates/rustc_codegen_spirv/src/target.rs | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.0.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.0.json index 9fa58d8558..d76e303e2a 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.0.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.0.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.1.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.1.json index 13d687233c..10eaa2f6ed 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.1.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.1.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.2.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.2.json index d1312620a2..9a8e14bced 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.2.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.2.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.3.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.3.json index 7a52159432..a164073671 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.3.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.3.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.5.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.5.json index ba509ed6dd..00d23b035d 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.5.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.5.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.0.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.0.json index d9e2166f5c..b1f7f910c3 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.0.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.0.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.1.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.1.json index 8fc1bcaf38..4319c16514 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.1.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.1.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.2.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.2.json index 0037561bee..43a4ec9bd8 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.2.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.2.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.3.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.3.json index 645848caf5..3903cdba51 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.3.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.3.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.4.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.4.json index 43ab248a65..a645839c76 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.4.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.4.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.5.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.5.json index e339e11535..67a2fb375f 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.5.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.5.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.6.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.6.json index 17fe415ca9..0208756e96 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.6.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.6.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.0.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.0.json index a15b45b6c6..468d7e6049 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.0.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.0.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1.json index b71dd7b2fd..b75eaa7dd9 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1spv1.4.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1spv1.4.json index 82634e6b85..66eaba431b 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1spv1.4.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1spv1.4.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.2.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.2.json index 7952baed9d..34032c502a 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.2.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.2.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.3.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.3.json index 5ed3beb293..ef4d7c2726 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.3.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.3.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.4.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.4.json index e77e7433ba..f2b4d8ad37 100644 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.4.json +++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.4.json @@ -3,6 +3,7 @@ "arch": "spirv", "crt-objects-fallback": "false", "crt-static-allows-dylibs": true, + "crt-static-respected": true, "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", "dll-prefix": "", "dll-suffix": ".spv.json", @@ -19,7 +20,6 @@ "std": null, "tier": null }, - "os": "unknown", "panic-strategy": "abort", "simd-types-indirect": false, "target-pointer-width": "32" diff --git a/crates/rustc_codegen_spirv/src/target.rs b/crates/rustc_codegen_spirv/src/target.rs index 8a6cdaf03f..42c5fbdf8c 100644 --- a/crates/rustc_codegen_spirv/src/target.rs +++ b/crates/rustc_codegen_spirv/src/target.rs @@ -54,13 +54,13 @@ impl SpirvTarget { o.simd_types_indirect = false; o.allows_weak_linkage = false; o.crt_static_allows_dylibs = true; + o.crt_static_respected = true; o.dll_prefix = "".into(); o.dll_suffix = ".spv.json".into(); o.dynamic_linking = true; o.emit_debug_gdb_scripts = false; o.linker_flavor = LinkerFlavor::Unix(Cc::No); o.panic_strategy = PanicStrategy::Abort; - o.os = "unknown".into(); o.env = self.env.to_string().into(); o.vendor = self.vendor.clone().into(); // TODO: Investigate if main_needs_argc_argv is useful (for building exes) From 68f4555fab6248a41587f5424dc1f2df3c167e8d Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 10 May 2025 21:11:47 +0300 Subject: [PATCH 11/38] Fix new `clippy::unnecessary_map_or` warnings. --- .../src/builder/builder_methods.rs | 2 +- .../src/linker/import_export_link.rs | 13 ++++++------- crates/rustc_codegen_spirv/src/linker/mem2reg.rs | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index 43851a242a..18fb83bdae 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -618,7 +618,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if offset == Size::ZERO && leaf_size_range.contains(&ty_size) - && leaf_ty.map_or(true, |leaf_ty| leaf_ty == ty) + && leaf_ty.is_none_or(|leaf_ty| leaf_ty == ty) { trace!("successful recovery leaf type: {:?}", self.debug_type(ty)); trace!("successful recovery indices: {:?}", indices); diff --git a/crates/rustc_codegen_spirv/src/linker/import_export_link.rs b/crates/rustc_codegen_spirv/src/linker/import_export_link.rs index 68a789104a..307277057a 100644 --- a/crates/rustc_codegen_spirv/src/linker/import_export_link.rs +++ b/crates/rustc_codegen_spirv/src/linker/import_export_link.rs @@ -229,10 +229,9 @@ fn kill_linkage_instructions( .retain(|f| !rewrite_rules.contains_key(&f.def_id().unwrap())); // drop imported variables - module.types_global_values.retain(|v| { - v.result_id - .map_or(true, |v| !rewrite_rules.contains_key(&v)) - }); + module + .types_global_values + .retain(|v| v.result_id.is_none_or(|v| !rewrite_rules.contains_key(&v))); // NOTE(eddyb) `Options`'s `keep_link_export`s field requests that `Export`s // are left in (primarily for unit testing - see also its doc comment). @@ -264,13 +263,13 @@ fn import_kill_annotations_and_debug( ) { module.annotations.retain(|inst| { inst.operands.is_empty() - || inst.operands[0].id_ref_any().map_or(true, |id| { + || inst.operands[0].id_ref_any().is_none_or(|id| { !rewrite_rules.contains_key(&id) && !killed_parameters.contains(&id) }) }); module.debug_names.retain(|inst| { inst.operands.is_empty() - || inst.operands[0].id_ref_any().map_or(true, |id| { + || inst.operands[0].id_ref_any().is_none_or(|id| { !rewrite_rules.contains_key(&id) && !killed_parameters.contains(&id) }) }); @@ -278,7 +277,7 @@ fn import_kill_annotations_and_debug( for inst in &mut module.annotations { if inst.class.opcode == Op::GroupDecorate { inst.operands.retain(|op| { - op.id_ref_any().map_or(true, |id| { + op.id_ref_any().is_none_or(|id| { !rewrite_rules.contains_key(&id) && !killed_parameters.contains(&id) }) }); diff --git a/crates/rustc_codegen_spirv/src/linker/mem2reg.rs b/crates/rustc_codegen_spirv/src/linker/mem2reg.rs index ba82f95fee..9688c5ce95 100644 --- a/crates/rustc_codegen_spirv/src/linker/mem2reg.rs +++ b/crates/rustc_codegen_spirv/src/linker/mem2reg.rs @@ -598,7 +598,7 @@ fn remove_old_variables( block.instructions.retain(|inst| { !matches!(inst.class.opcode, Op::AccessChain | Op::InBoundsAccessChain) || inst.operands.iter().all(|op| { - op.id_ref_any().map_or(true, |id| { + op.id_ref_any().is_none_or(|id| { var_maps_and_types .iter() .all(|(var_map, _)| !var_map.contains_key(&id)) From f7b83e9d721f2319850f8bef8cd2fe912f633d88 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 6 May 2025 18:29:20 +0300 Subject: [PATCH 12/38] rustup: update to `nightly-2024-12-10`. --- crates/rustc_codegen_spirv/build.rs | 4 +-- .../src/codegen_cx/constant.rs | 2 +- crates/rustc_codegen_spirv/src/lib.rs | 11 ++---- rust-toolchain.toml | 4 +-- .../ui/dis/ptr_copy.normal.stderr | 36 +++++++++---------- 5 files changed, 25 insertions(+), 32 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 2c22ea664a..9aa05be601 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-2024-12-01" +channel = "nightly-2024-12-10" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 7442931d49b199ad0a1cc0f8ca54e327b5139b66"#; +# commit_hash = a224f3807e58afc9353510f1d556c607d367545d"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs index 1461f23246..0b98cd7afb 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs @@ -254,7 +254,7 @@ impl<'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'tcx> { (value, AddressSpace::DATA) } GlobalAlloc::Function { instance } => ( - self.get_fn_addr(instance.polymorphize(self.tcx)), + self.get_fn_addr(instance), self.data_layout().instruction_address_space, ), GlobalAlloc::VTable(vty, dyn_ty) => { diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs index 82d8e8e7a2..275fb31968 100644 --- a/crates/rustc_codegen_spirv/src/lib.rs +++ b/crates/rustc_codegen_spirv/src/lib.rs @@ -151,7 +151,7 @@ use maybe_pqp_cg_ssa::{CodegenResults, CompiledModule, ModuleCodegen, ModuleKind use rspirv::binary::Assemble; use rustc_ast::expand::allocator::AllocatorKind; use rustc_data_structures::fx::FxIndexMap; -use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, FatalError}; +use rustc_errors::{DiagCtxtHandle, FatalError}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::mir::mono::{MonoItem, MonoItemData}; @@ -271,12 +271,7 @@ impl CodegenBackend for SpirvCodegenBackend { .join(sess) } - fn link( - &self, - sess: &Session, - codegen_results: CodegenResults, - outputs: &OutputFilenames, - ) -> Result<(), ErrorGuaranteed> { + fn link(&self, sess: &Session, codegen_results: CodegenResults, outputs: &OutputFilenames) { let timer = sess.timer("link_crate"); link::link( sess, @@ -285,8 +280,6 @@ impl CodegenBackend for SpirvCodegenBackend { codegen_results.crate_info.local_crate_name.as_str(), ); drop(timer); - - sess.dcx().has_errors().map_or(Ok(()), Err) } } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 777aaf74b0..714fe421cd 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2024-12-01" +channel = "nightly-2024-12-10" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 7442931d49b199ad0a1cc0f8ca54e327b5139b66 +# commit_hash = a224f3807e58afc9353510f1d556c607d367545d # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. diff --git a/tests/compiletests/ui/dis/ptr_copy.normal.stderr b/tests/compiletests/ui/dis/ptr_copy.normal.stderr index 39796faa46..22c29015c4 100644 --- a/tests/compiletests/ui/dis/ptr_copy.normal.stderr +++ b/tests/compiletests/ui/dis/ptr_copy.normal.stderr @@ -1,13 +1,13 @@ error: cannot memcpy dynamically sized data - --> $CORE_SRC/intrinsics/mod.rs:4421:9 + --> $CORE_SRC/intrinsics/mod.rs:4445:9 | -4421 | copy(src, dst, count) +4445 | copy(src, dst, count) | ^^^^^^^^^^^^^^^^^^^^^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4398:21 + --> $CORE_SRC/intrinsics/mod.rs:4422:21 | -4398 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { +4422 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { | ^^^^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 @@ -28,27 +28,27 @@ note: called by `main` error: cannot cast between pointer types from `*f32` to `*struct () { }` - --> $CORE_SRC/intrinsics/mod.rs:4409:9 + --> $CORE_SRC/intrinsics/mod.rs:4433:9 | -4409 | / ub_checks::assert_unsafe_precondition!( -4410 | | check_language_ub, -4411 | | "ptr::copy requires that both pointer arguments are aligned and non-null", -4412 | | ( +4433 | / ub_checks::assert_unsafe_precondition!( +4434 | | check_language_ub, +4435 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +4436 | | ( ... | -4419 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4420 | | ); +4443 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +4444 | | ); | |_________^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4409:9 + --> $CORE_SRC/intrinsics/mod.rs:4433:9 | -4409 | / ub_checks::assert_unsafe_precondition!( -4410 | | check_language_ub, -4411 | | "ptr::copy requires that both pointer arguments are aligned and non-null", -4412 | | ( +4433 | / ub_checks::assert_unsafe_precondition!( +4434 | | check_language_ub, +4435 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +4436 | | ( ... | -4419 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4420 | | ); +4443 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +4444 | | ); | |_________^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 From 0c88124bb0c6a66b92b60d054060a6a470f794e3 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 6 May 2025 19:05:56 +0300 Subject: [PATCH 13/38] rustup: update to `nightly-2024-12-15`. --- crates/rustc_codegen_spirv/build.rs | 4 ++-- crates/rustc_codegen_spirv/src/codegen_cx/mod.rs | 16 ++++++++++++++-- crates/rustc_codegen_spirv/src/lib.rs | 2 +- crates/rustc_codegen_spirv/src/link.rs | 10 ++++------ rust-toolchain.toml | 4 ++-- tests/compiletests/ui/dis/issue-1062.stderr | 2 +- tests/compiletests/ui/dis/ptr_copy.normal.stderr | 2 -- tests/compiletests/ui/dis/ptr_read.stderr | 2 +- tests/compiletests/ui/dis/ptr_read_method.stderr | 2 +- tests/compiletests/ui/dis/ptr_write.stderr | 2 +- .../compiletests/ui/dis/ptr_write_method.stderr | 2 +- 11 files changed, 28 insertions(+), 20 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 9aa05be601..6634c192c2 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-2024-12-10" +channel = "nightly-2024-12-15" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = a224f3807e58afc9353510f1d556c607d367545d"#; +# commit_hash = 0aeaa5eb22180fdf12a8489e63c4daa18da6f236"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs b/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs index 9f575fba72..497a828e4f 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs @@ -975,8 +975,20 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'tcx> { _template: &[InlineAsmTemplatePiece], _operands: &[GlobalAsmOperandRef<'tcx>], _options: InlineAsmOptions, - _line_spans: &[Span], + line_spans: &[Span], ) { - todo!() + self.tcx.dcx().span_fatal( + line_spans.first().copied().unwrap_or_default(), + "[Rust-GPU] `global_asm!` not yet supported", + ); + } + + // FIXME(eddyb) should this method be implemented as just symbol mangling, + // or renamed upstream into something much more specific? + fn mangled_name(&self, instance: Instance<'tcx>) -> String { + self.tcx.dcx().span_bug( + self.tcx.def_span(instance.def_id()), + "[Rust-GPU] `#[naked] fn` not yet supported", + ) } } diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs index 275fb31968..6ff459df97 100644 --- a/crates/rustc_codegen_spirv/src/lib.rs +++ b/crates/rustc_codegen_spirv/src/lib.rs @@ -218,7 +218,7 @@ impl CodegenBackend for SpirvCodegenBackend { rustc_errors::DEFAULT_LOCALE_RESOURCE } - fn target_features(&self, sess: &Session, _allow_unstable: bool) -> Vec { + fn target_features_cfg(&self, sess: &Session, _allow_unstable: bool) -> Vec { let cmdline = sess.opts.cg.target_feature.split(','); let cfg = sess.target.options.features.split(','); cfg.chain(cmdline) diff --git a/crates/rustc_codegen_spirv/src/link.rs b/crates/rustc_codegen_spirv/src/link.rs index 4c702b7c78..208518db0b 100644 --- a/crates/rustc_codegen_spirv/src/link.rs +++ b/crates/rustc_codegen_spirv/src/link.rs @@ -427,11 +427,10 @@ fn add_upstream_rust_crates( codegen_results: &CodegenResults, crate_type: CrateType, ) { - let (_, data) = codegen_results + let data = codegen_results .crate_info .dependency_formats - .iter() - .find(|(ty, _)| *ty == crate_type) + .get(&crate_type) .expect("failed to find crate type in dependency format list"); for &cnum in &codegen_results.crate_info.used_crates { let src = &codegen_results.crate_info.used_crate_source[&cnum]; @@ -451,11 +450,10 @@ fn add_upstream_native_libraries( codegen_results: &CodegenResults, crate_type: CrateType, ) { - let (_, data) = codegen_results + let data = codegen_results .crate_info .dependency_formats - .iter() - .find(|(ty, _)| *ty == crate_type) + .get(&crate_type) .expect("failed to find crate type in dependency format list"); for &cnum in &codegen_results.crate_info.used_crates { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 714fe421cd..a20b3d8ceb 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2024-12-10" +channel = "nightly-2024-12-15" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = a224f3807e58afc9353510f1d556c607d367545d +# commit_hash = 0aeaa5eb22180fdf12a8489e63c4daa18da6f236 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. diff --git a/tests/compiletests/ui/dis/issue-1062.stderr b/tests/compiletests/ui/dis/issue-1062.stderr index e62cf988bf..dac0cbb76e 100644 --- a/tests/compiletests/ui/dis/issue-1062.stderr +++ b/tests/compiletests/ui/dis/issue-1062.stderr @@ -4,7 +4,7 @@ OpLine %5 11 12 %6 = OpLoad %7 %8 OpLine %5 11 35 %9 = OpLoad %7 %10 -OpLine %11 1199 4 +OpLine %11 1224 4 %12 = OpBitwiseAnd %7 %9 %13 %14 = OpISub %7 %15 %12 %16 = OpShiftLeftLogical %7 %6 %12 diff --git a/tests/compiletests/ui/dis/ptr_copy.normal.stderr b/tests/compiletests/ui/dis/ptr_copy.normal.stderr index 22c29015c4..203cda642f 100644 --- a/tests/compiletests/ui/dis/ptr_copy.normal.stderr +++ b/tests/compiletests/ui/dis/ptr_copy.normal.stderr @@ -33,7 +33,6 @@ error: cannot cast between pointer types 4433 | / ub_checks::assert_unsafe_precondition!( 4434 | | check_language_ub, 4435 | | "ptr::copy requires that both pointer arguments are aligned and non-null", -4436 | | ( ... | 4443 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) 4444 | | ); @@ -45,7 +44,6 @@ note: used from within `core::intrinsics::copy::` 4433 | / ub_checks::assert_unsafe_precondition!( 4434 | | check_language_ub, 4435 | | "ptr::copy requires that both pointer arguments are aligned and non-null", -4436 | | ( ... | 4443 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) 4444 | | ); diff --git a/tests/compiletests/ui/dis/ptr_read.stderr b/tests/compiletests/ui/dis/ptr_read.stderr index ee8fd2aab4..7f147e42ac 100644 --- a/tests/compiletests/ui/dis/ptr_read.stderr +++ b/tests/compiletests/ui/dis/ptr_read.stderr @@ -2,7 +2,7 @@ %4 = OpFunctionParameter %5 %6 = OpFunctionParameter %5 %7 = OpLabel -OpLine %8 1374 8 +OpLine %8 1375 8 %9 = OpLoad %10 %4 OpLine %11 7 13 OpStore %6 %9 diff --git a/tests/compiletests/ui/dis/ptr_read_method.stderr b/tests/compiletests/ui/dis/ptr_read_method.stderr index ee8fd2aab4..7f147e42ac 100644 --- a/tests/compiletests/ui/dis/ptr_read_method.stderr +++ b/tests/compiletests/ui/dis/ptr_read_method.stderr @@ -2,7 +2,7 @@ %4 = OpFunctionParameter %5 %6 = OpFunctionParameter %5 %7 = OpLabel -OpLine %8 1374 8 +OpLine %8 1375 8 %9 = OpLoad %10 %4 OpLine %11 7 13 OpStore %6 %9 diff --git a/tests/compiletests/ui/dis/ptr_write.stderr b/tests/compiletests/ui/dis/ptr_write.stderr index 2ca3b239fc..c3911fadcd 100644 --- a/tests/compiletests/ui/dis/ptr_write.stderr +++ b/tests/compiletests/ui/dis/ptr_write.stderr @@ -4,7 +4,7 @@ %7 = OpLabel OpLine %8 7 35 %9 = OpLoad %10 %4 -OpLine %11 1578 8 +OpLine %11 1579 8 OpStore %6 %9 OpNoLine OpReturn diff --git a/tests/compiletests/ui/dis/ptr_write_method.stderr b/tests/compiletests/ui/dis/ptr_write_method.stderr index 5ff386ef8c..33cc436b2f 100644 --- a/tests/compiletests/ui/dis/ptr_write_method.stderr +++ b/tests/compiletests/ui/dis/ptr_write_method.stderr @@ -4,7 +4,7 @@ %7 = OpLabel OpLine %8 7 37 %9 = OpLoad %10 %4 -OpLine %11 1578 8 +OpLine %11 1579 8 OpStore %6 %9 OpNoLine OpReturn From 87f0485277a5340e3d4902ca71b1328dcc5e8f85 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 6 May 2025 19:31:22 +0300 Subject: [PATCH 14/38] rustup: update to `nightly-2024-12-16`. --- crates/rustc_codegen_spirv/build.rs | 4 ++-- rust-toolchain.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 6634c192c2..5f292b038c 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-2024-12-15" +channel = "nightly-2024-12-16" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 0aeaa5eb22180fdf12a8489e63c4daa18da6f236"#; +# commit_hash = c26db435bf8aee2efc397aab50f3a21eb351d6e5"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/rust-toolchain.toml b/rust-toolchain.toml index a20b3d8ceb..d415a3aaeb 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2024-12-15" +channel = "nightly-2024-12-16" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 0aeaa5eb22180fdf12a8489e63c4daa18da6f236 +# commit_hash = c26db435bf8aee2efc397aab50f3a21eb351d6e5 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. From b17e1388af346155d6fa1ab7f8138a27d704b9c0 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 6 May 2025 19:16:00 +0300 Subject: [PATCH 15/38] rustup: update to `nightly-2024-12-17`. --- crates/rustc_codegen_spirv/build.rs | 4 ++-- crates/rustc_codegen_spirv/src/attr.rs | 3 +-- crates/rustc_codegen_spirv/src/symbols.rs | 11 ++++++----- rust-toolchain.toml | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 5f292b038c..d03293998f 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-2024-12-16" +channel = "nightly-2024-12-17" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = c26db435bf8aee2efc397aab50f3a21eb351d6e5"#; +# commit_hash = 6d9f6ae36ae1299d6126ba40c15191f7aa3b79d8"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/crates/rustc_codegen_spirv/src/attr.rs b/crates/rustc_codegen_spirv/src/attr.rs index a47b1ba1ad..7d30d586a9 100644 --- a/crates/rustc_codegen_spirv/src/attr.rs +++ b/crates/rustc_codegen_spirv/src/attr.rs @@ -5,11 +5,10 @@ use crate::codegen_cx::CodegenCx; use crate::symbols::Symbols; use rspirv::spirv::{BuiltIn, ExecutionMode, ExecutionModel, StorageClass}; -use rustc_ast::Attribute; use rustc_hir as hir; use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{CRATE_HIR_ID, HirId, MethodKind, Target}; +use rustc_hir::{Attribute, CRATE_HIR_ID, HirId, MethodKind, Target}; use rustc_middle::hir::nested_filter; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; diff --git a/crates/rustc_codegen_spirv/src/symbols.rs b/crates/rustc_codegen_spirv/src/symbols.rs index 8b1c610a32..8aa95ae91c 100644 --- a/crates/rustc_codegen_spirv/src/symbols.rs +++ b/crates/rustc_codegen_spirv/src/symbols.rs @@ -1,8 +1,9 @@ use crate::attr::{Entry, ExecutionModeExtra, IntrinsicType, SpecConstant, SpirvAttribute}; use crate::builder::libm_intrinsics; use rspirv::spirv::{BuiltIn, ExecutionMode, ExecutionModel, StorageClass}; -use rustc_ast::ast::{AttrKind, Attribute, LitIntType, LitKind, MetaItemInner, MetaItemLit}; +use rustc_ast::ast::{LitIntType, LitKind, MetaItemInner, MetaItemLit}; use rustc_data_structures::fx::FxHashMap; +use rustc_hir::{AttrKind, Attribute}; use rustc_span::Span; use rustc_span::symbol::{Ident, Symbol}; use std::rc::Rc; @@ -442,12 +443,12 @@ pub(crate) fn parse_attrs_for_checking<'a>( ) -> impl Iterator> + 'a { attrs.iter().flat_map(move |attr| { let (whole_attr_error, args) = match attr.kind { - AttrKind::Normal(ref normal) => { + AttrKind::Normal(ref item) => { // #[...] - let s = &normal.item.path.segments; - if s.len() > 1 && s[0].ident.name == sym.rust_gpu { + let s = &item.path.segments; + if s.len() > 1 && s[0].name == sym.rust_gpu { // #[rust_gpu ...] - if s.len() != 2 || s[1].ident.name != sym.spirv { + if s.len() != 2 || s[1].name != sym.spirv { // #[rust_gpu::...] but not #[rust_gpu::spirv] ( Some(Err(( diff --git a/rust-toolchain.toml b/rust-toolchain.toml index d415a3aaeb..1fd0299fbe 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2024-12-16" +channel = "nightly-2024-12-17" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = c26db435bf8aee2efc397aab50f3a21eb351d6e5 +# commit_hash = 6d9f6ae36ae1299d6126ba40c15191f7aa3b79d8 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. From 7b300b99950eb700f8103fea47997d8337a8dc90 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 6 May 2025 18:08:44 +0300 Subject: [PATCH 16/38] rustup: update to `nightly-2024-12-20`. --- crates/rustc_codegen_spirv/build.rs | 4 ++-- crates/rustc_codegen_spirv/src/abi.rs | 4 +++- crates/rustc_codegen_spirv/src/codegen_cx/declare.rs | 2 +- crates/rustc_codegen_spirv/src/lib.rs | 2 +- crates/rustc_codegen_spirv/src/link.rs | 2 +- rust-toolchain.toml | 4 ++-- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index d03293998f..2b1f703d8e 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-2024-12-17" +channel = "nightly-2024-12-20" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 6d9f6ae36ae1299d6126ba40c15191f7aa3b79d8"#; +# commit_hash = 9e136a30a965bf4e63f03095c57df7257bf96fd6"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/crates/rustc_codegen_spirv/src/abi.rs b/crates/rustc_codegen_spirv/src/abi.rs index 79815c0dbb..2e28352bd2 100644 --- a/crates/rustc_codegen_spirv/src/abi.rs +++ b/crates/rustc_codegen_spirv/src/abi.rs @@ -125,6 +125,7 @@ pub(crate) fn provide(providers: &mut Providers) { }, }, variants: match *variants { + Variants::Empty => Variants::Empty, Variants::Single { index } => Variants::Single { index }, Variants::Multiple { tag, @@ -652,6 +653,7 @@ fn dig_scalar_pointee<'tcx>( } let all_fields = (match &layout.variants { + Variants::Empty => 0..0, Variants::Multiple { variants, .. } => 0..variants.len(), Variants::Single { index } => { let i = index.as_usize(); @@ -867,7 +869,7 @@ impl<'tcx> From> for TyLayoutNameKey<'tcx> { ty: layout.ty, variant: match layout.variants { Variants::Single { index } => Some(index), - Variants::Multiple { .. } => None, + _ => None, }, } } diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs b/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs index a01bcadaff..657dd099f4 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs @@ -9,7 +9,7 @@ use crate::custom_decorations::{CustomDecoration, SrcLocDecoration}; use crate::spirv_type::SpirvType; use itertools::Itertools; use rspirv::spirv::{FunctionControl, LinkageType, StorageClass, Word}; -use rustc_attr::InlineAttr; +use rustc_attr_parsing::InlineAttr; use rustc_codegen_ssa::traits::{PreDefineCodegenMethods, StaticCodegenMethods}; use rustc_hir::def::DefKind; use rustc_middle::bug; diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs index 6ff459df97..0c550d98c0 100644 --- a/crates/rustc_codegen_spirv/src/lib.rs +++ b/crates/rustc_codegen_spirv/src/lib.rs @@ -85,7 +85,7 @@ extern crate rustc_arena; #[cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)] extern crate rustc_ast; #[cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)] -extern crate rustc_attr; +extern crate rustc_attr_parsing; #[cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)] extern crate rustc_codegen_ssa; #[cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)] diff --git a/crates/rustc_codegen_spirv/src/link.rs b/crates/rustc_codegen_spirv/src/link.rs index 208518db0b..6dffb437a8 100644 --- a/crates/rustc_codegen_spirv/src/link.rs +++ b/crates/rustc_codegen_spirv/src/link.rs @@ -485,7 +485,7 @@ fn add_upstream_native_libraries( // (see `compiler/rustc_codegen_ssa/src/back/link.rs`) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { match lib.cfg { - Some(ref cfg) => rustc_attr::cfg_matches(cfg, sess, CRATE_NODE_ID, None), + Some(ref cfg) => rustc_attr_parsing::cfg_matches(cfg, sess, CRATE_NODE_ID, None), None => true, } } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 1fd0299fbe..d2ad42e716 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2024-12-17" +channel = "nightly-2024-12-20" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 6d9f6ae36ae1299d6126ba40c15191f7aa3b79d8 +# commit_hash = 9e136a30a965bf4e63f03095c57df7257bf96fd6 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. From 12e2c00f7b437a238287b5497aaa49b97d12e80f Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 6 May 2025 18:03:04 +0300 Subject: [PATCH 17/38] rustup: update to `nightly-2024-12-25`. --- crates/rustc_codegen_spirv/build.rs | 4 ++-- crates/rustc_codegen_spirv/src/link.rs | 4 ++-- rust-toolchain.toml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 2b1f703d8e..4b45fdb6c5 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-2024-12-20" +channel = "nightly-2024-12-25" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 9e136a30a965bf4e63f03095c57df7257bf96fd6"#; +# commit_hash = 409998c4e8cae45344fd434b358b697cc93870d0"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/crates/rustc_codegen_spirv/src/link.rs b/crates/rustc_codegen_spirv/src/link.rs index 6dffb437a8..37cb6db9e3 100644 --- a/crates/rustc_codegen_spirv/src/link.rs +++ b/crates/rustc_codegen_spirv/src/link.rs @@ -434,7 +434,7 @@ fn add_upstream_rust_crates( .expect("failed to find crate type in dependency format list"); for &cnum in &codegen_results.crate_info.used_crates { let src = &codegen_results.crate_info.used_crate_source[&cnum]; - match data[cnum.as_usize() - 1] { + match data[cnum] { Linkage::NotLinked | Linkage::IncludedFromDylib => {} Linkage::Static => rlibs.push(src.rlib.as_ref().unwrap().0.clone()), //Linkage::Dynamic => rlibs.push(src.dylib.as_ref().unwrap().0.clone()), @@ -465,7 +465,7 @@ fn add_upstream_native_libraries( NativeLibKind::Static { bundle: Some(false), .. - } if data[cnum.as_usize() - 1] != Linkage::Static => {} + } if data[cnum] != Linkage::Static => {} NativeLibKind::Static { bundle: None | Some(true), diff --git a/rust-toolchain.toml b/rust-toolchain.toml index d2ad42e716..7d45f29069 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2024-12-20" +channel = "nightly-2024-12-25" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 9e136a30a965bf4e63f03095c57df7257bf96fd6 +# commit_hash = 409998c4e8cae45344fd434b358b697cc93870d0 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. From d1dbb8ef399512e9cb8f565faa15213e47b7b2ff Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 4 May 2025 17:53:48 +0300 Subject: [PATCH 18/38] rustup: update to `nightly-2025-01-03` (~1.85). --- crates/rustc_codegen_spirv/build.rs | 4 +-- crates/rustc_codegen_spirv/src/lib.rs | 11 +++++++ rust-toolchain.toml | 4 +-- tests/compiletests/ui/dis/issue-1062.stderr | 2 +- .../ui/dis/ptr_copy.normal.stderr | 32 +++++++++---------- tests/compiletests/ui/dis/ptr_read.stderr | 2 +- .../ui/dis/ptr_read_method.stderr | 2 +- tests/compiletests/ui/dis/ptr_write.stderr | 2 +- .../ui/dis/ptr_write_method.stderr | 2 +- .../ui/lang/core/unwrap_or.stderr | 4 +-- 10 files changed, 38 insertions(+), 27 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 4b45fdb6c5..39d984a093 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-2024-12-25" +channel = "nightly-2025-01-03" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 409998c4e8cae45344fd434b358b697cc93870d0"#; +# commit_hash = 4363f9b6f6d3656d94adbcabba6348a485ef9a56"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs index 0c550d98c0..8bd2c42f21 100644 --- a/crates/rustc_codegen_spirv/src/lib.rs +++ b/crates/rustc_codegen_spirv/src/lib.rs @@ -150,6 +150,7 @@ use maybe_pqp_cg_ssa::traits::{ use maybe_pqp_cg_ssa::{CodegenResults, CompiledModule, ModuleCodegen, ModuleKind}; use rspirv::binary::Assemble; use rustc_ast::expand::allocator::AllocatorKind; +use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::{DiagCtxtHandle, FatalError}; use rustc_metadata::EncodedMetadata; @@ -390,6 +391,16 @@ impl WriteBackendMethods for SpirvCodegenBackend { fn serialize_module(module: ModuleCodegen) -> (String, Self::ModuleBuffer) { (module.name, SpirvModuleBuffer(module.module_llvm)) } + + fn autodiff( + _cgcx: &CodegenContext, + _tcx: TyCtxt<'_>, + _module: &ModuleCodegen, + _diff_fncs: Vec, + _config: &ModuleConfig, + ) -> Result<(), FatalError> { + todo!() + } } impl ExtraBackendMethods for SpirvCodegenBackend { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 7d45f29069..b29a7c784e 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2024-12-25" +channel = "nightly-2025-01-03" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 409998c4e8cae45344fd434b358b697cc93870d0 +# commit_hash = 4363f9b6f6d3656d94adbcabba6348a485ef9a56 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. diff --git a/tests/compiletests/ui/dis/issue-1062.stderr b/tests/compiletests/ui/dis/issue-1062.stderr index dac0cbb76e..590dc85880 100644 --- a/tests/compiletests/ui/dis/issue-1062.stderr +++ b/tests/compiletests/ui/dis/issue-1062.stderr @@ -4,7 +4,7 @@ OpLine %5 11 12 %6 = OpLoad %7 %8 OpLine %5 11 35 %9 = OpLoad %7 %10 -OpLine %11 1224 4 +OpLine %11 1094 4 %12 = OpBitwiseAnd %7 %9 %13 %14 = OpISub %7 %15 %12 %16 = OpShiftLeftLogical %7 %6 %12 diff --git a/tests/compiletests/ui/dis/ptr_copy.normal.stderr b/tests/compiletests/ui/dis/ptr_copy.normal.stderr index 203cda642f..b49e20f662 100644 --- a/tests/compiletests/ui/dis/ptr_copy.normal.stderr +++ b/tests/compiletests/ui/dis/ptr_copy.normal.stderr @@ -1,13 +1,13 @@ error: cannot memcpy dynamically sized data - --> $CORE_SRC/intrinsics/mod.rs:4445:9 + --> $CORE_SRC/intrinsics/mod.rs:4488:9 | -4445 | copy(src, dst, count) +4488 | copy(src, dst, count) | ^^^^^^^^^^^^^^^^^^^^^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4422:21 + --> $CORE_SRC/intrinsics/mod.rs:4465:21 | -4422 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { +4465 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { | ^^^^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 @@ -28,25 +28,25 @@ note: called by `main` error: cannot cast between pointer types from `*f32` to `*struct () { }` - --> $CORE_SRC/intrinsics/mod.rs:4433:9 + --> $CORE_SRC/intrinsics/mod.rs:4476:9 | -4433 | / ub_checks::assert_unsafe_precondition!( -4434 | | check_language_ub, -4435 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +4476 | / ub_checks::assert_unsafe_precondition!( +4477 | | check_language_ub, +4478 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -4443 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4444 | | ); +4486 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +4487 | | ); | |_________^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4433:9 + --> $CORE_SRC/intrinsics/mod.rs:4476:9 | -4433 | / ub_checks::assert_unsafe_precondition!( -4434 | | check_language_ub, -4435 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +4476 | / ub_checks::assert_unsafe_precondition!( +4477 | | check_language_ub, +4478 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -4443 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4444 | | ); +4486 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +4487 | | ); | |_________^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 diff --git a/tests/compiletests/ui/dis/ptr_read.stderr b/tests/compiletests/ui/dis/ptr_read.stderr index 7f147e42ac..e21db8e96c 100644 --- a/tests/compiletests/ui/dis/ptr_read.stderr +++ b/tests/compiletests/ui/dis/ptr_read.stderr @@ -2,7 +2,7 @@ %4 = OpFunctionParameter %5 %6 = OpFunctionParameter %5 %7 = OpLabel -OpLine %8 1375 8 +OpLine %8 1385 8 %9 = OpLoad %10 %4 OpLine %11 7 13 OpStore %6 %9 diff --git a/tests/compiletests/ui/dis/ptr_read_method.stderr b/tests/compiletests/ui/dis/ptr_read_method.stderr index 7f147e42ac..e21db8e96c 100644 --- a/tests/compiletests/ui/dis/ptr_read_method.stderr +++ b/tests/compiletests/ui/dis/ptr_read_method.stderr @@ -2,7 +2,7 @@ %4 = OpFunctionParameter %5 %6 = OpFunctionParameter %5 %7 = OpLabel -OpLine %8 1375 8 +OpLine %8 1385 8 %9 = OpLoad %10 %4 OpLine %11 7 13 OpStore %6 %9 diff --git a/tests/compiletests/ui/dis/ptr_write.stderr b/tests/compiletests/ui/dis/ptr_write.stderr index c3911fadcd..484ce4fd07 100644 --- a/tests/compiletests/ui/dis/ptr_write.stderr +++ b/tests/compiletests/ui/dis/ptr_write.stderr @@ -4,7 +4,7 @@ %7 = OpLabel OpLine %8 7 35 %9 = OpLoad %10 %4 -OpLine %11 1579 8 +OpLine %11 1587 8 OpStore %6 %9 OpNoLine OpReturn diff --git a/tests/compiletests/ui/dis/ptr_write_method.stderr b/tests/compiletests/ui/dis/ptr_write_method.stderr index 33cc436b2f..ca5d656e09 100644 --- a/tests/compiletests/ui/dis/ptr_write_method.stderr +++ b/tests/compiletests/ui/dis/ptr_write_method.stderr @@ -4,7 +4,7 @@ %7 = OpLabel OpLine %8 7 37 %9 = OpLoad %10 %4 -OpLine %11 1579 8 +OpLine %11 1587 8 OpStore %6 %9 OpNoLine OpReturn diff --git a/tests/compiletests/ui/lang/core/unwrap_or.stderr b/tests/compiletests/ui/lang/core/unwrap_or.stderr index 7f46d10973..8e0864941b 100644 --- a/tests/compiletests/ui/lang/core/unwrap_or.stderr +++ b/tests/compiletests/ui/lang/core/unwrap_or.stderr @@ -3,9 +3,9 @@ OpLine %5 13 11 %6 = OpCompositeInsert %7 %8 %9 0 %10 = OpCompositeExtract %11 %6 1 -OpLine %12 993 14 +OpLine %12 999 14 %13 = OpBitcast %14 %8 -OpLine %12 993 8 +OpLine %12 999 8 %15 = OpIEqual %16 %13 %17 OpNoLine OpSelectionMerge %18 None From 0b4a6bd55956c7b7a538ada1340a928361cc40cf Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 10 May 2025 21:51:33 +0300 Subject: [PATCH 19/38] Fix new `clippy::precedence` warnings. --- examples/runners/cpu/src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/runners/cpu/src/main.rs b/examples/runners/cpu/src/main.rs index 813c350222..41737510c1 100644 --- a/examples/runners/cpu/src/main.rs +++ b/examples/runners/cpu/src/main.rs @@ -92,9 +92,9 @@ fn color_u32_from_vec4(v: Vec4) -> u32 { let convert = |f: f32| -> u32 { (f.clamp(0.0, 1.0) * 255.0).round() as u32 }; convert(srgb_oetf(v.z)) - | convert(srgb_oetf(v.y)) << 8 - | convert(srgb_oetf(v.x)) << 16 - | convert(v.w) << 24 + | (convert(srgb_oetf(v.y)) << 8) + | (convert(srgb_oetf(v.x)) << 16) + | (convert(v.w) << 24) } fn main() { From a8e863f0eb9d789528e711e3425bcb2fbb2bbce2 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 5 Jul 2025 09:44:24 +0300 Subject: [PATCH 20/38] rustup: update to `nightly-2025-01-09`. --- crates/rustc_codegen_spirv/build.rs | 4 ++-- rust-toolchain.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 39d984a093..28c2bd3973 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-01-03" +channel = "nightly-2025-01-09" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 4363f9b6f6d3656d94adbcabba6348a485ef9a56"#; +# commit_hash = a580b5c379b4fca50dfe5afc0fc0ce00921e4e00"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/rust-toolchain.toml b/rust-toolchain.toml index b29a7c784e..69da292cc4 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2025-01-03" +channel = "nightly-2025-01-09" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 4363f9b6f6d3656d94adbcabba6348a485ef9a56 +# commit_hash = a580b5c379b4fca50dfe5afc0fc0ce00921e4e00 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. From 4e0e3455da0e454d66f1c3699ad3a308ff4494b4 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 5 Jul 2025 09:55:07 +0300 Subject: [PATCH 21/38] rustup: update to `nightly-2025-01-12`. --- crates/rustc_codegen_spirv/build.rs | 4 +-- crates/rustc_codegen_spirv/src/abi.rs | 2 ++ .../src/codegen_cx/declare.rs | 4 ++- .../src/linker/param_weakening.rs | 2 +- rust-toolchain.toml | 4 +-- tests/compiletests/ui/dis/issue-1062.stderr | 2 +- .../ui/dis/ptr_copy.normal.stderr | 32 +++++++++---------- 7 files changed, 27 insertions(+), 23 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 28c2bd3973..9ddf30bca2 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-01-09" +channel = "nightly-2025-01-12" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = a580b5c379b4fca50dfe5afc0fc0ce00921e4e00"#; +# commit_hash = eb54a50837ad4bcc9842924f27e7287ca66e294c"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/crates/rustc_codegen_spirv/src/abi.rs b/crates/rustc_codegen_spirv/src/abi.rs index 2e28352bd2..df750957f0 100644 --- a/crates/rustc_codegen_spirv/src/abi.rs +++ b/crates/rustc_codegen_spirv/src/abi.rs @@ -110,6 +110,7 @@ pub(crate) fn provide(providers: &mut Providers) { size, max_repr_align, unadjusted_abi_align, + randomization_seed, } = *layout; LayoutData { fields: match *fields { @@ -156,6 +157,7 @@ pub(crate) fn provide(providers: &mut Providers) { size, max_repr_align, unadjusted_abi_align, + randomization_seed, } } diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs b/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs index 657dd099f4..1d93215343 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs @@ -25,7 +25,9 @@ fn attrs_to_spirv(attrs: &CodegenFnAttrs) -> FunctionControl { let mut control = FunctionControl::NONE; match attrs.inline { InlineAttr::None => (), - InlineAttr::Hint | InlineAttr::Always => control.insert(FunctionControl::INLINE), + InlineAttr::Hint | InlineAttr::Always | InlineAttr::Force { .. } => { + control.insert(FunctionControl::INLINE) + } InlineAttr::Never => control.insert(FunctionControl::DONT_INLINE), } if attrs.flags.contains(CodegenFnAttrFlags::FFI_PURE) { diff --git a/crates/rustc_codegen_spirv/src/linker/param_weakening.rs b/crates/rustc_codegen_spirv/src/linker/param_weakening.rs index 8dc6442ccc..ee9df070c5 100644 --- a/crates/rustc_codegen_spirv/src/linker/param_weakening.rs +++ b/crates/rustc_codegen_spirv/src/linker/param_weakening.rs @@ -8,7 +8,7 @@ use indexmap::IndexMap; use rspirv::dr::{Builder, Module, Operand}; use rspirv::spirv::{Op, Word}; use rustc_data_structures::fx::FxHashMap; -use rustc_index::bit_set::BitSet; +use rustc_index::bit_set::DenseBitSet as BitSet; use std::mem; pub fn remove_unused_params(module: Module) -> Module { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 69da292cc4..1bd66eec92 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2025-01-09" +channel = "nightly-2025-01-12" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = a580b5c379b4fca50dfe5afc0fc0ce00921e4e00 +# commit_hash = eb54a50837ad4bcc9842924f27e7287ca66e294c # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. diff --git a/tests/compiletests/ui/dis/issue-1062.stderr b/tests/compiletests/ui/dis/issue-1062.stderr index 590dc85880..355e065baa 100644 --- a/tests/compiletests/ui/dis/issue-1062.stderr +++ b/tests/compiletests/ui/dis/issue-1062.stderr @@ -4,7 +4,7 @@ OpLine %5 11 12 %6 = OpLoad %7 %8 OpLine %5 11 35 %9 = OpLoad %7 %10 -OpLine %11 1094 4 +OpLine %11 1098 4 %12 = OpBitwiseAnd %7 %9 %13 %14 = OpISub %7 %15 %12 %16 = OpShiftLeftLogical %7 %6 %12 diff --git a/tests/compiletests/ui/dis/ptr_copy.normal.stderr b/tests/compiletests/ui/dis/ptr_copy.normal.stderr index b49e20f662..8fd6fa6b5d 100644 --- a/tests/compiletests/ui/dis/ptr_copy.normal.stderr +++ b/tests/compiletests/ui/dis/ptr_copy.normal.stderr @@ -1,13 +1,13 @@ error: cannot memcpy dynamically sized data - --> $CORE_SRC/intrinsics/mod.rs:4488:9 + --> $CORE_SRC/intrinsics/mod.rs:4460:9 | -4488 | copy(src, dst, count) +4460 | copy(src, dst, count) | ^^^^^^^^^^^^^^^^^^^^^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4465:21 + --> $CORE_SRC/intrinsics/mod.rs:4437:21 | -4465 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { +4437 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { | ^^^^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 @@ -28,25 +28,25 @@ note: called by `main` error: cannot cast between pointer types from `*f32` to `*struct () { }` - --> $CORE_SRC/intrinsics/mod.rs:4476:9 + --> $CORE_SRC/intrinsics/mod.rs:4448:9 | -4476 | / ub_checks::assert_unsafe_precondition!( -4477 | | check_language_ub, -4478 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +4448 | / ub_checks::assert_unsafe_precondition!( +4449 | | check_language_ub, +4450 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -4486 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4487 | | ); +4458 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +4459 | | ); | |_________^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4476:9 + --> $CORE_SRC/intrinsics/mod.rs:4448:9 | -4476 | / ub_checks::assert_unsafe_precondition!( -4477 | | check_language_ub, -4478 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +4448 | / ub_checks::assert_unsafe_precondition!( +4449 | | check_language_ub, +4450 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -4486 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4487 | | ); +4458 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +4459 | | ); | |_________^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 From 026fd05423e7bfb56663db147b5fb6dc23e5ad7d Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 5 Jul 2025 08:33:29 +0300 Subject: [PATCH 22/38] rustup: update to `nightly-2025-01-13`. --- crates/rustc_codegen_spirv/build.rs | 4 ++-- rust-toolchain.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 9ddf30bca2..942559222a 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-01-12" +channel = "nightly-2025-01-13" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = eb54a50837ad4bcc9842924f27e7287ca66e294c"#; +# commit_hash = 48a426eca9df23b24b3559e545cf88dee61d4de9"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 1bd66eec92..5775cf9b82 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2025-01-12" +channel = "nightly-2025-01-13" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = eb54a50837ad4bcc9842924f27e7287ca66e294c +# commit_hash = 48a426eca9df23b24b3559e545cf88dee61d4de9 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. From 887ca36f5497662aab78e63ce24bebd7b6289a86 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 5 Jul 2025 08:05:01 +0300 Subject: [PATCH 23/38] rustup: update to `nightly-2025-01-24`. --- crates/rustc_codegen_spirv/build.rs | 4 +-- .../src/codegen_cx/constant.rs | 3 ++ rust-toolchain.toml | 4 +-- .../ui/dis/ptr_copy.normal.stderr | 32 +++++++++---------- tests/compiletests/ui/dis/ptr_read.stderr | 2 +- .../ui/dis/ptr_read_method.stderr | 2 +- tests/compiletests/ui/dis/ptr_write.stderr | 2 +- .../ui/dis/ptr_write_method.stderr | 2 +- 8 files changed, 27 insertions(+), 24 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 942559222a..14d862e101 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-01-13" +channel = "nightly-2025-01-24" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 48a426eca9df23b24b3559e545cf88dee61d4de9"#; +# commit_hash = 99768c80a1c094a5cfc3b25a04e7a99de7210eae"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs index 0b98cd7afb..b2e2977edb 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs @@ -116,6 +116,9 @@ impl<'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'tcx> { fn const_undef(&self, ty: Self::Type) -> Self::Value { self.undef(ty) } + fn is_undef(&self, v: Self::Value) -> bool { + matches!(self.builder.lookup_const(v), Some(SpirvConst::Undef)) + } fn const_poison(&self, ty: Self::Type) -> Self::Value { // No distinction between undef and poison. self.const_undef(ty) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 5775cf9b82..beebf8b60e 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2025-01-13" +channel = "nightly-2025-01-24" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 48a426eca9df23b24b3559e545cf88dee61d4de9 +# commit_hash = 99768c80a1c094a5cfc3b25a04e7a99de7210eae # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. diff --git a/tests/compiletests/ui/dis/ptr_copy.normal.stderr b/tests/compiletests/ui/dis/ptr_copy.normal.stderr index 8fd6fa6b5d..70db15020e 100644 --- a/tests/compiletests/ui/dis/ptr_copy.normal.stderr +++ b/tests/compiletests/ui/dis/ptr_copy.normal.stderr @@ -1,13 +1,13 @@ error: cannot memcpy dynamically sized data - --> $CORE_SRC/intrinsics/mod.rs:4460:9 + --> $CORE_SRC/intrinsics/mod.rs:4472:9 | -4460 | copy(src, dst, count) +4472 | copy(src, dst, count) | ^^^^^^^^^^^^^^^^^^^^^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4437:21 + --> $CORE_SRC/intrinsics/mod.rs:4449:21 | -4437 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { +4449 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { | ^^^^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 @@ -28,25 +28,25 @@ note: called by `main` error: cannot cast between pointer types from `*f32` to `*struct () { }` - --> $CORE_SRC/intrinsics/mod.rs:4448:9 + --> $CORE_SRC/intrinsics/mod.rs:4460:9 | -4448 | / ub_checks::assert_unsafe_precondition!( -4449 | | check_language_ub, -4450 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +4460 | / ub_checks::assert_unsafe_precondition!( +4461 | | check_language_ub, +4462 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -4458 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4459 | | ); +4470 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +4471 | | ); | |_________^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4448:9 + --> $CORE_SRC/intrinsics/mod.rs:4460:9 | -4448 | / ub_checks::assert_unsafe_precondition!( -4449 | | check_language_ub, -4450 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +4460 | / ub_checks::assert_unsafe_precondition!( +4461 | | check_language_ub, +4462 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -4458 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4459 | | ); +4470 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +4471 | | ); | |_________^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 diff --git a/tests/compiletests/ui/dis/ptr_read.stderr b/tests/compiletests/ui/dis/ptr_read.stderr index e21db8e96c..c3de258279 100644 --- a/tests/compiletests/ui/dis/ptr_read.stderr +++ b/tests/compiletests/ui/dis/ptr_read.stderr @@ -2,7 +2,7 @@ %4 = OpFunctionParameter %5 %6 = OpFunctionParameter %5 %7 = OpLabel -OpLine %8 1385 8 +OpLine %8 1380 8 %9 = OpLoad %10 %4 OpLine %11 7 13 OpStore %6 %9 diff --git a/tests/compiletests/ui/dis/ptr_read_method.stderr b/tests/compiletests/ui/dis/ptr_read_method.stderr index e21db8e96c..c3de258279 100644 --- a/tests/compiletests/ui/dis/ptr_read_method.stderr +++ b/tests/compiletests/ui/dis/ptr_read_method.stderr @@ -2,7 +2,7 @@ %4 = OpFunctionParameter %5 %6 = OpFunctionParameter %5 %7 = OpLabel -OpLine %8 1385 8 +OpLine %8 1380 8 %9 = OpLoad %10 %4 OpLine %11 7 13 OpStore %6 %9 diff --git a/tests/compiletests/ui/dis/ptr_write.stderr b/tests/compiletests/ui/dis/ptr_write.stderr index 484ce4fd07..4fb47101fe 100644 --- a/tests/compiletests/ui/dis/ptr_write.stderr +++ b/tests/compiletests/ui/dis/ptr_write.stderr @@ -4,7 +4,7 @@ %7 = OpLabel OpLine %8 7 35 %9 = OpLoad %10 %4 -OpLine %11 1587 8 +OpLine %11 1582 8 OpStore %6 %9 OpNoLine OpReturn diff --git a/tests/compiletests/ui/dis/ptr_write_method.stderr b/tests/compiletests/ui/dis/ptr_write_method.stderr index ca5d656e09..7be26bb339 100644 --- a/tests/compiletests/ui/dis/ptr_write_method.stderr +++ b/tests/compiletests/ui/dis/ptr_write_method.stderr @@ -4,7 +4,7 @@ %7 = OpLabel OpLine %8 7 37 %9 = OpLoad %10 %4 -OpLine %11 1587 8 +OpLine %11 1582 8 OpStore %6 %9 OpNoLine OpReturn From 0e02f10fed89db349eb58e3f53522da525d7b01e Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 7 May 2025 20:38:19 +0300 Subject: [PATCH 24/38] rustfmt using `nightly-2025-02-16`. --- .../src/builder/builder_methods.rs | 39 ++++---- .../src/builder/intrinsics.rs | 88 +++++++++++-------- .../src/builder/libm_intrinsics.rs | 9 +- .../src/codegen_cx/constant.rs | 16 ++-- .../src/codegen_cx/declare.rs | 26 +++--- .../src/codegen_cx/entry.rs | 30 ++++--- .../src/custom_decorations.rs | 26 ++++-- .../rustc_codegen_spirv/src/custom_insts.rs | 55 +++++++----- .../src/linker/duplicates.rs | 9 +- .../rustc_codegen_spirv/src/linker/inline.rs | 21 +++-- .../rustc_codegen_spirv/src/linker/mem2reg.rs | 41 +++++---- crates/rustc_codegen_spirv/src/linker/mod.rs | 47 +++++----- .../src/linker/specializer.rs | 26 +++--- .../src/linker/spirt_passes/controlflow.rs | 19 ++-- crates/rustc_codegen_spirv/src/linker/test.rs | 15 ++-- examples/runners/ash/src/main.rs | 27 +++--- tests/compiletests/src/main.rs | 20 +++-- 17 files changed, 310 insertions(+), 204 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index 18fb83bdae..b287701422 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -1136,9 +1136,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; // TODO: rspirv doesn't have insert_variable function let result_id = builder.id(); - let inst = Instruction::new(Op::Variable, Some(ptr_ty), Some(result_id), vec![ - Operand::StorageClass(StorageClass::Function), - ]); + let inst = Instruction::new( + Op::Variable, + Some(ptr_ty), + Some(result_id), + vec![Operand::StorageClass(StorageClass::Function)], + ); builder.insert_into_block(index, inst).unwrap(); result_id.with_type(ptr_ty) } @@ -1211,13 +1214,16 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { let ((line_start, col_start), (line_end, col_end)) = (line_col_range.start, line_col_range.end); - self.custom_inst(void_ty, CustomInst::SetDebugSrcLoc { - file: Operand::IdRef(file.file_name_op_string_id), - line_start: Operand::IdRef(self.const_u32(line_start).def(self)), - line_end: Operand::IdRef(self.const_u32(line_end).def(self)), - col_start: Operand::IdRef(self.const_u32(col_start).def(self)), - col_end: Operand::IdRef(self.const_u32(col_end).def(self)), - }); + self.custom_inst( + void_ty, + CustomInst::SetDebugSrcLoc { + file: Operand::IdRef(file.file_name_op_string_id), + line_start: Operand::IdRef(self.const_u32(line_start).def(self)), + line_end: Operand::IdRef(self.const_u32(line_end).def(self)), + col_start: Operand::IdRef(self.const_u32(col_start).def(self)), + col_end: Operand::IdRef(self.const_u32(col_end).def(self)), + }, + ); } // HACK(eddyb) remove the previous instruction if made irrelevant. @@ -1566,11 +1572,14 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { let signed = match ty.kind() { ty::Int(_) => true, ty::Uint(_) => false, - other => self.fatal(format!("Unexpected {} type: {other:#?}", match oop { - OverflowOp::Add => "checked add", - OverflowOp::Sub => "checked sub", - OverflowOp::Mul => "checked mul", - })), + other => self.fatal(format!( + "Unexpected {} type: {other:#?}", + match oop { + OverflowOp::Add => "checked add", + OverflowOp::Sub => "checked sub", + OverflowOp::Mul => "checked mul", + } + )), }; let result = if is_add { diff --git a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs index 02fd1e998e..3f8467d65d 100644 --- a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs +++ b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs @@ -161,10 +161,11 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> { } sym::sinf32 | sym::sinf64 => self.gl_op(GLOp::Sin, ret_ty, [args[0].immediate()]), sym::cosf32 | sym::cosf64 => self.gl_op(GLOp::Cos, ret_ty, [args[0].immediate()]), - sym::powf32 | sym::powf64 => self.gl_op(GLOp::Pow, ret_ty, [ - args[0].immediate(), - args[1].immediate(), - ]), + sym::powf32 | sym::powf64 => self.gl_op( + GLOp::Pow, + ret_ty, + [args[0].immediate(), args[1].immediate()], + ), sym::expf32 | sym::expf64 => self.gl_op(GLOp::Exp, ret_ty, [args[0].immediate()]), sym::exp2f32 | sym::exp2f64 => self.gl_op(GLOp::Exp2, ret_ty, [args[0].immediate()]), sym::logf32 | sym::logf64 => self.gl_op(GLOp::Log, ret_ty, [args[0].immediate()]), @@ -176,20 +177,26 @@ 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 => self.gl_op(GLOp::Fma, ret_ty, [ - args[0].immediate(), - args[1].immediate(), - args[2].immediate(), - ]), + sym::fmaf32 | sym::fmaf64 => self.gl_op( + GLOp::Fma, + ret_ty, + [ + args[0].immediate(), + args[1].immediate(), + args[2].immediate(), + ], + ), sym::fabsf32 | sym::fabsf64 => self.gl_op(GLOp::FAbs, ret_ty, [args[0].immediate()]), - sym::minnumf32 | sym::minnumf64 => self.gl_op(GLOp::FMin, ret_ty, [ - args[0].immediate(), - args[1].immediate(), - ]), - sym::maxnumf32 | sym::maxnumf64 => self.gl_op(GLOp::FMax, ret_ty, [ - args[0].immediate(), - args[1].immediate(), - ]), + sym::minnumf32 | sym::minnumf64 => self.gl_op( + GLOp::FMin, + ret_ty, + [args[0].immediate(), args[1].immediate()], + ), + sym::maxnumf32 | sym::maxnumf64 => self.gl_op( + GLOp::FMax, + ret_ty, + [args[0].immediate(), args[1].immediate()], + ), sym::copysignf32 | sym::copysignf64 => { let val = args[0].immediate(); let sign = args[1].immediate(); @@ -485,9 +492,13 @@ impl Builder<'_, '_> { if trailing { let lsb = self .emit() - .ext_inst(u32, None, glsl, GLOp::FindILsb as u32, [Operand::IdRef( - arg, - )]) + .ext_inst( + u32, + None, + glsl, + GLOp::FindILsb as u32, + [Operand::IdRef(arg)], + ) .unwrap(); if offset == 0 { lsb @@ -499,9 +510,13 @@ impl Builder<'_, '_> { // rust is always unsigned, so FindUMsb let msb_bit = self .emit() - .ext_inst(u32, None, glsl, GLOp::FindUMsb as u32, [Operand::IdRef( - arg, - )]) + .ext_inst( + u32, + None, + glsl, + GLOp::FindUMsb as u32, + [Operand::IdRef(arg)], + ) .unwrap(); // the glsl op returns the Msb bit, not the amount of leading zeros of this u32 // leading zeros = 31 - Msb bit @@ -607,18 +622,21 @@ impl Builder<'_, '_> { // so the best thing we can do is use our own custom instruction. let kind_id = self.emit().string(kind); let message_debug_printf_fmt_str_id = self.emit().string(message_debug_printf_fmt_str); - self.custom_inst(void_ty, CustomInst::Abort { - kind: Operand::IdRef(kind_id), - message_debug_printf: [message_debug_printf_fmt_str_id] - .into_iter() - .chain( - message_debug_printf_args - .into_iter() - .map(|arg| arg.def(self)), - ) - .map(Operand::IdRef) - .collect(), - }); + self.custom_inst( + void_ty, + CustomInst::Abort { + kind: Operand::IdRef(kind_id), + message_debug_printf: [message_debug_printf_fmt_str_id] + .into_iter() + .chain( + message_debug_printf_args + .into_iter() + .map(|arg| arg.def(self)), + ) + .map(Operand::IdRef) + .collect(), + }, + ); self.unreachable(); // HACK(eddyb) we still need an active block in case the user of this diff --git a/crates/rustc_codegen_spirv/src/builder/libm_intrinsics.rs b/crates/rustc_codegen_spirv/src/builder/libm_intrinsics.rs index 9ac081d161..4b57dc17c6 100644 --- a/crates/rustc_codegen_spirv/src/builder/libm_intrinsics.rs +++ b/crates/rustc_codegen_spirv/src/builder/libm_intrinsics.rs @@ -230,10 +230,11 @@ impl Builder<'_, '_> { } LibmIntrinsic::Custom(LibmCustomIntrinsic::Cbrt) => { assert_eq!(args.len(), 1); - self.gl_op(GLOp::Pow, result_type, [ - args[0], - self.constant_float(args[0].ty, 1.0 / 3.0), - ]) + self.gl_op( + GLOp::Pow, + result_type, + [args[0], self.constant_float(args[0].ty, 1.0 / 3.0)], + ) } LibmIntrinsic::Custom(LibmCustomIntrinsic::Log10) => { assert_eq!(args.len(), 1); diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs index b2e2977edb..e70d56d8e3 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs @@ -172,11 +172,17 @@ impl<'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'tcx> { .layout_of(self.tcx.types.str_) .spirv_type(DUMMY_SP, self); ( - self.def_constant(self.type_ptr_to(str_ty), SpirvConst::PtrTo { - pointee: self - .constant_composite(str_ty, s.bytes().map(|b| self.const_u8(b).def_cx(self))) - .def_cx(self), - }), + self.def_constant( + self.type_ptr_to(str_ty), + SpirvConst::PtrTo { + pointee: self + .constant_composite( + str_ty, + s.bytes().map(|b| self.const_u8(b).def_cx(self)), + ) + .def_cx(self), + }, + ), self.const_usize(len as u64), ) } diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs b/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs index 1d93215343..f98daef2e3 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs @@ -127,13 +127,16 @@ impl<'tcx> CodegenCx<'tcx> { let declared = fn_id.with_type(function_type); - let attrs = AggregatedSpirvAttributes::parse(self, match self.tcx.def_kind(def_id) { - // This was made to ICE cross-crate at some point, but then got - // reverted in https://github.com/rust-lang/rust/pull/111381. - // FIXME(eddyb) remove this workaround once we rustup past that. - DefKind::Closure => &[], - _ => self.tcx.get_attrs_unchecked(def_id), - }); + let attrs = AggregatedSpirvAttributes::parse( + self, + match self.tcx.def_kind(def_id) { + // This was made to ICE cross-crate at some point, but then got + // reverted in https://github.com/rust-lang/rust/pull/111381. + // FIXME(eddyb) remove this workaround once we rustup past that. + DefKind::Closure => &[], + _ => self.tcx.get_attrs_unchecked(def_id), + }, + ); if let Some(entry) = attrs.entry.map(|attr| attr.value) { let entry_name = entry .name @@ -365,9 +368,12 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'tcx> { impl<'tcx> StaticCodegenMethods for CodegenCx<'tcx> { fn static_addr_of(&self, cv: Self::Value, _align: Align, _kind: Option<&str>) -> Self::Value { - self.def_constant(self.type_ptr_to(cv.ty), SpirvConst::PtrTo { - pointee: cv.def_cx(self), - }) + self.def_constant( + self.type_ptr_to(cv.ty), + SpirvConst::PtrTo { + pointee: cv.def_cx(self), + }, + ) } fn codegen_static(&self, def_id: DefId) { diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs b/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs index a2ad70a010..dfe40aee79 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs @@ -354,10 +354,13 @@ impl<'tcx> CodegenCx<'tcx> { if !ref_is_read_only && storage_class_requires_read_only { let mut err = self.tcx.dcx().struct_span_err( hir_param.ty_span, - format!("entry-point requires {}...", match explicit_mutbl { - hir::Mutability::Not => "interior mutability", - hir::Mutability::Mut => "a mutable reference", - }), + format!( + "entry-point requires {}...", + match explicit_mutbl { + hir::Mutability::Not => "interior mutability", + hir::Mutability::Mut => "a mutable reference", + } + ), ); { let note_message = @@ -445,9 +448,11 @@ impl<'tcx> CodegenCx<'tcx> { let mut emit = self.emit_global(); let spec_const_id = emit.spec_constant_bit32(value_spirv_type, default.unwrap_or(0)); - emit.decorate(spec_const_id, Decoration::SpecId, [Operand::LiteralBit32( - id, - )]); + emit.decorate( + spec_const_id, + Decoration::SpecId, + [Operand::LiteralBit32(id)], + ); ( Err("`#[spirv(spec_constant)]` is not an entry-point interface variable"), Ok(spec_const_id), @@ -772,10 +777,13 @@ impl<'tcx> CodegenCx<'tcx> { } => true, SpirvType::RuntimeArray { element: elt, .. } | SpirvType::Array { element: elt, .. } => { - matches!(self.lookup_type(elt), SpirvType::Image { - dim: Dim::DimSubpassData, - .. - }) + matches!( + self.lookup_type(elt), + SpirvType::Image { + dim: Dim::DimSubpassData, + .. + } + ) } _ => false, }; diff --git a/crates/rustc_codegen_spirv/src/custom_decorations.rs b/crates/rustc_codegen_spirv/src/custom_decorations.rs index e2cf68158c..e4c590bfcf 100644 --- a/crates/rustc_codegen_spirv/src/custom_decorations.rs +++ b/crates/rustc_codegen_spirv/src/custom_decorations.rs @@ -39,11 +39,16 @@ pub trait CustomDecoration<'a>: Sized { let mut encoded = Self::ENCODING_PREFIX.to_string(); self.encode(&mut encoded).unwrap(); - Instruction::new(Op::DecorateString, None, None, vec![ - Operand::IdRef(id), - Operand::Decoration(Decoration::UserTypeGOOGLE), - Operand::LiteralString(encoded), - ]) + Instruction::new( + Op::DecorateString, + None, + None, + vec![ + Operand::IdRef(id), + Operand::Decoration(Decoration::UserTypeGOOGLE), + Operand::LiteralString(encoded), + ], + ) } fn try_decode_from_inst(inst: &Instruction) -> Option<(Word, LazilyDecoded<'_, Self>)> { @@ -54,10 +59,13 @@ pub trait CustomDecoration<'a>: Sized { let prefixed_encoded = inst.operands[2].unwrap_literal_string(); let encoded = prefixed_encoded.strip_prefix(Self::ENCODING_PREFIX)?; - Some((id, LazilyDecoded { - encoded, - _marker: PhantomData, - })) + Some(( + id, + LazilyDecoded { + encoded, + _marker: PhantomData, + }, + )) } else { None } diff --git a/crates/rustc_codegen_spirv/src/custom_insts.rs b/crates/rustc_codegen_spirv/src/custom_insts.rs index 54a1331c9f..946202ec00 100644 --- a/crates/rustc_codegen_spirv/src/custom_insts.rs +++ b/crates/rustc_codegen_spirv/src/custom_insts.rs @@ -57,31 +57,38 @@ lazy_static! { pub fn register_to_spirt_context(cx: &spirt::Context) { use spirt::spv::spec::{ExtInstSetDesc, ExtInstSetInstructionDesc}; - cx.register_custom_ext_inst_set(&CUSTOM_EXT_INST_SET, ExtInstSetDesc { - // HACK(eddyb) this is the most compact form I've found, that isn't - // outright lossy by omitting "Rust vs Rust-GPU" or the version. - short_alias: Some( - concat!("Rust-GPU ", join_cargo_pkg_version_major_minor_patch!(".")).into(), - ), - instructions: SCHEMA - .iter() - .map(|&(i, name, operand_names)| { - (i, ExtInstSetInstructionDesc { - name: name.into(), - operand_names: operand_names - .iter() - .map(|name| { - name.strip_prefix("..") - .unwrap_or(name) - .replace('_', " ") - .into() - }) - .collect(), - is_debuginfo: name.contains("Debug") || name.contains("InlinedCallFrame"), + cx.register_custom_ext_inst_set( + &CUSTOM_EXT_INST_SET, + ExtInstSetDesc { + // HACK(eddyb) this is the most compact form I've found, that isn't + // outright lossy by omitting "Rust vs Rust-GPU" or the version. + short_alias: Some( + concat!("Rust-GPU ", join_cargo_pkg_version_major_minor_patch!(".")).into(), + ), + instructions: SCHEMA + .iter() + .map(|&(i, name, operand_names)| { + ( + i, + ExtInstSetInstructionDesc { + name: name.into(), + operand_names: operand_names + .iter() + .map(|name| { + name.strip_prefix("..") + .unwrap_or(name) + .replace('_', " ") + .into() + }) + .collect(), + is_debuginfo: name.contains("Debug") + || name.contains("InlinedCallFrame"), + }, + ) }) - }) - .collect(), - }); + .collect(), + }, + ); } macro_rules! def_custom_insts { diff --git a/crates/rustc_codegen_spirv/src/linker/duplicates.rs b/crates/rustc_codegen_spirv/src/linker/duplicates.rs index 6b1b45d8cd..0f8a36d8a0 100644 --- a/crates/rustc_codegen_spirv/src/linker/duplicates.rs +++ b/crates/rustc_codegen_spirv/src/linker/duplicates.rs @@ -401,11 +401,12 @@ pub fn remove_duplicate_debuginfo(module: &mut Module) { // as it needs to reset callee-side `DbgLocInst`, // but we can replace it in-place and hope later // it get nop'd out by some real `DbgLocInst`. - insts[inst_idx] - .operands - .splice(1.., [Operand::LiteralExtInstInteger( + insts[inst_idx].operands.splice( + 1.., + [Operand::LiteralExtInstInteger( CustomOp::ClearDebugSrcLoc as u32, - )]); + )], + ); dbg = DbgState { loc: Some(DbgLocInst { inst_idx, diff --git a/crates/rustc_codegen_spirv/src/linker/inline.rs b/crates/rustc_codegen_spirv/src/linker/inline.rs index 70b2ec4b2b..34a4886ca0 100644 --- a/crates/rustc_codegen_spirv/src/linker/inline.rs +++ b/crates/rustc_codegen_spirv/src/linker/inline.rs @@ -63,9 +63,14 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> { custom_ext_inst_set_import: custom_ext_inst_set_import.unwrap_or_else(|| { let id = next_id(header); - let inst = Instruction::new(Op::ExtInstImport, None, Some(id), vec![ - Operand::LiteralString(custom_insts::CUSTOM_EXT_INST_SET.to_string()), - ]); + let inst = Instruction::new( + Op::ExtInstImport, + None, + Some(id), + vec![Operand::LiteralString( + custom_insts::CUSTOM_EXT_INST_SET.to_string(), + )], + ); module.ext_inst_imports.push(inst); id }), @@ -921,10 +926,12 @@ impl Inliner<'_, '_> { .entry(callee_name) .or_insert_with(|| { let id = next_id(self.header); - self.debug_string_source - .push(Instruction::new(Op::String, None, Some(id), vec![ - Operand::LiteralString(callee_name.to_string()), - ])); + self.debug_string_source.push(Instruction::new( + Op::String, + None, + Some(id), + vec![Operand::LiteralString(callee_name.to_string())], + )); id }); let mut mk_debuginfo_prefix_and_suffix = || { diff --git a/crates/rustc_codegen_spirv/src/linker/mem2reg.rs b/crates/rustc_codegen_spirv/src/linker/mem2reg.rs index 9688c5ce95..6a2cb926d5 100644 --- a/crates/rustc_codegen_spirv/src/linker/mem2reg.rs +++ b/crates/rustc_codegen_spirv/src/linker/mem2reg.rs @@ -253,10 +253,13 @@ fn collect_access_chains( } let mut variables = FxHashMap::default(); - variables.insert(base_var, VarInfo { - ty: base_var_ty, - indices: vec![], - }); + variables.insert( + base_var, + VarInfo { + ty: base_var_ty, + indices: vec![], + }, + ); // Loop in case a previous block references a later AccessChain loop { let mut changed = false; @@ -345,17 +348,21 @@ fn split_copy_memory( } }; let temp_id = id(header); - block.instructions[inst_index] = - Instruction::new(Op::Load, Some(ty), Some(temp_id), vec![Operand::IdRef( - source, - )]); + block.instructions[inst_index] = Instruction::new( + Op::Load, + Some(ty), + Some(temp_id), + vec![Operand::IdRef(source)], + ); inst_index += 1; block.instructions.insert( inst_index, - Instruction::new(Op::Store, None, None, vec![ - Operand::IdRef(target), - Operand::IdRef(temp_id), - ]), + Instruction::new( + Op::Store, + None, + None, + vec![Operand::IdRef(target), Operand::IdRef(temp_id)], + ), ); } inst_index += 1; @@ -462,10 +469,12 @@ impl Renamer<'_, '_> { let new_id = id(self.header); self.blocks[block].instructions.insert( 0, - Instruction::new(Op::Phi, Some(self.base_var_type), Some(new_id), vec![ - Operand::IdRef(top_def), - Operand::IdRef(from_block_label), - ]), + Instruction::new( + Op::Phi, + Some(self.base_var_type), + Some(new_id), + vec![Operand::IdRef(top_def), Operand::IdRef(from_block_label)], + ), ); self.phi_defs.insert(new_id); new_id diff --git a/crates/rustc_codegen_spirv/src/linker/mod.rs b/crates/rustc_codegen_spirv/src/linker/mod.rs index b4e91e1dcb..c4fed4d06b 100644 --- a/crates/rustc_codegen_spirv/src/linker/mod.rs +++ b/crates/rustc_codegen_spirv/src/linker/mod.rs @@ -336,23 +336,27 @@ pub fn link( for func in &mut output.functions { simple_passes::block_ordering_pass(func); } - output = specializer::specialize(opts, output, specializer::SimpleSpecialization { - specialize_operand: |operand| { - matches!(operand, Operand::StorageClass(StorageClass::Generic)) - }, + output = specializer::specialize( + opts, + output, + specializer::SimpleSpecialization { + specialize_operand: |operand| { + matches!(operand, Operand::StorageClass(StorageClass::Generic)) + }, - // NOTE(eddyb) this can be anything that is guaranteed to pass - // validation - there are no constraints so this is either some - // unused pointer, or perhaps one created using `OpConstantNull` - // and simply never mixed with pointers that have a storage class. - // It would be nice to use `Generic` itself here so that we leave - // some kind of indication of it being unconstrained, but `Generic` - // requires additional capabilities, so we use `Function` instead. - // TODO(eddyb) investigate whether this can end up in a pointer - // type that's the value of a module-scoped variable, and whether - // `Function` is actually invalid! (may need `Private`) - concrete_fallback: Operand::StorageClass(StorageClass::Function), - }); + // NOTE(eddyb) this can be anything that is guaranteed to pass + // validation - there are no constraints so this is either some + // unused pointer, or perhaps one created using `OpConstantNull` + // and simply never mixed with pointers that have a storage class. + // It would be nice to use `Generic` itself here so that we leave + // some kind of indication of it being unconstrained, but `Generic` + // requires additional capabilities, so we use `Function` instead. + // TODO(eddyb) investigate whether this can end up in a pointer + // type that's the value of a module-scoped variable, and whether + // `Function` is actually invalid! (may need `Private`) + concrete_fallback: Operand::StorageClass(StorageClass::Function), + }, + ); } // NOTE(eddyb) with SPIR-T, we can do `mem2reg` before inlining, too! @@ -653,10 +657,13 @@ pub fn link( module.entry_points.push(entry.clone()); let entry_name = entry.operands[2].unwrap_literal_string().to_string(); let mut file_stem = OsString::from( - sanitize_filename::sanitize_with_options(&entry_name, sanitize_filename::Options { - replacement: "-", - ..Default::default() - }) + sanitize_filename::sanitize_with_options( + &entry_name, + sanitize_filename::Options { + replacement: "-", + ..Default::default() + }, + ) .replace("--", "-"), ); // It's always possible to find an unambiguous `file_stem`, but it diff --git a/crates/rustc_codegen_spirv/src/linker/specializer.rs b/crates/rustc_codegen_spirv/src/linker/specializer.rs index 01c4c9f9b1..73f24be19b 100644 --- a/crates/rustc_codegen_spirv/src/linker/specializer.rs +++ b/crates/rustc_codegen_spirv/src/linker/specializer.rs @@ -624,12 +624,15 @@ impl Specializer { // Inference variables become "generic" parameters. if param_count > 0 { - self.generics.insert(result_id, Generic { - param_count, - def: inst.clone(), - param_values, - replacements, - }); + self.generics.insert( + result_id, + Generic { + param_count, + def: inst.clone(), + param_values, + replacements, + }, + ); } } } @@ -2102,10 +2105,13 @@ impl<'a, S: Specialization> InferCx<'a, S> { Op::Return => {} - _ => self.instantiate_instruction(inst, InstructionLocation::FnBody { - block_idx, - inst_idx, - }), + _ => self.instantiate_instruction( + inst, + InstructionLocation::FnBody { + block_idx, + inst_idx, + }, + ), } } } diff --git a/crates/rustc_codegen_spirv/src/linker/spirt_passes/controlflow.rs b/crates/rustc_codegen_spirv/src/linker/spirt_passes/controlflow.rs index 83b603c88b..76ae455e02 100644 --- a/crates/rustc_codegen_spirv/src/linker/spirt_passes/controlflow.rs +++ b/crates/rustc_codegen_spirv/src/linker/spirt_passes/controlflow.rs @@ -228,14 +228,17 @@ pub fn convert_custom_aborts_to_unstructured_returns_in_entry_points( }; let block_insts_maybe_custom = func_at_block_insts.into_iter().map(|func_at_inst| { let data_inst_def = func_at_inst.def(); - (func_at_inst, match cx[data_inst_def.form].kind { - DataInstKind::SpvExtInst { ext_set, inst } - if ext_set == custom_ext_inst_set => - { - Some(CustomOp::decode(inst).with_operands(&data_inst_def.inputs)) - } - _ => None, - }) + ( + func_at_inst, + match cx[data_inst_def.form].kind { + DataInstKind::SpvExtInst { ext_set, inst } + if ext_set == custom_ext_inst_set => + { + Some(CustomOp::decode(inst).with_operands(&data_inst_def.inputs)) + } + _ => None, + }, + ) }); let custom_terminator_inst = block_insts_maybe_custom .clone() diff --git a/crates/rustc_codegen_spirv/src/linker/test.rs b/crates/rustc_codegen_spirv/src/linker/test.rs index 529b4c697b..e48382c97e 100644 --- a/crates/rustc_codegen_spirv/src/linker/test.rs +++ b/crates/rustc_codegen_spirv/src/linker/test.rs @@ -66,12 +66,15 @@ fn load(bytes: &[u8]) -> Module { // FIXME(eddyb) shouldn't this be named just `link`? (`assemble_spirv` is separate) fn assemble_and_link(binaries: &[&[u8]]) -> Result { - link_with_linker_opts(binaries, &crate::linker::Options { - compact_ids: true, - dce: true, - keep_link_exports: true, - ..Default::default() - }) + link_with_linker_opts( + binaries, + &crate::linker::Options { + compact_ids: true, + dce: true, + keep_link_exports: true, + ..Default::default() + }, + ) } fn link_with_linker_opts( diff --git a/examples/runners/ash/src/main.rs b/examples/runners/ash/src/main.rs index 7a006574ca..e667549421 100644 --- a/examples/runners/ash/src/main.rs +++ b/examples/runners/ash/src/main.rs @@ -128,18 +128,21 @@ pub fn main() { for SpvFile { name, data } in shaders { ctx.insert_shader_module(name, &data); } - ctx.build_pipelines(vk::PipelineCache::null(), vec![( - // HACK(eddyb) used to be `module: "sky_shader"` but we need `multimodule` - // for `debugPrintf` instrumentation to work (see `compile_shaders`). - VertexShaderEntryPoint { - module: "sky_shader::main_vs".into(), - entry_point: "main_vs".into(), - }, - FragmentShaderEntryPoint { - module: "sky_shader::main_fs".into(), - entry_point: "main_fs".into(), - }, - )]); + ctx.build_pipelines( + vk::PipelineCache::null(), + vec![( + // HACK(eddyb) used to be `module: "sky_shader"` but we need `multimodule` + // for `debugPrintf` instrumentation to work (see `compile_shaders`). + VertexShaderEntryPoint { + module: "sky_shader::main_vs".into(), + entry_point: "main_vs".into(), + }, + FragmentShaderEntryPoint { + module: "sky_shader::main_fs".into(), + entry_point: "main_fs".into(), + }, + )], + ); let (compiler_sender, compiler_receiver) = sync_channel(1); diff --git a/tests/compiletests/src/main.rs b/tests/compiletests/src/main.rs index a17ec704b7..4f14d419b3 100644 --- a/tests/compiletests/src/main.rs +++ b/tests/compiletests/src/main.rs @@ -155,14 +155,18 @@ impl Runner { let target = format!("{SPIRV_TARGET_PREFIX}{env}"); let libs = build_deps(&self.deps_target_dir, &self.codegen_backend_path, &target); - let mut flags = test_rustc_flags(&self.codegen_backend_path, &libs, &[ - &self - .deps_target_dir - .join(DepKind::SpirvLib.target_dir_suffix(&target)), - &self - .deps_target_dir - .join(DepKind::ProcMacro.target_dir_suffix(&target)), - ]); + let mut flags = test_rustc_flags( + &self.codegen_backend_path, + &libs, + &[ + &self + .deps_target_dir + .join(DepKind::SpirvLib.target_dir_suffix(&target)), + &self + .deps_target_dir + .join(DepKind::ProcMacro.target_dir_suffix(&target)), + ], + ); flags += variation.extra_flags; let config = compiletest::Config { From de779ef522374d70d016d6a41058c95aeb4e8715 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 7 May 2025 20:11:35 +0300 Subject: [PATCH 25/38] rustup: update to `nightly-2025-02-16` (~1.86). --- crates/rustc_codegen_spirv/build.rs | 7 ++-- crates/rustc_codegen_spirv/src/abi.rs | 19 +++++------ .../src/builder/builder_methods.rs | 23 ++++++++++--- .../src/builder/byte_addressable_buffer.rs | 4 +-- .../src/builder/intrinsics.rs | 8 ++--- crates/rustc_codegen_spirv/src/builder/mod.rs | 4 +-- .../rustc_codegen_spirv/src/builder_spirv.rs | 14 ++++---- .../src/codegen_cx/constant.rs | 9 ++++-- .../src/codegen_cx/declare.rs | 2 +- .../src/codegen_cx/entry.rs | 2 +- .../rustc_codegen_spirv/src/codegen_cx/mod.rs | 12 +++---- .../src/codegen_cx/type_.rs | 4 +-- .../src/custom_decorations.rs | 4 +-- crates/rustc_codegen_spirv/src/lib.rs | 3 +- crates/rustc_codegen_spirv/src/link.rs | 2 +- crates/rustc_codegen_spirv/src/linker/test.rs | 6 ++-- crates/rustc_codegen_spirv/src/spirv_type.rs | 2 +- rust-toolchain.toml | 4 +-- .../ui/arch/debug_printf_type_checking.stderr | 10 +++--- .../ui/dis/ptr_copy.normal.stderr | 32 +++++++++---------- 20 files changed, 100 insertions(+), 71 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 14d862e101..7690495ae1 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-01-24" +channel = "nightly-2025-02-16" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 99768c80a1c094a5cfc3b25a04e7a99de7210eae"#; +# commit_hash = 9cd60bd2ccc41bc898d2ad86728f14035d2df72d"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); @@ -276,6 +276,9 @@ mod maybe_pqp_cg_ssa; println!("cargo::rustc-check-cfg=cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)"); + // HACK(eddyb) `if cfg!(llvm_enzyme)` added upstream for autodiff support. + println!("cargo::rustc-check-cfg=cfg(llvm_enzyme)"); + Ok(()) } diff --git a/crates/rustc_codegen_spirv/src/abi.rs b/crates/rustc_codegen_spirv/src/abi.rs index df750957f0..bab2ce329c 100644 --- a/crates/rustc_codegen_spirv/src/abi.rs +++ b/crates/rustc_codegen_spirv/src/abi.rs @@ -6,6 +6,11 @@ use crate::codegen_cx::CodegenCx; use crate::spirv_type::SpirvType; use itertools::Itertools; use rspirv::spirv::{Dim, ImageFormat, StorageClass, Word}; +use rustc_abi::ExternAbi as Abi; +use rustc_abi::{ + Align, BackendRepr, FieldsShape, LayoutData, Primitive, ReprFlags, ReprOptions, Scalar, Size, + TagEncoding, VariantIdx, Variants, +}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; use rustc_index::Idx; @@ -20,12 +25,7 @@ use rustc_middle::{bug, span_bug}; use rustc_span::DUMMY_SP; use rustc_span::def_id::DefId; use rustc_span::{Span, Symbol}; -use rustc_target::abi::call::{ArgAbi, ArgAttributes, FnAbi, PassMode}; -use rustc_target::abi::{ - Align, BackendRepr, FieldsShape, LayoutData, Primitive, ReprFlags, ReprOptions, Scalar, Size, - TagEncoding, VariantIdx, Variants, -}; -use rustc_target::spec::abi::Abi; +use rustc_target::callconv::{ArgAbi, ArgAttributes, FnAbi, PassMode}; use std::cell::RefCell; use std::collections::hash_map::Entry; use std::fmt; @@ -988,9 +988,10 @@ fn trans_intrinsic_type<'tcx>( cx: &CodegenCx<'tcx>, const_: Const<'tcx>, ) -> Result { - let (const_val, const_ty) = const_ - .try_to_valtree() - .expect("expected monomorphic const in codegen"); + let ty::Value { + ty: const_ty, + valtree: const_val, + } = const_.to_value(); assert!(const_ty.is_integral()); const_val .try_to_scalar_int() diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index b287701422..0cc78b4175 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -10,6 +10,7 @@ use crate::spirv_type::SpirvType; use itertools::{Either, Itertools}; use rspirv::dr::{InsertPoint, Instruction, Operand}; use rspirv::spirv::{Capability, MemoryModel, MemorySemantics, Op, Scope, StorageClass, Word}; +use rustc_abi::{Align, BackendRepr, Scalar, Size, WrappingRange}; use rustc_apfloat::{Float, Round, Status, ieee}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::common::{ @@ -27,8 +28,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; -use rustc_target::abi::call::FnAbi; -use rustc_target::abi::{Align, BackendRepr, Scalar, Size, WrappingRange}; +use rustc_target::callconv::FnAbi; use smallvec::SmallVec; use std::borrow::Cow; use std::cell::Cell; @@ -1776,6 +1776,11 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { } } + // FIXME(eddyb) `assume` is not implemented atm, so all of its forms should + // avoid computing its (potentially illegal) bool input in the first place. + fn assume_integer_range(&mut self, _imm: Self::Value, _ty: Self::Type, _range: WrappingRange) {} + fn assume_nonnull(&mut self, _val: Self::Value) {} + fn range_metadata(&mut self, _load: Self::Value, _range: WrappingRange) { // ignore } @@ -2296,9 +2301,19 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { } } - fn icmp(&mut self, op: IntPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value { + fn icmp(&mut self, op: IntPredicate, lhs: Self::Value, mut rhs: Self::Value) -> Self::Value { // Note: the signedness of the opcode doesn't have to match the signedness of the operands. use IntPredicate::*; + + if lhs.ty != rhs.ty + && [lhs, rhs].map(|v| matches!(self.lookup_type(v.ty), SpirvType::Pointer { .. })) + == [true, true] + { + // HACK(eddyb) temporary workaround for untyped pointers upstream. + // FIXME(eddyb) replace with untyped memory SPIR-V + `qptr` or similar. + rhs = self.pointercast(rhs, lhs.ty); + } + assert_ty_eq!(self, lhs.ty, rhs.ty); let b = SpirvType::Bool.def(self.span(), self); match self.lookup_type(lhs.ty) { @@ -3662,7 +3677,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { let args = ref_arg_ids_with_ty_and_spec .iter() .map(|&(ref_id, ty, spec)| { - use rustc_target::abi::{Float::*, Integer::*, Primitive::*}; + use rustc_abi::{Float::*, Integer::*, Primitive::*}; let layout = self.layout_of(ty); diff --git a/crates/rustc_codegen_spirv/src/builder/byte_addressable_buffer.rs b/crates/rustc_codegen_spirv/src/builder/byte_addressable_buffer.rs index 4704f903a8..ab2a78cf65 100644 --- a/crates/rustc_codegen_spirv/src/builder/byte_addressable_buffer.rs +++ b/crates/rustc_codegen_spirv/src/builder/byte_addressable_buffer.rs @@ -5,12 +5,12 @@ use super::Builder; use crate::builder_spirv::{SpirvValue, SpirvValueExt, SpirvValueKind}; use crate::spirv_type::SpirvType; use rspirv::spirv::{Decoration, Word}; +use rustc_abi::{Align, Size}; use rustc_codegen_spirv_types::Capability; use rustc_codegen_ssa::traits::BuilderMethods; use rustc_errors::ErrorGuaranteed; use rustc_span::DUMMY_SP; -use rustc_target::abi::call::PassMode; -use rustc_target::abi::{Align, Size}; +use rustc_target::callconv::PassMode; impl<'a, 'tcx> Builder<'a, 'tcx> { fn load_err(&mut self, original_type: Word, invalid_type: Word) -> SpirvValue { diff --git a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs index 3f8467d65d..f35e3463bb 100644 --- a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs +++ b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::{FnDef, Instance, Ty, TyKind, TypingEnv}; use rustc_middle::{bug, ty}; use rustc_span::Span; use rustc_span::sym; -use rustc_target::abi::call::{FnAbi, PassMode}; +use rustc_target::callconv::{FnAbi, PassMode}; use std::assert_matches::assert_matches; fn int_type_width_signed(ty: Ty<'_>, cx: &CodegenCx<'_>) -> Option<(u64, bool)> { @@ -336,9 +336,9 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> { self.abort_with_kind_and_message_debug_printf("abort", "intrinsics::abort() called", []); } - fn assume(&mut self, _val: Self::Value) { - // TODO: llvm.assume - } + // FIXME(eddyb) `assume` is not implemented atm, so all of its forms should + // avoid computing its (potentially illegal) bool input in the first place. + fn assume(&mut self, _val: Self::Value) {} fn expect(&mut self, cond: Self::Value, _expected: bool) -> Self::Value { // TODO: llvm.expect diff --git a/crates/rustc_codegen_spirv/src/builder/mod.rs b/crates/rustc_codegen_spirv/src/builder/mod.rs index 044a9a13e6..f319d65d34 100644 --- a/crates/rustc_codegen_spirv/src/builder/mod.rs +++ b/crates/rustc_codegen_spirv/src/builder/mod.rs @@ -17,6 +17,7 @@ use crate::builder_spirv::{BuilderCursor, SpirvValue, SpirvValueExt}; use crate::codegen_cx::CodegenCx; use crate::spirv_type::SpirvType; use rspirv::spirv::Word; +use rustc_abi::{HasDataLayout, Size, TargetDataLayout}; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::{ @@ -34,8 +35,7 @@ use rustc_middle::ty::layout::{ use rustc_middle::ty::{Instance, Ty, TyCtxt, TypingEnv}; use rustc_span::Span; use rustc_span::def_id::DefId; -use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode}; -use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout}; +use rustc_target::callconv::{ArgAbi, FnAbi, PassMode}; use rustc_target::spec::{HasTargetSpec, Target}; use std::ops::{Deref, Range}; diff --git a/crates/rustc_codegen_spirv/src/builder_spirv.rs b/crates/rustc_codegen_spirv/src/builder_spirv.rs index 4c87f0584d..936edf883a 100644 --- a/crates/rustc_codegen_spirv/src/builder_spirv.rs +++ b/crates/rustc_codegen_spirv/src/builder_spirv.rs @@ -12,23 +12,23 @@ use rspirv::spirv::{ AddressingModel, Capability, MemoryModel, Op, SourceLanguage, StorageClass, Word, }; use rspirv::{binary::Assemble, binary::Disassemble}; +use rustc_abi::Size; use rustc_arena::DroplessArena; use rustc_codegen_ssa::traits::ConstCodegenMethods as _; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::sync::Lrc; use rustc_middle::bug; use rustc_middle::mir::interpret::ConstAllocation; use rustc_middle::ty::TyCtxt; use rustc_span::source_map::SourceMap; use rustc_span::symbol::Symbol; use rustc_span::{DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Span}; -use rustc_target::abi::Size; use std::assert_matches::assert_matches; use std::cell::{RefCell, RefMut}; use std::hash::{Hash, Hasher}; use std::iter; use std::ops::Range; use std::str; +use std::sync::Arc; use std::{fs::File, io::Write, path::Path}; #[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)] @@ -346,16 +346,16 @@ struct WithConstLegality { /// equivalent to a whole `rustc` `SourceFile`, but has O(1) `Eq` and `Hash` /// implementations (i.e. not involving the path or the contents of the file). /// -/// This is possible because we can compare `Lrc`s by equality, as +/// This is possible because we can compare `Arc`s by equality, as /// `rustc`'s `SourceMap` already ensures that only one `SourceFile` will be /// allocated for some given file. For hashing, we could hash the address, or /// -struct DebugFileKey(Lrc); +struct DebugFileKey(Arc); impl PartialEq for DebugFileKey { fn eq(&self, other: &Self) -> bool { let (Self(self_sf), Self(other_sf)) = (self, other); - Lrc::ptr_eq(self_sf, other_sf) + Arc::ptr_eq(self_sf, other_sf) } } impl Eq for DebugFileKey {} @@ -829,7 +829,7 @@ impl<'tcx> BuilderSpirv<'tcx> { (self.def_debug_file(lo_loc.file), lo_line_col..hi_line_col) } - fn def_debug_file(&self, sf: Lrc) -> DebugFileSpirv<'tcx> { + fn def_debug_file(&self, sf: Arc) -> DebugFileSpirv<'tcx> { *self .debug_file_cache .borrow_mut() @@ -839,7 +839,7 @@ impl<'tcx> BuilderSpirv<'tcx> { // FIXME(eddyb) it would be nicer if we could just rely on // `RealFileName::to_string_lossy` returning `Cow<'_, str>`, - // but sadly that `'_` is the lifetime of the temporary `Lrc`, + // but sadly that `'_` is the lifetime of the temporary `Arc`, // not `'tcx`, so we have to arena-allocate to get `&'tcx str`. let file_name = match &sf.name { FileName::Real(name) => { diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs index e70d56d8e3..bef5c500b4 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs @@ -6,12 +6,12 @@ use crate::abi::ConvSpirvType; use crate::builder_spirv::{SpirvConst, SpirvValue, SpirvValueExt, SpirvValueKind}; use crate::spirv_type::SpirvType; 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_middle::bug; use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar, alloc_range}; use rustc_middle::ty::layout::LayoutOf; use rustc_span::{DUMMY_SP, Span}; -use rustc_target::abi::{self, AddressSpace, Float, HasDataLayout, Integer, Primitive, Size}; impl<'tcx> CodegenCx<'tcx> { pub fn def_constant(&self, ty: Word, val: SpirvConst<'_, 'tcx>) -> SpirvValue { @@ -269,7 +269,12 @@ impl<'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'tcx> { GlobalAlloc::VTable(vty, dyn_ty) => { let alloc = self .tcx - .global_alloc(self.tcx.vtable_allocation((vty, dyn_ty.principal()))) + .global_alloc(self.tcx.vtable_allocation(( + vty, + dyn_ty.principal().map(|principal| { + self.tcx.instantiate_bound_regions_with_erased(principal) + }), + ))) .unwrap_memory(); let pointee = match self.lookup_type(ty) { SpirvType::Pointer { pointee } => pointee, diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs b/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs index f98daef2e3..75214e61c6 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs @@ -9,6 +9,7 @@ use crate::custom_decorations::{CustomDecoration, SrcLocDecoration}; use crate::spirv_type::SpirvType; use itertools::Itertools; use rspirv::spirv::{FunctionControl, LinkageType, StorageClass, Word}; +use rustc_abi::Align; use rustc_attr_parsing::InlineAttr; use rustc_codegen_ssa::traits::{PreDefineCodegenMethods, StaticCodegenMethods}; use rustc_hir::def::DefKind; @@ -19,7 +20,6 @@ use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; use rustc_middle::ty::{self, Instance, TypeVisitableExt, TypingEnv}; use rustc_span::Span; use rustc_span::def_id::DefId; -use rustc_target::abi::Align; fn attrs_to_spirv(attrs: &CodegenFnAttrs) -> FunctionControl { let mut control = FunctionControl::NONE; diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs b/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs index dfe40aee79..4a0c7a9b06 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs @@ -19,7 +19,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::Span; -use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode}; +use rustc_target::callconv::{ArgAbi, FnAbi, PassMode}; use std::assert_matches::assert_matches; /// Various information about an entry-point parameter, which can only be deduced diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs b/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs index 497a828e4f..77d5eacdf2 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs @@ -16,6 +16,7 @@ use crate::maybe_pqp_cg_ssa as rustc_codegen_ssa; use itertools::Itertools as _; use rspirv::dr::{Module, Operand}; use rspirv::spirv::{Decoration, LinkageType, Op, Word}; +use rustc_abi::{AddressSpace, HasDataLayout, TargetDataLayout}; use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, VariableKind}; use rustc_codegen_ssa::traits::{ @@ -27,12 +28,11 @@ use rustc_hir::def_id::DefId; use rustc_middle::mir; use rustc_middle::mir::mono::CodegenUnit; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv}; -use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty, TyCtxt, TypingEnv}; +use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypingEnv}; use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_span::{DUMMY_SP, SourceFile, Span}; -use rustc_target::abi::call::{FnAbi, PassMode}; -use rustc_target::abi::{AddressSpace, HasDataLayout, TargetDataLayout}; +use rustc_target::callconv::{FnAbi, PassMode}; use rustc_target::spec::{HasTargetSpec, Target, TargetTuple}; use std::cell::RefCell; use std::collections::BTreeSet; @@ -52,7 +52,7 @@ pub struct CodegenCx<'tcx> { pub function_parameter_values: RefCell>>, pub type_cache: TypeCache<'tcx>, /// Cache generated vtables - pub vtables: RefCell, Option>), SpirvValue>>, + pub vtables: RefCell, Option>), SpirvValue>>, pub ext_inst: RefCell, /// Invalid SPIR-V IDs that should be stripped from the final binary, /// each with its own reason and span that should be used for reporting @@ -854,7 +854,7 @@ impl<'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'tcx> { #[allow(clippy::type_complexity)] fn vtables( &self, - ) -> &RefCell, Option>), Self::Value>> { + ) -> &RefCell, Option>), Self::Value>> { &self.vtables } @@ -915,7 +915,7 @@ impl<'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'tcx> { fn create_vtable_debuginfo( &self, _ty: Ty<'tcx>, - _trait_ref: Option>, + _trait_ref: Option>, _vtable: Self::Value, ) { // Ignore. diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/type_.rs b/crates/rustc_codegen_spirv/src/codegen_cx/type_.rs index f0005a9e42..e4effb7e75 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/type_.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/type_.rs @@ -5,6 +5,7 @@ use super::CodegenCx; use crate::abi::ConvSpirvType; use crate::spirv_type::SpirvType; use rspirv::spirv::Word; +use rustc_abi::{AddressSpace, BackendRepr, Reg}; use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, LayoutTypeCodegenMethods}; use rustc_middle::ty::Ty; @@ -14,8 +15,7 @@ use rustc_middle::ty::layout::{ use rustc_middle::{bug, span_bug}; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Span}; -use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; -use rustc_target::abi::{AddressSpace, BackendRepr}; +use rustc_target::callconv::{CastTarget, FnAbi}; impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'tcx> { type LayoutOfResult = TyAndLayout<'tcx>; diff --git a/crates/rustc_codegen_spirv/src/custom_decorations.rs b/crates/rustc_codegen_spirv/src/custom_decorations.rs index e4c590bfcf..1027df9aed 100644 --- a/crates/rustc_codegen_spirv/src/custom_decorations.rs +++ b/crates/rustc_codegen_spirv/src/custom_decorations.rs @@ -7,13 +7,13 @@ use either::Either; use rspirv::dr::{Instruction, Module, Operand}; use rspirv::spirv::{Decoration, Op, Word}; use rustc_data_structures::fx::FxIndexMap; -use rustc_data_structures::sync::Lrc; use rustc_span::{FileName, SourceFile}; use rustc_span::{Span, source_map::SourceMap}; use smallvec::SmallVec; use std::borrow::Cow; use std::marker::PhantomData; use std::path::PathBuf; +use std::sync::Arc; use std::{fmt, iter, slice, str}; /// Decorations not native to SPIR-V require some form of encoding into existing @@ -321,7 +321,7 @@ struct SpvDebugFile<'a> { /// Source strings from one `OpSource`, and any number of `OpSourceContinued`. op_source_parts: SmallVec<[&'a str; 1]>, - regenerated_rustc_source_file: Option>, + regenerated_rustc_source_file: Option>, } impl<'a> SpanRegenerator<'a> { diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs index 8bd2c42f21..10e4778e56 100644 --- a/crates/rustc_codegen_spirv/src/lib.rs +++ b/crates/rustc_codegen_spirv/src/lib.rs @@ -79,6 +79,8 @@ use rustc_codegen_ssa as maybe_pqp_cg_ssa; // FIXME(eddyb) remove all `#[cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)]` // as soon as they're not needed anymore (i.e. using `rustc_codegen_ssa` again). +#[cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)] +extern crate rustc_abi; extern crate rustc_apfloat; #[cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)] extern crate rustc_arena; @@ -394,7 +396,6 @@ impl WriteBackendMethods for SpirvCodegenBackend { fn autodiff( _cgcx: &CodegenContext, - _tcx: TyCtxt<'_>, _module: &ModuleCodegen, _diff_fncs: Vec, _config: &ModuleConfig, diff --git a/crates/rustc_codegen_spirv/src/link.rs b/crates/rustc_codegen_spirv/src/link.rs index 37cb6db9e3..40dd23cc16 100644 --- a/crates/rustc_codegen_spirv/src/link.rs +++ b/crates/rustc_codegen_spirv/src/link.rs @@ -329,7 +329,7 @@ fn do_spirv_opt( match sess.opts.optimize { OptLevel::No => {} - OptLevel::Less | OptLevel::Default | OptLevel::Aggressive => { + OptLevel::Less | OptLevel::More | OptLevel::Aggressive => { optimizer.register_performance_passes(); } OptLevel::Size | OptLevel::SizeMin => { diff --git a/crates/rustc_codegen_spirv/src/linker/test.rs b/crates/rustc_codegen_spirv/src/linker/test.rs index e48382c97e..b8c05102fd 100644 --- a/crates/rustc_codegen_spirv/src/linker/test.rs +++ b/crates/rustc_codegen_spirv/src/linker/test.rs @@ -145,7 +145,6 @@ fn link_with_linker_opts( }; rustc_span::create_session_globals_then(sopts.edition, Some(sm_inputs), || { let mut sess = rustc_session::build_session( - early_dcx, sopts, CompilerIO { input: Input::Str { @@ -164,7 +163,10 @@ fn link_with_linker_opts( Default::default(), rustc_interface::util::rustc_version_str().unwrap_or("unknown"), Default::default(), - Default::default(), + { + extern crate rustc_driver_impl; + &rustc_driver_impl::USING_INTERNAL_FEATURES + }, Default::default(), ); diff --git a/crates/rustc_codegen_spirv/src/spirv_type.rs b/crates/rustc_codegen_spirv/src/spirv_type.rs index 69da8010e7..18c5d59e34 100644 --- a/crates/rustc_codegen_spirv/src/spirv_type.rs +++ b/crates/rustc_codegen_spirv/src/spirv_type.rs @@ -4,11 +4,11 @@ use crate::codegen_cx::CodegenCx; use indexmap::IndexSet; use rspirv::dr::Operand; use rspirv::spirv::{Decoration, Dim, ImageFormat, StorageClass, Word}; +use rustc_abi::{Align, Size}; use rustc_data_structures::fx::FxHashMap; use rustc_middle::span_bug; use rustc_span::def_id::DefId; use rustc_span::{Span, Symbol}; -use rustc_target::abi::{Align, Size}; use std::cell::RefCell; use std::fmt; use std::iter; diff --git a/rust-toolchain.toml b/rust-toolchain.toml index beebf8b60e..aeeb3d5fd3 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2025-01-24" +channel = "nightly-2025-02-16" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 99768c80a1c094a5cfc3b25a04e7a99de7210eae +# commit_hash = 9cd60bd2ccc41bc898d2ad86728f14035d2df72d # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. diff --git a/tests/compiletests/ui/arch/debug_printf_type_checking.stderr b/tests/compiletests/ui/arch/debug_printf_type_checking.stderr index b8ce41a270..125e1b1956 100644 --- a/tests/compiletests/ui/arch/debug_printf_type_checking.stderr +++ b/tests/compiletests/ui/arch/debug_printf_type_checking.stderr @@ -82,8 +82,9 @@ note: function defined here = note: this error originates in the macro `debug_printf` (in Nightly builds, run with -Z macro-backtrace for more info) help: change the type of the numeric literal from `u32` to `f32` | -21 | debug_printf!("%f", 11_f32); - | ~~~ +21 - debug_printf!("%f", 11_u32); +21 + debug_printf!("%f", 11_f32); + | error[E0308]: mismatched types --> $DIR/debug_printf_type_checking.rs:22:29 @@ -109,8 +110,9 @@ note: function defined here = note: this error originates in the macro `debug_printf` (in Nightly builds, run with -Z macro-backtrace for more info) help: change the type of the numeric literal from `f32` to `u32` | -22 | debug_printf!("%u", 11u32); - | ~~~ +22 - debug_printf!("%u", 11.0_f32); +22 + debug_printf!("%u", 11u32); + | error[E0277]: the trait bound `{float}: Vector` is not satisfied --> $DIR/debug_printf_type_checking.rs:23:9 diff --git a/tests/compiletests/ui/dis/ptr_copy.normal.stderr b/tests/compiletests/ui/dis/ptr_copy.normal.stderr index 70db15020e..8af2958946 100644 --- a/tests/compiletests/ui/dis/ptr_copy.normal.stderr +++ b/tests/compiletests/ui/dis/ptr_copy.normal.stderr @@ -1,13 +1,13 @@ error: cannot memcpy dynamically sized data - --> $CORE_SRC/intrinsics/mod.rs:4472:9 + --> $CORE_SRC/intrinsics/mod.rs:4543:9 | -4472 | copy(src, dst, count) +4543 | copy(src, dst, count) | ^^^^^^^^^^^^^^^^^^^^^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4449:21 + --> $CORE_SRC/intrinsics/mod.rs:4520:21 | -4449 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { +4520 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { | ^^^^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 @@ -28,25 +28,25 @@ note: called by `main` error: cannot cast between pointer types from `*f32` to `*struct () { }` - --> $CORE_SRC/intrinsics/mod.rs:4460:9 + --> $CORE_SRC/intrinsics/mod.rs:4531:9 | -4460 | / ub_checks::assert_unsafe_precondition!( -4461 | | check_language_ub, -4462 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +4531 | / ub_checks::assert_unsafe_precondition!( +4532 | | check_language_ub, +4533 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -4470 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4471 | | ); +4541 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +4542 | | ); | |_________^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4460:9 + --> $CORE_SRC/intrinsics/mod.rs:4531:9 | -4460 | / ub_checks::assert_unsafe_precondition!( -4461 | | check_language_ub, -4462 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +4531 | / ub_checks::assert_unsafe_precondition!( +4532 | | check_language_ub, +4533 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -4470 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4471 | | ); +4541 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +4542 | | ); | |_________^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 From 16812f3a4d01f66f2301f733315913dda12f81db Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 10 May 2025 21:55:16 +0300 Subject: [PATCH 26/38] Fix new clippy warnings. --- .../src/builder/builder_methods.rs | 27 +++++------------ .../src/builder/spirv_asm.rs | 6 ++-- .../src/codegen_cx/declare.rs | 2 +- .../src/linker/destructure_composites.rs | 1 - crates/spirv-builder/src/lib.rs | 29 +++++++++---------- crates/spirv-std/macros/src/image.rs | 1 - crates/spirv-std/macros/src/lib.rs | 16 +++++----- examples/runners/ash/src/main.rs | 2 +- examples/runners/wgpu/src/lib.rs | 13 ++++----- 9 files changed, 41 insertions(+), 56 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index 0cc78b4175..9dea36213b 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -139,11 +139,7 @@ fn memset_dynamic_scalar( .def(builder.span(), builder); let composite = builder .emit() - .composite_construct( - composite_type, - None, - iter::repeat(fill_var).take(byte_width), - ) + .composite_construct(composite_type, None, iter::repeat_n(fill_var, byte_width)) .unwrap(); let result_type = if is_float { SpirvType::Float(byte_width as u32 * 8) @@ -252,18 +248,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let elem_pat = self.memset_const_pattern(&self.lookup_type(element), fill_byte); self.constant_composite( ty.def(self.span(), self), - iter::repeat(elem_pat).take(count as usize), + iter::repeat_n(elem_pat, count as usize), ) .def(self) } SpirvType::Array { element, count } => { let elem_pat = self.memset_const_pattern(&self.lookup_type(element), fill_byte); let count = self.builder.lookup_const_scalar(count).unwrap() as usize; - self.constant_composite( - ty.def(self.span(), self), - iter::repeat(elem_pat).take(count), - ) - .def(self) + self.constant_composite(ty.def(self.span(), self), iter::repeat_n(elem_pat, count)) + .def(self) } SpirvType::RuntimeArray { .. } => { self.fatal("memset on runtime arrays not implemented yet") @@ -308,7 +301,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .composite_construct( ty.def(self.span(), self), None, - iter::repeat(elem_pat).take(count), + iter::repeat_n(elem_pat, count), ) .unwrap() } @@ -318,7 +311,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .composite_construct( ty.def(self.span(), self), None, - iter::repeat(elem_pat).take(count as usize), + iter::repeat_n(elem_pat, count as usize), ) .unwrap() } @@ -2752,14 +2745,10 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { } .def(self.span(), self); if self.builder.lookup_const(elt).is_some() { - self.constant_composite(result_type, iter::repeat(elt.def(self)).take(num_elts)) + self.constant_composite(result_type, iter::repeat_n(elt.def(self), num_elts)) } else { self.emit() - .composite_construct( - result_type, - None, - iter::repeat(elt.def(self)).take(num_elts), - ) + .composite_construct(result_type, None, iter::repeat_n(elt.def(self), num_elts)) .unwrap() .with_type(result_type) } diff --git a/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs b/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs index 50aa2184a4..320716f1f8 100644 --- a/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs +++ b/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs @@ -285,7 +285,7 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> { let start = line.as_str(); match line.next()? { // skip over leading whitespace - ch if ch.is_whitespace() => continue, + ch if ch.is_whitespace() => {} // lex a string '"' => { let mut cooked = String::new(); @@ -328,7 +328,7 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> { let end = loop { let end = line.as_str(); match line.next() { - Some(ch) if !ch.is_whitespace() => continue, + Some(ch) if !ch.is_whitespace() => {} _ => break end, } }; @@ -862,6 +862,8 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> { _ => return None, } + // HACK(eddyb) clippy false positive, `.ok()` loses information. + #[allow(clippy::manual_ok_err)] match subst_ty_pat( self, sig.output_type.unwrap(), diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs b/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs index 75214e61c6..ff221f0ad9 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs @@ -26,7 +26,7 @@ fn attrs_to_spirv(attrs: &CodegenFnAttrs) -> FunctionControl { match attrs.inline { InlineAttr::None => (), InlineAttr::Hint | InlineAttr::Always | InlineAttr::Force { .. } => { - control.insert(FunctionControl::INLINE) + control.insert(FunctionControl::INLINE); } InlineAttr::Never => control.insert(FunctionControl::DONT_INLINE), } diff --git a/crates/rustc_codegen_spirv/src/linker/destructure_composites.rs b/crates/rustc_codegen_spirv/src/linker/destructure_composites.rs index 9384eecf60..0185be16f9 100644 --- a/crates/rustc_codegen_spirv/src/linker/destructure_composites.rs +++ b/crates/rustc_codegen_spirv/src/linker/destructure_composites.rs @@ -51,7 +51,6 @@ pub fn destructure_composites(function: &mut Function) { rewrite_rules.get(&origin_id).map_or(origin_id, |id| *id), ); *inst = Instruction::new(Op::Nop, None, None, vec![]); - continue; } } } diff --git a/crates/spirv-builder/src/lib.rs b/crates/spirv-builder/src/lib.rs index c757b59f63..d9c0a353e5 100644 --- a/crates/spirv-builder/src/lib.rs +++ b/crates/spirv-builder/src/lib.rs @@ -1081,22 +1081,21 @@ struct RustcOutput { const ARTIFACT_SUFFIX: &str = ".spv.json"; fn get_sole_artifact(out: &str) -> Option { - let last = out - .lines() - .filter_map(|line| { - if let Ok(line) = serde_json::from_str::(line) { - Some(line) - } else { - // Pass through invalid lines - println!("{line}"); - None - } - }) - .filter(|line| line.reason == "compiler-artifact") - .last() - .expect("Did not find output file in rustc output"); + let mut last_compiler_artifact = None; + for line in out.lines() { + let Ok(msg) = serde_json::from_str::(line) else { + // Pass through invalid lines + println!("{line}"); + continue; + }; + if msg.reason == "compiler-artifact" { + last_compiler_artifact = Some(msg); + } + } + let last_compiler_artifact = + last_compiler_artifact.expect("Did not find output file in rustc output"); - let mut filenames = last + let mut filenames = last_compiler_artifact .filenames .unwrap() .into_iter() diff --git a/crates/spirv-std/macros/src/image.rs b/crates/spirv-std/macros/src/image.rs index 7cecb637a1..0af4a7c67c 100644 --- a/crates/spirv-std/macros/src/image.rs +++ b/crates/spirv-std/macros/src/image.rs @@ -218,7 +218,6 @@ impl Parse for ImageType { if input.peek(syn::Token![,]) { input.parse::()?; - continue; } else { break; } diff --git a/crates/spirv-std/macros/src/lib.rs b/crates/spirv-std/macros/src/lib.rs index f9f447004b..5651b394cf 100644 --- a/crates/spirv-std/macros/src/lib.rs +++ b/crates/spirv-std/macros/src/lib.rs @@ -109,20 +109,20 @@ use std::fmt::Write; /// ## Arguments /// /// - `dimensionality` — Dimensionality of an image. -/// Accepted values: `1D`, `2D`, `3D`, `rect`, `cube`, `subpass`. +/// Accepted values: `1D`, `2D`, `3D`, `rect`, `cube`, `subpass`. /// - `type` — The sampled type of an image, mutually exclusive with `format`, -/// when set the image format is unknown. -/// Accepted values: `f32`, `f64`, `u8`, `u16`, `u32`, `u64`, `i8`, `i16`, `i32`, `i64`. +/// when set the image format is unknown. +/// Accepted values: `f32`, `f64`, `u8`, `u16`, `u32`, `u64`, `i8`, `i16`, `i32`, `i64`. /// - `format` — The image format of the image, mutually exclusive with `type`. -/// Accepted values: Snake case versions of [`ImageFormat`]. +/// Accepted values: Snake case versions of [`ImageFormat`]. /// - `sampled` — Whether it is known that the image will be used with a sampler. -/// Accepted values: `true` or `false`. Default: `unknown`. +/// Accepted values: `true` or `false`. Default: `unknown`. /// - `multisampled` — Whether the image contains multisampled content. -/// Accepted values: `true` or `false`. Default: `false`. +/// Accepted values: `true` or `false`. Default: `false`. /// - `arrayed` — Whether the image contains arrayed content. -/// Accepted values: `true` or `false`. Default: `false`. +/// Accepted values: `true` or `false`. Default: `false`. /// - `depth` — Whether it is known that the image is a depth image. -/// Accepted values: `true` or `false`. Default: `unknown`. +/// Accepted values: `true` or `false`. Default: `unknown`. /// /// [`ImageFormat`]: spirv_std_types::image_params::ImageFormat /// diff --git a/examples/runners/ash/src/main.rs b/examples/runners/ash/src/main.rs index e667549421..3e22f9c268 100644 --- a/examples/runners/ash/src/main.rs +++ b/examples/runners/ash/src/main.rs @@ -151,7 +151,7 @@ pub fn main() { #[allow(deprecated)] event_loop .run(move |event, event_loop_window_target| match event { - Event::AboutToWait { .. } => { + Event::AboutToWait => { match compiler_receiver.try_recv() { Err(TryRecvError::Empty) => { if ctx.rendering_paused { diff --git a/examples/runners/wgpu/src/lib.rs b/examples/runners/wgpu/src/lib.rs index 34daf8d6f6..446407fabb 100644 --- a/examples/runners/wgpu/src/lib.rs +++ b/examples/runners/wgpu/src/lib.rs @@ -100,14 +100,11 @@ impl CompiledShaderModules { wanted_entry: &str, ) -> wgpu::ShaderModuleDescriptorSpirV<'a> { for (name, spv_module) in &self.named_spv_modules { - match name { - Some(name) if name != wanted_entry => continue, - _ => { - return wgpu::ShaderModuleDescriptorSpirV { - label: name.as_deref(), - source: Cow::Borrowed(&spv_module.source), - }; - } + if name.as_ref().is_none_or(|name| name == wanted_entry) { + return wgpu::ShaderModuleDescriptorSpirV { + label: name.as_deref(), + source: Cow::Borrowed(&spv_module.source), + }; } } unreachable!( From df80b6a5841bcb0085efa188dde699c04113c04a Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 7 May 2025 22:41:56 +0300 Subject: [PATCH 27/38] rustc_codegen_spirv: switch to Rust 2024 edition. --- crates/rustc_codegen_spirv/Cargo.toml | 2 +- crates/rustc_codegen_spirv/src/codegen_cx/mod.rs | 4 ++-- crates/rustc_codegen_spirv/src/custom_insts.rs | 2 +- crates/rustc_codegen_spirv/src/lib.rs | 2 +- .../rustc_codegen_spirv/src/linker/import_export_link.rs | 2 +- crates/rustc_codegen_spirv/src/linker/simple_passes.rs | 8 ++++---- .../src/linker/spirt_passes/diagnostics.rs | 6 +++--- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/crates/rustc_codegen_spirv/Cargo.toml b/crates/rustc_codegen_spirv/Cargo.toml index 5af8dbea20..fe335cadb0 100644 --- a/crates/rustc_codegen_spirv/Cargo.toml +++ b/crates/rustc_codegen_spirv/Cargo.toml @@ -4,7 +4,7 @@ description = "SPIR-V code generator backend for rustc" documentation = "https://rust-gpu.github.io/rust-gpu/api/rustc_codegen_spirv/index.html" version.workspace = true authors.workspace = true -edition.workspace = true +edition = "2024" license.workspace = true repository.workspace = true diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs b/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs index 77d5eacdf2..0668314faa 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs @@ -690,10 +690,10 @@ impl CodegenArgs { *current_id = *remap.entry(*current_id).or_insert_with(|| len as u32 + 1); }; module.all_inst_iter_mut().for_each(|inst| { - if let Some(ref mut result_id) = &mut inst.result_id { + if let Some(result_id) = &mut inst.result_id { insert(result_id); } - if let Some(ref mut result_type) = &mut inst.result_type { + if let Some(result_type) = &mut inst.result_type { insert(result_type); } inst.operands.iter_mut().for_each(|op| { diff --git a/crates/rustc_codegen_spirv/src/custom_insts.rs b/crates/rustc_codegen_spirv/src/custom_insts.rs index 946202ec00..6fac97096d 100644 --- a/crates/rustc_codegen_spirv/src/custom_insts.rs +++ b/crates/rustc_codegen_spirv/src/custom_insts.rs @@ -117,7 +117,7 @@ macro_rules! def_custom_insts { pub fn with_operands(self, operands: &[T]) -> CustomInst { match self { $(Self::$name => match operands { - [$($($field,)+ $(ref $variadic_field @ ..)?)?] => CustomInst::$name $({ + [$($($field,)+ $($variadic_field @ ..)?)?] => CustomInst::$name $({ $($field: $field.clone(),)+ $($variadic_field: $variadic_field.iter().cloned().collect())? })?, diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs index 10e4778e56..15e5730ecc 100644 --- a/crates/rustc_codegen_spirv/src/lib.rs +++ b/crates/rustc_codegen_spirv/src/lib.rs @@ -500,7 +500,7 @@ impl Drop for DumpModuleOnPanic<'_, '_, '_> { } /// This is the entrypoint for a hot plugged `rustc_codegen_spirv` -#[no_mangle] +#[unsafe(no_mangle)] pub fn __rustc_codegen_backend() -> Box { // Tweak rustc's default ICE panic hook, to direct people to `rust-gpu`. rustc_driver::install_ice_hook("https://github.com/rust-gpu/rust-gpu/issues/new", |dcx| { diff --git a/crates/rustc_codegen_spirv/src/linker/import_export_link.rs b/crates/rustc_codegen_spirv/src/linker/import_export_link.rs index 307277057a..e5290af40d 100644 --- a/crates/rustc_codegen_spirv/src/linker/import_export_link.rs +++ b/crates/rustc_codegen_spirv/src/linker/import_export_link.rs @@ -202,7 +202,7 @@ fn check_tys_equal( fn replace_all_uses_with(module: &mut Module, rules: &FxHashMap) { module.all_inst_iter_mut().for_each(|inst| { - if let Some(ref mut result_type) = &mut inst.result_type { + if let Some(result_type) = &mut inst.result_type { if let Some(&rewrite) = rules.get(result_type) { *result_type = rewrite; } diff --git a/crates/rustc_codegen_spirv/src/linker/simple_passes.rs b/crates/rustc_codegen_spirv/src/linker/simple_passes.rs index 68e820ae2a..77932b99c7 100644 --- a/crates/rustc_codegen_spirv/src/linker/simple_passes.rs +++ b/crates/rustc_codegen_spirv/src/linker/simple_passes.rs @@ -28,11 +28,11 @@ fn capability_for_float_width(width: u32) -> Option { pub fn shift_ids(module: &mut Module, add: u32) { module.all_inst_iter_mut().for_each(|inst| { - if let Some(ref mut result_id) = &mut inst.result_id { + if let Some(result_id) = &mut inst.result_id { *result_id += add; } - if let Some(ref mut result_type) = &mut inst.result_type { + if let Some(result_type) = &mut inst.result_type { *result_type += add; } @@ -130,11 +130,11 @@ pub fn compact_ids(module: &mut Module) -> u32 { }; module.all_inst_iter_mut().for_each(|inst| { - if let Some(ref mut result_id) = &mut inst.result_id { + if let Some(result_id) = &mut inst.result_id { *result_id = insert(*result_id); } - if let Some(ref mut result_type) = &mut inst.result_type { + if let Some(result_type) = &mut inst.result_type { *result_type = insert(*result_type); } diff --git a/crates/rustc_codegen_spirv/src/linker/spirt_passes/diagnostics.rs b/crates/rustc_codegen_spirv/src/linker/spirt_passes/diagnostics.rs index 948f14fe8e..29fefe430d 100644 --- a/crates/rustc_codegen_spirv/src/linker/spirt_passes/diagnostics.rs +++ b/crates/rustc_codegen_spirv/src/linker/spirt_passes/diagnostics.rs @@ -389,15 +389,15 @@ impl DiagnosticReporter<'_> { .split_last() .filter( |( - &UseOrigin::Global { + UseOrigin::Global { attrs: use_attrs, .. } - | &UseOrigin::IntraFunc { + | UseOrigin::IntraFunc { func_attrs: use_attrs, .. }, _, - )| { use_attrs == attrs }, + )| *use_attrs == attrs, ) .map_or((None, &self.use_stack[..]), |(current, stack)| { (Some(current), stack) From 8a1ac16227cd624c141bd622df4d6dd27d1ad0c4 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 7 May 2025 21:21:13 +0300 Subject: [PATCH 28/38] rustup: update to `nightly-2025-03-29` (~1.87). --- crates/rustc_codegen_spirv/build.rs | 38 ++++++++- crates/rustc_codegen_spirv/src/abi.rs | 16 ++-- crates/rustc_codegen_spirv/src/attr.rs | 20 +++-- .../src/builder/builder_methods.rs | 23 +++--- .../src/builder/intrinsics.rs | 77 +++++++++++-------- crates/rustc_codegen_spirv/src/builder/mod.rs | 2 +- .../src/codegen_cx/constant.rs | 12 +-- .../src/codegen_cx/entry.rs | 4 +- .../src/codegen_cx/type_.rs | 11 ++- .../rustc_codegen_spirv/src/custom_insts.rs | 3 +- crates/rustc_codegen_spirv/src/lib.rs | 21 ++++- .../src/linker/specializer.rs | 7 +- crates/rustc_codegen_spirv/src/symbols.rs | 12 +-- rust-toolchain.toml | 4 +- .../ui/arch/debug_printf_type_checking.stderr | 6 +- .../subgroup_cluster_size_0_fail.stderr | 2 +- ..._cluster_size_non_power_of_two_fail.stderr | 2 +- .../ui/dis/ptr_copy.normal.stderr | 32 ++++---- tests/compiletests/ui/dis/ptr_write.stderr | 2 +- .../ui/dis/ptr_write_method.stderr | 2 +- .../ui/lang/core/unwrap_or.stderr | 4 +- .../ui/spirv-attr/invalid-target.stderr | 30 +++++++- 22 files changed, 206 insertions(+), 124 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 7690495ae1..394820004e 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-02-16" +channel = "nightly-2025-03-29" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 9cd60bd2ccc41bc898d2ad86728f14035d2df72d"#; +# commit_hash = 920d95eaf23d7eb6b415d09868e4f793024fa604"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); @@ -159,9 +159,9 @@ fn generate_pqp_cg_ssa() -> Result<(), Box> { } } - // HACK(eddyb) remove `windows` dependency (from MSVC linker output - // parsing, which `rustc_codegen_spirv` will never invoke anyway). if relative_path == Path::new("src/back/link.rs") { + // HACK(eddyb) remove `windows` dependency (from MSVC linker output + // parsing, which `rustc_codegen_spirv` will never invoke anyway). src = src.replace( "#[cfg(not(windows))] fn escape_linker_output(", @@ -179,6 +179,33 @@ mod win {", "#[cfg(any())] mod win {", ); + // HACK(eddyb) remove `object` dependency (for Windows `raw_dylib` + // handling, which `rustc_codegen_spirv` will never invoke anyway). + src = src.replace("mod raw_dylib;", "// mod raw_dylib;"); + src = src.replace( + " + for output_path in raw_dylib::", + " + #[cfg(any())] + for output_path in raw_dylib::", + ); + src = src.replace( + " + for link_path in raw_dylib::", + " + #[cfg(any())] + for link_path in raw_dylib::", + ); + } + if relative_path == Path::new("src/back/metadata.rs") { + // HACK(eddyb) remove `object` dependency. + src = src.replace(" +pub(crate) fn create_object_file(sess: &Session) -> Option> {"," +pub(crate) fn create_object_file(_: &Session) -> Option> { + None +} +#[cfg(any())] +pub(crate) fn create_object_file(sess: &Session) -> Option> {"); } // HACK(eddyb) "typed alloca" patches. @@ -259,6 +286,9 @@ mod win {", println!("cargo::warning={line}"); } println!("cargo::warning="); + + // HACK(eddyb) allow the warning to be cleared after `lib.rs` is fixed. + println!("cargo:rerun-if-changed=src/lib.rs"); } // HACK(eddyb) write a file that can be `include!`d from `lib.rs`. diff --git a/crates/rustc_codegen_spirv/src/abi.rs b/crates/rustc_codegen_spirv/src/abi.rs index bab2ce329c..b1d2dff60d 100644 --- a/crates/rustc_codegen_spirv/src/abi.rs +++ b/crates/rustc_codegen_spirv/src/abi.rs @@ -8,8 +8,8 @@ use itertools::Itertools; use rspirv::spirv::{Dim, ImageFormat, StorageClass, Word}; use rustc_abi::ExternAbi as Abi; use rustc_abi::{ - Align, BackendRepr, FieldsShape, LayoutData, Primitive, ReprFlags, ReprOptions, Scalar, Size, - TagEncoding, VariantIdx, Variants, + Align, BackendRepr, FieldIdx, FieldsShape, LayoutData, Primitive, ReprFlags, ReprOptions, + Scalar, Size, TagEncoding, VariantIdx, Variants, }; use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; @@ -106,6 +106,7 @@ pub(crate) fn provide(providers: &mut Providers) { ref variants, backend_repr, largest_niche, + uninhabited, align, size, max_repr_align, @@ -153,6 +154,7 @@ pub(crate) fn provide(providers: &mut Providers) { }, backend_repr, largest_niche, + uninhabited, align, size, max_repr_align, @@ -201,7 +203,7 @@ pub(crate) fn provide(providers: &mut Providers) { let trivial_struct = match tcx.hir_node_by_def_id(def_id) { rustc_hir::Node::Item(item) => match item.kind { rustc_hir::ItemKind::Struct( - _, + .., &rustc_hir::Generics { params: &[] @@ -465,7 +467,7 @@ impl<'tcx> ConvSpirvType<'tcx> for TyAndLayout<'tcx> { // `ScalarPair`. // There's a few layers that we go through here. First we inspect layout.backend_repr, then if relevant, layout.fields, etc. match self.backend_repr { - BackendRepr::Uninhabited => SpirvType::Adt { + _ if self.uninhabited => SpirvType::Adt { def_id: def_id_for_spirv_type_adt(*self), size: Some(Size::ZERO), align: Align::from_bytes(0).unwrap(), @@ -526,7 +528,7 @@ impl<'tcx> ConvSpirvType<'tcx> for TyAndLayout<'tcx> { if let TyKind::Adt(adt, _) = self.ty.kind() { if let Variants::Single { index } = self.variants { for i in self.fields.index_by_increasing_offset() { - let field = &adt.variants()[index].fields[i.into()]; + let field = &adt.variants()[index].fields[FieldIdx::new(i)]; field_names.push(field.name); } } @@ -545,7 +547,7 @@ impl<'tcx> ConvSpirvType<'tcx> for TyAndLayout<'tcx> { } .def_with_name(cx, span, TyLayoutNameKey::from(*self)) } - BackendRepr::Vector { element, count } => { + BackendRepr::SimdVector { element, count } => { let elem_spirv = trans_scalar(cx, span, *self, element, Size::ZERO); SpirvType::Vector { element: elem_spirv, @@ -815,7 +817,7 @@ fn trans_struct<'tcx>(cx: &CodegenCx<'tcx>, span: Span, ty: TyAndLayout<'tcx>) - field_offsets.push(offset); if let Variants::Single { index } = ty.variants { if let TyKind::Adt(adt, _) = ty.ty.kind() { - let field = &adt.variants()[index].fields[i.into()]; + let field = &adt.variants()[index].fields[FieldIdx::new(i)]; field_names.push(field.name); } else { // FIXME(eddyb) this looks like something that should exist in rustc. diff --git a/crates/rustc_codegen_spirv/src/attr.rs b/crates/rustc_codegen_spirv/src/attr.rs index 7d30d586a9..b35dbb6c3c 100644 --- a/crates/rustc_codegen_spirv/src/attr.rs +++ b/crates/rustc_codegen_spirv/src/attr.rs @@ -253,8 +253,8 @@ fn target_from_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) -> Targ match impl_item.kind { hir::ImplItemKind::Const(..) => Target::AssocConst, hir::ImplItemKind::Fn(..) => { - let parent_owner_id = tcx.hir().get_parent_item(impl_item.hir_id()); - let containing_item = tcx.hir().expect_item(parent_owner_id.def_id); + let parent_owner_id = tcx.hir_get_parent_item(impl_item.hir_id()); + let containing_item = tcx.hir_expect_item(parent_owner_id.def_id); let containing_impl_is_for_trait = match &containing_item.kind { hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => of_trait.is_some(), _ => unreachable!("parent of an ImplItem must be an Impl"), @@ -280,7 +280,7 @@ impl CheckSpirvAttrVisitor<'_> { let parse_attrs = |attrs| crate::symbols::parse_attrs_for_checking(&self.sym, attrs); - let attrs = self.tcx.hir().attrs(hir_id); + let attrs = self.tcx.hir_attrs(hir_id); for parse_attr_result in parse_attrs(attrs) { let (span, parsed_attr) = match parse_attr_result { Ok(span_and_parsed_attr) => span_and_parsed_attr, @@ -326,10 +326,9 @@ impl CheckSpirvAttrVisitor<'_> { | SpirvAttribute::SpecConstant(_) => match target { Target::Param => { let parent_hir_id = self.tcx.parent_hir_id(hir_id); - let parent_is_entry_point = - parse_attrs(self.tcx.hir().attrs(parent_hir_id)) - .filter_map(|r| r.ok()) - .any(|(_, attr)| matches!(attr, SpirvAttribute::Entry(_))); + let parent_is_entry_point = parse_attrs(self.tcx.hir_attrs(parent_hir_id)) + .filter_map(|r| r.ok()) + .any(|(_, attr)| matches!(attr, SpirvAttribute::Entry(_))); if !parent_is_entry_point { self.tcx.dcx().span_err( span, @@ -417,8 +416,8 @@ impl CheckSpirvAttrVisitor<'_> { impl<'tcx> Visitor<'tcx> for CheckSpirvAttrVisitor<'tcx> { type NestedFilter = nested_filter::OnlyBodies; - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx } fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { @@ -497,8 +496,7 @@ fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { tcx, sym: Symbols::get(), }; - tcx.hir() - .visit_item_likes_in_module(module_def_id, check_spirv_attr_visitor); + tcx.hir_visit_item_likes_in_module(module_def_id, check_spirv_attr_visitor); if module_def_id.is_top_level_module() { check_spirv_attr_visitor.check_spirv_attributes(CRATE_HIR_ID, Target::Mod); } diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index 9dea36213b..265b46c5de 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -1712,7 +1712,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { place.val.llval, place.val.align, ); - OperandValue::Immediate(self.to_immediate(llval, place.layout)) + OperandValue::Immediate(llval) } else if let BackendRepr::ScalarPair(a, b) = place.layout.backend_repr { let b_offset = a .primitive() @@ -3443,20 +3443,15 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { // HACK(eddyb) even worse, each call made to // `rt::Placeholder::new(...)` takes anywhere - // between 16 and 20 instructions each, due - // to `enum`s represented as scalar pairs. + // between 8 and 16 instructions each, due + // to `rt::Count`'s `enum` representation. for _ in 0..fmt_placeholders_len { - try_rev_take(16).and_then(|insts| { - let scalar_pairs_with_used_2nd_field = insts - .iter() - .take_while(|inst| { - !matches!(inst, Inst::Load(..)) - }) - .filter(|inst| { - matches!(inst, Inst::InBoundsAccessChain(.., 1)) - }) - .count(); - try_rev_take(scalar_pairs_with_used_2nd_field * 2)?; + try_rev_take(4).and_then(|_| { + for _ in 0..2 { + if let [Inst::Bitcast(..), _] = try_rev_take(2)?[..] { + try_rev_take(4)?; + } + } Some(()) }) .ok_or_else(|| { diff --git a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs index f35e3463bb..36233f72fe 100644 --- a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs +++ b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs @@ -46,16 +46,10 @@ impl Builder<'_, '_> { ), }; let int_ty = SpirvType::Integer(width, false).def(self.span(), self); - let (mask_sign, mask_value) = match width { - 32 => ( - self.constant_u32(self.span(), 1 << 31), - self.constant_u32(self.span(), u32::MAX >> 1), - ), - 64 => ( - self.constant_u64(self.span(), 1 << 63), - self.constant_u64(self.span(), u64::MAX >> 1), - ), - _ => bug!("copysign must have width 32 or 64, not {}", width), + let [mask_sign, mask_value] = { + let sign_bit = 1u128.checked_shl(width - 1).unwrap(); + let value_mask = sign_bit - 1; + [sign_bit, value_mask].map(|v| self.constant_int(int_ty, v)) }; let val_bits = self.bitcast(val, int_ty); let sign_bits = self.bitcast(sign, int_ty); @@ -154,30 +148,44 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> { result } - sym::sqrtf32 | sym::sqrtf64 => self.gl_op(GLOp::Sqrt, ret_ty, [args[0].immediate()]), - sym::powif32 | sym::powif64 => { + sym::sqrtf32 | sym::sqrtf64 | sym::sqrtf128 => { + self.gl_op(GLOp::Sqrt, ret_ty, [args[0].immediate()]) + } + sym::powif32 | sym::powif64 | sym::powif128 => { let float = self.sitofp(args[1].immediate(), args[0].immediate().ty); self.gl_op(GLOp::Pow, ret_ty, [args[0].immediate(), float]) } - sym::sinf32 | sym::sinf64 => self.gl_op(GLOp::Sin, ret_ty, [args[0].immediate()]), - sym::cosf32 | sym::cosf64 => self.gl_op(GLOp::Cos, ret_ty, [args[0].immediate()]), - sym::powf32 | sym::powf64 => self.gl_op( + sym::sinf32 | sym::sinf64 | sym::sinf128 => { + self.gl_op(GLOp::Sin, ret_ty, [args[0].immediate()]) + } + sym::cosf32 | sym::cosf64 | sym::cosf128 => { + self.gl_op(GLOp::Cos, ret_ty, [args[0].immediate()]) + } + sym::powf32 | sym::powf64 | sym::powf128 => self.gl_op( GLOp::Pow, ret_ty, [args[0].immediate(), args[1].immediate()], ), - sym::expf32 | sym::expf64 => self.gl_op(GLOp::Exp, ret_ty, [args[0].immediate()]), - sym::exp2f32 | sym::exp2f64 => self.gl_op(GLOp::Exp2, ret_ty, [args[0].immediate()]), - sym::logf32 | sym::logf64 => self.gl_op(GLOp::Log, ret_ty, [args[0].immediate()]), - sym::log2f32 | sym::log2f64 => self.gl_op(GLOp::Log2, ret_ty, [args[0].immediate()]), - sym::log10f32 | sym::log10f64 => { + sym::expf32 | sym::expf64 | sym::expf128 => { + self.gl_op(GLOp::Exp, ret_ty, [args[0].immediate()]) + } + sym::exp2f32 | sym::exp2f64 | sym::exp2f128 => { + self.gl_op(GLOp::Exp2, ret_ty, [args[0].immediate()]) + } + sym::logf32 | sym::logf64 | sym::logf128 => { + self.gl_op(GLOp::Log, ret_ty, [args[0].immediate()]) + } + sym::log2f32 | sym::log2f64 | sym::log2f128 => { + self.gl_op(GLOp::Log2, ret_ty, [args[0].immediate()]) + } + sym::log10f32 | sym::log10f64 | sym::log10f128 => { // spir-v glsl doesn't have log10, so, // log10(x) == (1 / ln(10)) * ln(x) let mul = self.constant_float(args[0].immediate().ty, 1.0 / 10.0f64.ln()); let ln = self.gl_op(GLOp::Log, ret_ty, [args[0].immediate()]); self.fmul(mul, ln) } - sym::fmaf32 | sym::fmaf64 => self.gl_op( + sym::fmaf32 | sym::fmaf64 | sym::fmaf128 => self.gl_op( GLOp::Fma, ret_ty, [ @@ -186,30 +194,37 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> { args[2].immediate(), ], ), - sym::fabsf32 | sym::fabsf64 => self.gl_op(GLOp::FAbs, ret_ty, [args[0].immediate()]), - sym::minnumf32 | sym::minnumf64 => self.gl_op( + sym::fabsf32 | sym::fabsf64 | sym::fabsf128 => { + self.gl_op(GLOp::FAbs, ret_ty, [args[0].immediate()]) + } + sym::minnumf32 | sym::minnumf64 | sym::minnumf128 => self.gl_op( GLOp::FMin, ret_ty, [args[0].immediate(), args[1].immediate()], ), - sym::maxnumf32 | sym::maxnumf64 => self.gl_op( + sym::maxnumf32 | sym::maxnumf64 | sym::maxnumf128 => self.gl_op( GLOp::FMax, ret_ty, [args[0].immediate(), args[1].immediate()], ), - sym::copysignf32 | sym::copysignf64 => { + sym::copysignf32 | sym::copysignf64 | sym::copysignf128 => { let val = args[0].immediate(); let sign = args[1].immediate(); self.copysign(val, sign) } - sym::floorf32 | sym::floorf64 => self.gl_op(GLOp::Floor, ret_ty, [args[0].immediate()]), - sym::ceilf32 | sym::ceilf64 => self.gl_op(GLOp::Ceil, ret_ty, [args[0].immediate()]), - sym::truncf32 | sym::truncf64 => self.gl_op(GLOp::Trunc, ret_ty, [args[0].immediate()]), - sym::rintf32 | sym::rintf64 => { + 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()]) } - // TODO: Correctness of all these rounds - sym::nearbyintf32 | sym::nearbyintf64 | sym::roundf32 | sym::roundf64 => { + sym::roundf32 | sym::roundf64 | sym::roundf128 => { self.gl_op(GLOp::Round, ret_ty, [args[0].immediate()]) } diff --git a/crates/rustc_codegen_spirv/src/builder/mod.rs b/crates/rustc_codegen_spirv/src/builder/mod.rs index f319d65d34..37d7d53fe3 100644 --- a/crates/rustc_codegen_spirv/src/builder/mod.rs +++ b/crates/rustc_codegen_spirv/src/builder/mod.rs @@ -260,7 +260,7 @@ impl<'a, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'tcx> { } } -impl<'a, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'tcx> { +impl AbiBuilderMethods for Builder<'_, '_> { fn get_param(&mut self, index: usize) -> Self::Value { self.function_parameter_values.borrow()[&self.current_fn.def(self)][index] } diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs index bef5c500b4..87e7338de5 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs @@ -109,16 +109,13 @@ impl<'tcx> CodegenCx<'tcx> { } } -impl<'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'tcx> { +impl ConstCodegenMethods for CodegenCx<'_> { fn const_null(&self, t: Self::Type) -> Self::Value { self.constant_null(t) } fn const_undef(&self, ty: Self::Type) -> Self::Value { self.undef(ty) } - fn is_undef(&self, v: Self::Value) -> bool { - matches!(self.builder.lookup_const(v), Some(SpirvConst::Undef)) - } fn const_poison(&self, ty: Self::Type) -> Self::Value { // No distinction between undef and poison. self.const_undef(ty) @@ -319,7 +316,12 @@ impl<'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'tcx> { // the actual value generation until after a pointer to this value is cast // to its final type (e.g. that will be loaded as). // FIXME(eddyb) replace this with `qptr` handling of constant data. - fn const_data_from_alloc(&self, alloc: ConstAllocation<'tcx>) -> Self::Value { + fn const_data_from_alloc(&self, alloc: ConstAllocation<'_>) -> Self::Value { + // 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 void_type = SpirvType::Void.def(DUMMY_SP, self); self.def_constant(void_type, SpirvConst::ConstDataFromAlloc(alloc)) } diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs b/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs index 4a0c7a9b06..7435781173 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs @@ -82,7 +82,7 @@ impl<'tcx> CodegenCx<'tcx> { .span_err(span, format!("cannot declare {name} as an entry point")); return; }; - self.tcx.hir().body_owned_by(fn_local_def_id).params + self.tcx.hir_body_owned_by(fn_local_def_id).params }; for (arg_abi, hir_param) in fn_abi.args.iter().zip(hir_params) { match arg_abi.mode { @@ -429,7 +429,7 @@ impl<'tcx> CodegenCx<'tcx> { call_args: &mut Vec, decoration_locations: &mut FxHashMap, ) { - let attrs = AggregatedSpirvAttributes::parse(self, self.tcx.hir().attrs(hir_param.hir_id)); + let attrs = AggregatedSpirvAttributes::parse(self, self.tcx.hir_attrs(hir_param.hir_id)); let EntryParamDeducedFromRustRefOrValue { value_layout, diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/type_.rs b/crates/rustc_codegen_spirv/src/codegen_cx/type_.rs index e4effb7e75..6ed23ead89 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/type_.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/type_.rs @@ -97,18 +97,17 @@ impl<'tcx> LayoutTypeCodegenMethods<'tcx> for CodegenCx<'tcx> { fn is_backend_immediate(&self, layout: TyAndLayout<'tcx>) -> bool { match layout.backend_repr { - BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true, + BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => true, BackendRepr::ScalarPair(..) => false, - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => layout.is_zst(), + BackendRepr::Memory { .. } => layout.is_zst(), } } fn is_backend_scalar_pair(&self, layout: TyAndLayout<'tcx>) -> bool { match layout.backend_repr { BackendRepr::ScalarPair(..) => true, - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::Vector { .. } + BackendRepr::Scalar(_) + | BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } => false, } } @@ -130,7 +129,7 @@ impl<'tcx> CodegenCx<'tcx> { } } -impl<'tcx> BaseTypeCodegenMethods<'tcx> for CodegenCx<'tcx> { +impl BaseTypeCodegenMethods for CodegenCx<'_> { fn type_i8(&self) -> Self::Type { SpirvType::Integer(8, false).def(DUMMY_SP, self) } diff --git a/crates/rustc_codegen_spirv/src/custom_insts.rs b/crates/rustc_codegen_spirv/src/custom_insts.rs index 6fac97096d..645326028d 100644 --- a/crates/rustc_codegen_spirv/src/custom_insts.rs +++ b/crates/rustc_codegen_spirv/src/custom_insts.rs @@ -43,7 +43,8 @@ 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::{Hash128, StableHasher}; + use rustc_data_structures::stable_hasher::StableHasher; + use rustc_hashes::Hash128; use std::hash::Hash; let mut hasher = StableHasher::new(); diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs index 15e5730ecc..8cd300848d 100644 --- a/crates/rustc_codegen_spirv/src/lib.rs +++ b/crates/rustc_codegen_spirv/src/lib.rs @@ -2,6 +2,7 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![feature(assert_matches)] #![feature(box_patterns)] #![feature(debug_closure_helpers)] @@ -10,6 +11,7 @@ #![feature(let_chains)] #![feature(negative_impls)] #![feature(rustdoc_internals)] +#![feature(string_from_utf8_lossy_owned)] #![feature(trait_alias)] #![feature(try_blocks)] // HACK(eddyb) end of `rustc_codegen_ssa` crate-level attributes (see `build.rs`). @@ -96,6 +98,8 @@ extern crate rustc_driver; #[cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)] extern crate rustc_errors; #[cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)] +extern crate rustc_hashes; +#[cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)] extern crate rustc_hir; #[cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)] extern crate rustc_index; @@ -221,15 +225,21 @@ impl CodegenBackend for SpirvCodegenBackend { rustc_errors::DEFAULT_LOCALE_RESOURCE } - fn target_features_cfg(&self, sess: &Session, _allow_unstable: bool) -> Vec { + fn target_features_cfg(&self, sess: &Session) -> (Vec, Vec) { let cmdline = sess.opts.cg.target_feature.split(','); let cfg = sess.target.options.features.split(','); - cfg.chain(cmdline) + + let all_target_features: Vec<_> = cfg + .chain(cmdline) .filter(|l| l.starts_with('+')) .map(|l| &l[1..]) .filter(|l| !l.is_empty()) .map(Symbol::intern) - .collect() + .collect(); + + // HACK(eddyb) the second list is "including unstable target features", + // but there is no reason to make a distinction for SPIR-V ones. + (all_target_features.clone(), all_target_features) } fn provide(&self, providers: &mut rustc_middle::util::Providers) { @@ -329,7 +339,7 @@ impl WriteBackendMethods for SpirvCodegenBackend { unsafe fn optimize( _: &CodegenContext, _: DiagCtxtHandle<'_>, - _: &ModuleCodegen, + _: &mut ModuleCodegen, _: &ModuleConfig, ) -> Result<(), FatalError> { // TODO: Implement @@ -346,6 +356,7 @@ impl WriteBackendMethods for SpirvCodegenBackend { .to_vec(), name: thin_module.name().to_string(), kind: ModuleKind::Regular, + thin_lto_buffer: None, }; Ok(module) } @@ -380,6 +391,7 @@ impl WriteBackendMethods for SpirvCodegenBackend { bytecode: None, assembly: None, llvm_ir: None, + links_from_incr_cache: vec![], }) } @@ -466,6 +478,7 @@ impl ExtraBackendMethods for SpirvCodegenBackend { name: cgu_name.to_string(), module_llvm: spirv_module, kind: ModuleKind::Regular, + thin_lto_buffer: None, }, 0, ) diff --git a/crates/rustc_codegen_spirv/src/linker/specializer.rs b/crates/rustc_codegen_spirv/src/linker/specializer.rs index 73f24be19b..88b8095062 100644 --- a/crates/rustc_codegen_spirv/src/linker/specializer.rs +++ b/crates/rustc_codegen_spirv/src/linker/specializer.rs @@ -54,7 +54,6 @@ use crate::spirv_type_constraints::{self, InstSig, StorageClassPat, TyListPat, T use indexmap::{IndexMap, IndexSet}; use rspirv::dr::{Builder, Function, Instruction, Module, Operand}; use rspirv::spirv::{Op, StorageClass, Word}; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use smallvec::SmallVec; use std::collections::{BTreeMap, VecDeque}; @@ -1112,10 +1111,10 @@ impl<'a> Match<'a> { self } - fn debug_with_infer_cx<'b>( + fn debug_with_infer_cx<'b, T: Specialization>( &'b self, - cx: &'b InferCx<'a, impl Specialization>, - ) -> impl fmt::Debug + Captures<'a> + '_ { + cx: &'b InferCx<'a, T>, + ) -> impl fmt::Debug + use<'a, 'b, T> { fn debug_var_found<'a, A: smallvec::Array + 'a, T: 'a, TD: fmt::Display>( var_found: &'a SmallIntMap>>, display: &'a impl Fn(&'a T) -> TD, diff --git a/crates/rustc_codegen_spirv/src/symbols.rs b/crates/rustc_codegen_spirv/src/symbols.rs index 8aa95ae91c..2b413fe86c 100644 --- a/crates/rustc_codegen_spirv/src/symbols.rs +++ b/crates/rustc_codegen_spirv/src/symbols.rs @@ -3,7 +3,7 @@ use crate::builder::libm_intrinsics; use rspirv::spirv::{BuiltIn, ExecutionMode, ExecutionModel, StorageClass}; use rustc_ast::ast::{LitIntType, LitKind, MetaItemInner, MetaItemLit}; use rustc_data_structures::fx::FxHashMap; -use rustc_hir::{AttrKind, Attribute}; +use rustc_hir::Attribute; use rustc_span::Span; use rustc_span::symbol::{Ident, Symbol}; use std::rc::Rc; @@ -442,8 +442,8 @@ pub(crate) fn parse_attrs_for_checking<'a>( attrs: &'a [Attribute], ) -> impl Iterator> + 'a { attrs.iter().flat_map(move |attr| { - let (whole_attr_error, args) = match attr.kind { - AttrKind::Normal(ref item) => { + let (whole_attr_error, args) = match attr { + Attribute::Unparsed(item) => { // #[...] let s = &item.path.segments; if s.len() > 1 && s[0].name == sym.rust_gpu { @@ -452,7 +452,7 @@ pub(crate) fn parse_attrs_for_checking<'a>( // #[rust_gpu::...] but not #[rust_gpu::spirv] ( Some(Err(( - attr.span, + attr.span(), "unknown `rust_gpu` attribute, expected `rust_gpu::spirv`" .to_string(), ))), @@ -465,7 +465,7 @@ pub(crate) fn parse_attrs_for_checking<'a>( // #[rust_gpu::spirv] ( Some(Err(( - attr.span, + attr.span(), "#[rust_gpu::spirv(..)] attribute must have at least one argument" .to_string(), ))), @@ -477,7 +477,7 @@ pub(crate) fn parse_attrs_for_checking<'a>( (None, Default::default()) } } - AttrKind::DocComment(..) => (None, Default::default()), // doccomment + Attribute::Parsed(_) => (None, Default::default()), }; whole_attr_error diff --git a/rust-toolchain.toml b/rust-toolchain.toml index aeeb3d5fd3..9e460fdb40 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2025-02-16" +channel = "nightly-2025-03-29" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 9cd60bd2ccc41bc898d2ad86728f14035d2df72d +# commit_hash = 920d95eaf23d7eb6b415d09868e4f793024fa604 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. diff --git a/tests/compiletests/ui/arch/debug_printf_type_checking.stderr b/tests/compiletests/ui/arch/debug_printf_type_checking.stderr index 125e1b1956..5c1b487bde 100644 --- a/tests/compiletests/ui/arch/debug_printf_type_checking.stderr +++ b/tests/compiletests/ui/arch/debug_printf_type_checking.stderr @@ -73,7 +73,7 @@ help: the return type of this call is `u32` due to the type of the argument pass 21 | debug_printf!("%f", 11_u32); | ^^^^^^^^^^^^^^^^^^^^------^ | | - | this argument influences the return type of `spirv_std` + | this argument influences the return type of `debug_printf_assert_is_type` note: function defined here --> $SPIRV_STD_SRC/lib.rs:134:8 | @@ -101,7 +101,7 @@ help: the return type of this call is `f32` due to the type of the argument pass 22 | debug_printf!("%u", 11.0_f32); | ^^^^^^^^^^^^^^^^^^^^--------^ | | - | this argument influences the return type of `spirv_std` + | this argument influences the return type of `debug_printf_assert_is_type` note: function defined here --> $SPIRV_STD_SRC/lib.rs:134:8 | @@ -155,7 +155,7 @@ help: the return type of this call is `Vec2` due to the type of the argument pas 24 | debug_printf!("%f", Vec2::splat(33.3)); | ^^^^^^^^^^^^^^^^^^^^-----------------^ | | - | this argument influences the return type of `spirv_std` + | this argument influences the return type of `debug_printf_assert_is_type` note: function defined here --> $SPIRV_STD_SRC/lib.rs:134:8 | diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.stderr index db4905f35d..b192673f2c 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_0_fail.stderr @@ -8,7 +8,7 @@ error[E0080]: evaluation of `spirv_std::arch::subgroup_clustered_i_add::<0, u32, ... | 856 | | * `ClusterSize` must not be greater than the size of the group 857 | | "); - | |__^ the evaluated program panicked at '`ClusterSize` must be at least 1', $SPIRV_STD_SRC/arch/subgroup.rs:840:1 + | |__^ evaluation panicked: `ClusterSize` must be at least 1 | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `macro_subgroup_op_clustered` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.stderr b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.stderr index 5442b482b9..3fb35d0b83 100644 --- a/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.stderr +++ b/tests/compiletests/ui/arch/subgroup/subgroup_cluster_size_non_power_of_two_fail.stderr @@ -8,7 +8,7 @@ error[E0080]: evaluation of `spirv_std::arch::subgroup_clustered_i_add::<5, u32, ... | 856 | | * `ClusterSize` must not be greater than the size of the group 857 | | "); - | |__^ the evaluated program panicked at '`ClusterSize` must be a power of 2', $SPIRV_STD_SRC/arch/subgroup.rs:840:1 + | |__^ evaluation panicked: `ClusterSize` must be a power of 2 | = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `macro_subgroup_op_clustered` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/compiletests/ui/dis/ptr_copy.normal.stderr b/tests/compiletests/ui/dis/ptr_copy.normal.stderr index 8af2958946..4f3bc4bc7d 100644 --- a/tests/compiletests/ui/dis/ptr_copy.normal.stderr +++ b/tests/compiletests/ui/dis/ptr_copy.normal.stderr @@ -1,13 +1,13 @@ error: cannot memcpy dynamically sized data - --> $CORE_SRC/intrinsics/mod.rs:4543:9 + --> $CORE_SRC/intrinsics/mod.rs:3854:9 | -4543 | copy(src, dst, count) +3854 | copy(src, dst, count) | ^^^^^^^^^^^^^^^^^^^^^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4520:21 + --> $CORE_SRC/intrinsics/mod.rs:3834:21 | -4520 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { +3834 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { | ^^^^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 @@ -28,25 +28,25 @@ note: called by `main` error: cannot cast between pointer types from `*f32` to `*struct () { }` - --> $CORE_SRC/intrinsics/mod.rs:4531:9 + --> $CORE_SRC/intrinsics/mod.rs:3842:9 | -4531 | / ub_checks::assert_unsafe_precondition!( -4532 | | check_language_ub, -4533 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +3842 | / ub_checks::assert_unsafe_precondition!( +3843 | | check_language_ub, +3844 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -4541 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4542 | | ); +3852 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +3853 | | ); | |_________^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:4531:9 + --> $CORE_SRC/intrinsics/mod.rs:3842:9 | -4531 | / ub_checks::assert_unsafe_precondition!( -4532 | | check_language_ub, -4533 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +3842 | / ub_checks::assert_unsafe_precondition!( +3843 | | check_language_ub, +3844 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -4541 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -4542 | | ); +3852 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +3853 | | ); | |_________^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 diff --git a/tests/compiletests/ui/dis/ptr_write.stderr b/tests/compiletests/ui/dis/ptr_write.stderr index 4fb47101fe..63605fd7cf 100644 --- a/tests/compiletests/ui/dis/ptr_write.stderr +++ b/tests/compiletests/ui/dis/ptr_write.stderr @@ -4,7 +4,7 @@ %7 = OpLabel OpLine %8 7 35 %9 = OpLoad %10 %4 -OpLine %11 1582 8 +OpLine %11 1580 8 OpStore %6 %9 OpNoLine OpReturn diff --git a/tests/compiletests/ui/dis/ptr_write_method.stderr b/tests/compiletests/ui/dis/ptr_write_method.stderr index 7be26bb339..7201d604ef 100644 --- a/tests/compiletests/ui/dis/ptr_write_method.stderr +++ b/tests/compiletests/ui/dis/ptr_write_method.stderr @@ -4,7 +4,7 @@ %7 = OpLabel OpLine %8 7 37 %9 = OpLoad %10 %4 -OpLine %11 1582 8 +OpLine %11 1580 8 OpStore %6 %9 OpNoLine OpReturn diff --git a/tests/compiletests/ui/lang/core/unwrap_or.stderr b/tests/compiletests/ui/lang/core/unwrap_or.stderr index 8e0864941b..6e2009b4fb 100644 --- a/tests/compiletests/ui/lang/core/unwrap_or.stderr +++ b/tests/compiletests/ui/lang/core/unwrap_or.stderr @@ -6,7 +6,7 @@ OpLine %5 13 11 OpLine %12 999 14 %13 = OpBitcast %14 %8 OpLine %12 999 8 -%15 = OpIEqual %16 %13 %17 +%15 = OpINotEqual %16 %13 %17 OpNoLine OpSelectionMerge %18 None OpBranchConditional %15 %19 %20 @@ -15,7 +15,7 @@ OpBranch %18 %20 = OpLabel OpBranch %18 %18 = OpLabel -%21 = OpPhi %11 %22 %19 %10 %20 +%21 = OpPhi %11 %10 %19 %22 %20 OpLine %5 13 4 OpStore %23 %21 OpNoLine diff --git a/tests/compiletests/ui/spirv-attr/invalid-target.stderr b/tests/compiletests/ui/spirv-attr/invalid-target.stderr index c8733ab54f..842d832503 100644 --- a/tests/compiletests/ui/spirv-attr/invalid-target.stderr +++ b/tests/compiletests/ui/spirv-attr/invalid-target.stderr @@ -2620,5 +2620,33 @@ error: attribute is only valid on a function parameter, not on a foreign functio 87 | uniform, position, descriptor_set = 0, binding = 0, flat, invariant, // param-only | ^^^^^^^^^ -error: aborting due to 437 previous errors +error: unconstrained opaque type + --> $DIR/invalid-target.rs:118:18 + | +118 | type _OpaqueTy = impl Copy; + | ^^^^^^^^^ + | + = note: `_OpaqueTy` must be used in combination with a concrete type within the same crate + +error[E0308]: mismatched types + --> $DIR/invalid-target.rs:121:5 + | +118 | type _OpaqueTy = impl Copy; + | --------- the expected opaque type +119 | +120 | fn _opaque_ty_definer() -> _OpaqueTy { + | --------- expected `_OpaqueTy` because of return type +121 | () + | ^^ expected opaque type, found `()` + | + = note: expected opaque type `_OpaqueTy` + found unit type `()` +note: this item must have a `#[define_opaque(_OpaqueTy)]` attribute to be able to define hidden types + --> $DIR/invalid-target.rs:120:4 + | +120 | fn _opaque_ty_definer() -> _OpaqueTy { + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 439 previous errors +For more information about this error, try `rustc --explain E0308`. From 35d1f96a761115212a82d10ed147d16924e2e53c Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 7 May 2025 22:59:03 +0300 Subject: [PATCH 29/38] abi: more workarounds for old-style `#[repr(simd)] struct`s. --- crates/rustc_codegen_spirv/build.rs | 19 ++++-- crates/rustc_codegen_spirv/src/abi.rs | 84 ++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 394820004e..f342443dec 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -199,13 +199,16 @@ mod win {", } if relative_path == Path::new("src/back/metadata.rs") { // HACK(eddyb) remove `object` dependency. - src = src.replace(" -pub(crate) fn create_object_file(sess: &Session) -> Option> {"," + src = src.replace( + " +pub(crate) fn create_object_file(sess: &Session) -> Option> {", + " pub(crate) fn create_object_file(_: &Session) -> Option> { None } #[cfg(any())] -pub(crate) fn create_object_file(sess: &Session) -> Option> {"); +pub(crate) fn create_object_file(sess: &Session) -> Option> {", + ); } // HACK(eddyb) "typed alloca" patches. @@ -225,8 +228,16 @@ pub(crate) fn create_object_file(sess: &Session) -> Option { + (Some(element), bx.extract_element(llval, bx.cx().const_usize(i as u64))) + }", + ); } fs::write(out_path, src)?; diff --git a/crates/rustc_codegen_spirv/src/abi.rs b/crates/rustc_codegen_spirv/src/abi.rs index b1d2dff60d..8a1851951f 100644 --- a/crates/rustc_codegen_spirv/src/abi.rs +++ b/crates/rustc_codegen_spirv/src/abi.rs @@ -8,11 +8,12 @@ use itertools::Itertools; use rspirv::spirv::{Dim, ImageFormat, StorageClass, Word}; use rustc_abi::ExternAbi as Abi; use rustc_abi::{ - Align, BackendRepr, FieldIdx, FieldsShape, LayoutData, Primitive, ReprFlags, ReprOptions, - Scalar, Size, TagEncoding, VariantIdx, Variants, + Align, BackendRepr, FieldIdx, FieldsShape, HasDataLayout as _, LayoutData, Primitive, + ReprFlags, ReprOptions, Scalar, Size, TagEncoding, VariantIdx, Variants, }; use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; +use rustc_hashes::Hash64; use rustc_index::Idx; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout}; @@ -164,6 +165,85 @@ pub(crate) fn provide(providers: &mut Providers) { } providers.layout_of = |tcx, key| { + // HACK(eddyb) to special-case any types at all, they must be normalized, + // but when normalization would be needed, `layout_of`'s default provider + // recurses (supposedly for caching reasons), i.e. its calls `layout_of` + // w/ the normalized type in input, which once again reaches this hook, + // without ever needing any explicit normalization here. + let ty = key.value; + + // HACK(eddyb) bypassing upstream `#[repr(simd)]` changes (see also + // the later comment above `check_well_formed`, for more details). + let reimplement_old_style_repr_simd = match ty.kind() { + ty::Adt(def, args) if def.repr().simd() && !def.repr().packed() && def.is_struct() => { + Some(def.non_enum_variant()).and_then(|v| { + let (count, e_ty) = v + .fields + .iter() + .map(|f| f.ty(tcx, args)) + .dedup_with_count() + .exactly_one() + .ok()?; + let e_len = u64::try_from(count).ok().filter(|&e_len| e_len > 1)?; + Some((def, e_ty, e_len)) + }) + } + _ => None, + }; + + // HACK(eddyb) tweaked copy of the old upstream logic for `#[repr(simd)]`: + // https://github.com/rust-lang/rust/blob/1.86.0/compiler/rustc_ty_utils/src/layout.rs#L464-L590 + if let Some((adt_def, e_ty, e_len)) = reimplement_old_style_repr_simd { + let cx = rustc_middle::ty::layout::LayoutCx::new( + tcx, + key.typing_env.with_post_analysis_normalized(tcx), + ); + let dl = cx.data_layout(); + + // Compute the ABI of the element type: + let e_ly = cx.layout_of(e_ty)?; + let BackendRepr::Scalar(e_repr) = e_ly.backend_repr else { + // This error isn't caught in typeck, e.g., if + // the element type of the vector is generic. + tcx.dcx().span_fatal( + tcx.def_span(adt_def.did()), + format!( + "SIMD type `{ty}` with a non-primitive-scalar \ + (integer/float/pointer) element type `{}`", + e_ly.ty + ), + ); + }; + + // Compute the size and alignment of the vector: + let size = e_ly.size.checked_mul(e_len, dl).unwrap(); + let align = dl.llvmlike_vector_align(size); + let size = size.align_to(align.abi); + + let layout = tcx.mk_layout(LayoutData { + variants: Variants::Single { + index: rustc_abi::FIRST_VARIANT, + }, + fields: FieldsShape::Array { + stride: e_ly.size, + count: e_len, + }, + backend_repr: BackendRepr::SimdVector { + element: e_repr, + count: e_len, + }, + largest_niche: e_ly.largest_niche, + uninhabited: false, + size, + align, + max_repr_align: None, + unadjusted_abi_align: align.abi, + randomization_seed: e_ly.randomization_seed.wrapping_add(Hash64::new(e_len)), + }); + + return Ok(TyAndLayout { ty, layout }); + } + let TyAndLayout { ty, mut layout } = (rustc_interface::DEFAULT_QUERY_PROVIDERS.layout_of)(tcx, key)?; From 36e6f950922d66c3b41cd0eda45c06351600febb Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 12 May 2025 16:03:50 +0300 Subject: [PATCH 30/38] Fix new clippy warnings. --- tests/compiletests/src/main.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/compiletests/src/main.rs b/tests/compiletests/src/main.rs index 4f14d419b3..e41dbc94ec 100644 --- a/tests/compiletests/src/main.rs +++ b/tests/compiletests/src/main.rs @@ -383,13 +383,10 @@ fn rust_flags(codegen_backend_path: &Path) -> String { fn map_status_to_result(status: std::process::ExitStatus) -> io::Result<()> { match status.success() { true => Ok(()), - false => Err(io::Error::new( - io::ErrorKind::Other, - format!( - "process terminated with non-zero code: {}", - status.code().unwrap_or(0) - ), - )), + false => Err(io::Error::other(format!( + "process terminated with non-zero code: {}", + status.code().unwrap_or(0) + ))), } } From 81b292191cdd38d4b792916f04ec2941c3dd9972 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 12 May 2025 16:44:47 +0300 Subject: [PATCH 31/38] rustup: update to `nightly-2025-04-13`. --- crates/rustc_codegen_spirv/build.rs | 4 +- .../src/builder/builder_methods.rs | 86 +++++++------------ crates/rustc_codegen_spirv/src/lib.rs | 9 +- crates/rustc_codegen_spirv/src/link.rs | 10 ++- crates/rustc_codegen_spirv/src/linker/mod.rs | 4 +- crates/rustc_codegen_spirv/src/linker/test.rs | 2 +- rust-toolchain.toml | 4 +- .../ui/dis/ptr_copy.normal.stderr | 32 +++---- tests/compiletests/ui/dis/ptr_copy.rs | 6 +- tests/compiletests/ui/dis/ptr_read.stderr | 2 +- .../ui/dis/ptr_read_method.stderr | 2 +- tests/compiletests/ui/dis/ptr_write.stderr | 2 +- .../ui/dis/ptr_write_method.stderr | 2 +- 13 files changed, 75 insertions(+), 90 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index f342443dec..3c8f93a991 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-03-29" +channel = "nightly-2025-04-13" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 920d95eaf23d7eb6b415d09868e4f793024fa604"#; +# commit_hash = 9ffde4b089fe8e43d5891eb517001df27a8443ff"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index 265b46c5de..9a55369b17 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -658,12 +658,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if !indices.is_empty() { // HACK(eddyb) Cargo silences warnings in dependencies. let force_warn = |span, msg| -> rustc_errors::Diag<'_, ()> { - rustc_errors::Diag::new( - self.tcx.dcx(), - rustc_errors::Level::ForceWarning(None), - msg, - ) - .with_span(span) + rustc_errors::Diag::new(self.tcx.dcx(), rustc_errors::Level::ForceWarning, msg) + .with_span(span) }; force_warn( self.span(), @@ -3391,7 +3387,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { pieces_len_id, rt_args_slice_ptr_id, rt_args_len_id, - _fmt_placeholders_slice_ptr_id, + fmt_placeholders_slice_ptr_id, fmt_placeholders_len_id, ] if (pieces_len, rt_args_count) == (!0, !0) => { let [pieces_len, rt_args_len, fmt_placeholders_len] = match [ @@ -3411,56 +3407,40 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { } }; - // FIXME(eddyb) simplify the logic below after - // https://github.com/rust-lang/rust/pull/139131 - // (~1.88) as it makes `&[rt::Placeholder]` - // constant (via promotion to 'static). - - // HACK(eddyb) this accounts for all of these: - // - `rt::Placeholder` copies into array: 2 insts each - // - `rt::UnsafeArg::new()` call: 1 inst - // - runtime args array->slice ptr cast: 1 inst - // - placeholders array->slice ptr cast: 1 inst - let extra_insts = try_rev_take(3 + fmt_placeholders_len * 2).ok_or_else(|| { + let prepare_args_insts = try_rev_take(3).ok_or_else(|| { FormatArgsNotRecognized( "fmt::Arguments::new_v1_formatted call: ran out of instructions".into(), ) })?; - let rt_args_slice_ptr_id = match extra_insts[..] { - [.., Inst::Bitcast(out_id, in_id), Inst::Bitcast(..)] - if out_id == rt_args_slice_ptr_id => - { - in_id - } - _ => { - let mut insts = extra_insts; - insts.extend(fmt_args_new_call_insts); - return Err(FormatArgsNotRecognized(format!( - "fmt::Arguments::new_v1_formatted call sequence ({insts:?})", - ))); - } - }; - - // HACK(eddyb) even worse, each call made to - // `rt::Placeholder::new(...)` takes anywhere - // between 8 and 16 instructions each, due - // to `rt::Count`'s `enum` representation. - for _ in 0..fmt_placeholders_len { - try_rev_take(4).and_then(|_| { - for _ in 0..2 { - if let [Inst::Bitcast(..), _] = try_rev_take(2)?[..] { - try_rev_take(4)?; - } + let (rt_args_slice_ptr_id, _fmt_placeholders_slice_ptr_id) = + match prepare_args_insts[..] { + [ + // HACK(eddyb) `rt::UnsafeArg::new()` call + // (`unsafe` ZST "constructor"). + Inst::Call(_, _, ref rt_unsafe_arg_call_args), + Inst::Bitcast( + rt_args_cast_out_id, + rt_args_cast_in_id, + ), + Inst::Bitcast( + placeholders_cast_out_id, + placeholders_cast_in_id, + ), + ] if rt_unsafe_arg_call_args.is_empty() + && rt_args_cast_out_id == rt_args_slice_ptr_id + && placeholders_cast_out_id + == fmt_placeholders_slice_ptr_id => + { + (rt_args_cast_in_id, placeholders_cast_in_id) } - Some(()) - }) - .ok_or_else(|| { - FormatArgsNotRecognized( - "fmt::rt::Placeholder::new call: ran out of instructions" - .into(), - ) - })?; - } + _ => { + let mut insts = prepare_args_insts; + insts.extend(fmt_args_new_call_insts); + return Err(FormatArgsNotRecognized(format!( + "fmt::Arguments::new_v1_formatted call sequence ({insts:?})", + ))); + } + }; decoded_format_args .has_unknown_fmt_placeholder_to_args_mapping = @@ -3749,7 +3729,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { let force_warn = |span, msg| -> rustc_errors::Diag<'_, ()> { rustc_errors::Diag::new( self.tcx.dcx(), - rustc_errors::Level::ForceWarning(None), + rustc_errors::Level::ForceWarning, msg, ) .with_span(span) diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs index 8cd300848d..893a1724ac 100644 --- a/crates/rustc_codegen_spirv/src/lib.rs +++ b/crates/rustc_codegen_spirv/src/lib.rs @@ -5,7 +5,6 @@ #![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 #![feature(assert_matches)] #![feature(box_patterns)] -#![feature(debug_closure_helpers)] #![feature(file_buffered)] #![feature(if_let_guard)] #![feature(let_chains)] @@ -374,9 +373,11 @@ impl WriteBackendMethods for SpirvCodegenBackend { module: ModuleCodegen, _config: &ModuleConfig, ) -> Result { - let path = cgcx - .output_filenames - .temp_path(OutputType::Object, Some(&module.name)); + let path = cgcx.output_filenames.temp_path_for_cgu( + OutputType::Object, + &module.name, + cgcx.invocation_temp.as_deref(), + ); // Note: endianness doesn't matter, readers deduce endianness from magic header. let spirv_module = spirv_tools::binary::from_binary(&module.module_llvm); File::create(&path) diff --git a/crates/rustc_codegen_spirv/src/link.rs b/crates/rustc_codegen_spirv/src/link.rs index 40dd23cc16..22165e2a03 100644 --- a/crates/rustc_codegen_spirv/src/link.rs +++ b/crates/rustc_codegen_spirv/src/link.rs @@ -65,8 +65,12 @@ 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, None); + let out_filename_file_for_writing = out_filename.file_for_writing( + outputs, + OutputType::Exe, + crate_name, + sess.invocation_temp.as_deref(), + ); match crate_type { CrateType::Rlib => { link_rlib(sess, codegen_results, &out_filename_file_for_writing); @@ -137,7 +141,7 @@ fn link_rlib(sess: &Session, codegen_results: &CodegenResults, out_filename: &Pa create_archive( &file_list, - codegen_results.metadata.raw_data(), + codegen_results.metadata.stub_or_full(), out_filename, ); } diff --git a/crates/rustc_codegen_spirv/src/linker/mod.rs b/crates/rustc_codegen_spirv/src/linker/mod.rs index c4fed4d06b..41a46a03e4 100644 --- a/crates/rustc_codegen_spirv/src/linker/mod.rs +++ b/crates/rustc_codegen_spirv/src/linker/mod.rs @@ -496,7 +496,7 @@ pub fn link( let (spv_words, module_or_err, lower_from_spv_timer) = spv_module_to_spv_words_and_spirt_module(&output); let module = &mut module_or_err.map_err(|e| { - let spv_path = outputs.temp_path_ext("spirt-lower-from-spv-input.spv", None); + let spv_path = outputs.temp_path_for_diagnostic("spirt-lower-from-spv-input.spv"); let was_saved_msg = match std::fs::write(&spv_path, spirv_tools::binary::from_binary(&spv_words)) { @@ -787,7 +787,7 @@ impl Drop for SpirtDumpGuard<'_> { self.per_pass_module_for_dumping .push(("", self.module.clone())); } - dump_spirt_file_path = Some(self.outputs.temp_path_ext("spirt", None)); + dump_spirt_file_path = Some(self.outputs.temp_path_for_diagnostic("spirt")); } if let Some(dump_spirt_file_path) = &dump_spirt_file_path { diff --git a/crates/rustc_codegen_spirv/src/linker/test.rs b/crates/rustc_codegen_spirv/src/linker/test.rs index b8c05102fd..1a1e1061ec 100644 --- a/crates/rustc_codegen_spirv/src/linker/test.rs +++ b/crates/rustc_codegen_spirv/src/linker/test.rs @@ -143,7 +143,7 @@ fn link_with_linker_opts( hash_kind: sopts.unstable_opts.src_hash_algorithm(&target), checksum_hash_kind: None, }; - rustc_span::create_session_globals_then(sopts.edition, Some(sm_inputs), || { + rustc_span::create_session_globals_then(sopts.edition, &[], Some(sm_inputs), || { let mut sess = rustc_session::build_session( sopts, CompilerIO { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 9e460fdb40..0dcbd4e65c 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2025-03-29" +channel = "nightly-2025-04-13" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 920d95eaf23d7eb6b415d09868e4f793024fa604 +# commit_hash = 9ffde4b089fe8e43d5891eb517001df27a8443ff # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. diff --git a/tests/compiletests/ui/dis/ptr_copy.normal.stderr b/tests/compiletests/ui/dis/ptr_copy.normal.stderr index 4f3bc4bc7d..9a7f61fe3c 100644 --- a/tests/compiletests/ui/dis/ptr_copy.normal.stderr +++ b/tests/compiletests/ui/dis/ptr_copy.normal.stderr @@ -1,13 +1,13 @@ error: cannot memcpy dynamically sized data - --> $CORE_SRC/intrinsics/mod.rs:3854:9 + --> $CORE_SRC/intrinsics/mod.rs:3805:9 | -3854 | copy(src, dst, count) +3805 | copy(src, dst, count) | ^^^^^^^^^^^^^^^^^^^^^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:3834:21 + --> $CORE_SRC/intrinsics/mod.rs:3785:21 | -3834 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { +3785 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { | ^^^^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 @@ -28,25 +28,25 @@ note: called by `main` error: cannot cast between pointer types from `*f32` to `*struct () { }` - --> $CORE_SRC/intrinsics/mod.rs:3842:9 + --> $CORE_SRC/intrinsics/mod.rs:3793:9 | -3842 | / ub_checks::assert_unsafe_precondition!( -3843 | | check_language_ub, -3844 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +3793 | / ub_checks::assert_unsafe_precondition!( +3794 | | check_language_ub, +3795 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -3852 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -3853 | | ); +3803 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +3804 | | ); | |_________^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:3842:9 + --> $CORE_SRC/intrinsics/mod.rs:3793:9 | -3842 | / ub_checks::assert_unsafe_precondition!( -3843 | | check_language_ub, -3844 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +3793 | / ub_checks::assert_unsafe_precondition!( +3794 | | check_language_ub, +3795 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -3852 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -3853 | | ); +3803 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +3804 | | ); | |_________^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 diff --git a/tests/compiletests/ui/dis/ptr_copy.rs b/tests/compiletests/ui/dis/ptr_copy.rs index 89f1a83d84..59a08ce76b 100644 --- a/tests/compiletests/ui/dis/ptr_copy.rs +++ b/tests/compiletests/ui/dis/ptr_copy.rs @@ -11,9 +11,9 @@ use spirv_std::spirv; fn copy_via_raw_ptr(src: &f32, dst: &mut f32) { #[cfg(via_intrinsic)] { - extern "rust-intrinsic" { - fn copy(src: *const T, dst: *mut T, count: usize); - } + #[rustc_intrinsic] + unsafe fn copy(src: *const T, dst: *mut T, count: usize); + unsafe { copy(src, dst, 1) } } diff --git a/tests/compiletests/ui/dis/ptr_read.stderr b/tests/compiletests/ui/dis/ptr_read.stderr index c3de258279..6535a9f5f1 100644 --- a/tests/compiletests/ui/dis/ptr_read.stderr +++ b/tests/compiletests/ui/dis/ptr_read.stderr @@ -2,7 +2,7 @@ %4 = OpFunctionParameter %5 %6 = OpFunctionParameter %5 %7 = OpLabel -OpLine %8 1380 8 +OpLine %8 1420 8 %9 = OpLoad %10 %4 OpLine %11 7 13 OpStore %6 %9 diff --git a/tests/compiletests/ui/dis/ptr_read_method.stderr b/tests/compiletests/ui/dis/ptr_read_method.stderr index c3de258279..6535a9f5f1 100644 --- a/tests/compiletests/ui/dis/ptr_read_method.stderr +++ b/tests/compiletests/ui/dis/ptr_read_method.stderr @@ -2,7 +2,7 @@ %4 = OpFunctionParameter %5 %6 = OpFunctionParameter %5 %7 = OpLabel -OpLine %8 1380 8 +OpLine %8 1420 8 %9 = OpLoad %10 %4 OpLine %11 7 13 OpStore %6 %9 diff --git a/tests/compiletests/ui/dis/ptr_write.stderr b/tests/compiletests/ui/dis/ptr_write.stderr index 63605fd7cf..69b26d117f 100644 --- a/tests/compiletests/ui/dis/ptr_write.stderr +++ b/tests/compiletests/ui/dis/ptr_write.stderr @@ -4,7 +4,7 @@ %7 = OpLabel OpLine %8 7 35 %9 = OpLoad %10 %4 -OpLine %11 1580 8 +OpLine %11 1620 8 OpStore %6 %9 OpNoLine OpReturn diff --git a/tests/compiletests/ui/dis/ptr_write_method.stderr b/tests/compiletests/ui/dis/ptr_write_method.stderr index 7201d604ef..b8e0a95ff0 100644 --- a/tests/compiletests/ui/dis/ptr_write_method.stderr +++ b/tests/compiletests/ui/dis/ptr_write_method.stderr @@ -4,7 +4,7 @@ %7 = OpLabel OpLine %8 7 37 %9 = OpLoad %10 %4 -OpLine %11 1580 8 +OpLine %11 1620 8 OpStore %6 %9 OpNoLine OpReturn From faa5e0b47a58b5a99d5f588f8869209a872893de Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 12 May 2025 17:31:07 +0300 Subject: [PATCH 32/38] rustup: update to `nightly-2025-04-14`. --- crates/rustc_codegen_spirv/build.rs | 4 +-- rust-toolchain.toml | 4 +-- .../ui/dis/ptr_copy.normal.stderr | 32 +++++++++---------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 3c8f93a991..3b37830bea 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-04-13" +channel = "nightly-2025-04-14" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 9ffde4b089fe8e43d5891eb517001df27a8443ff"#; +# commit_hash = 092a284ba0421695f2032c947765429fd7095796"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 0dcbd4e65c..f881e6bba0 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2025-04-13" +channel = "nightly-2025-04-14" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 9ffde4b089fe8e43d5891eb517001df27a8443ff +# commit_hash = 092a284ba0421695f2032c947765429fd7095796 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. diff --git a/tests/compiletests/ui/dis/ptr_copy.normal.stderr b/tests/compiletests/ui/dis/ptr_copy.normal.stderr index 9a7f61fe3c..10019c222f 100644 --- a/tests/compiletests/ui/dis/ptr_copy.normal.stderr +++ b/tests/compiletests/ui/dis/ptr_copy.normal.stderr @@ -1,13 +1,13 @@ error: cannot memcpy dynamically sized data - --> $CORE_SRC/intrinsics/mod.rs:3805:9 + --> $CORE_SRC/intrinsics/mod.rs:3806:9 | -3805 | copy(src, dst, count) +3806 | copy(src, dst, count) | ^^^^^^^^^^^^^^^^^^^^^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:3785:21 + --> $CORE_SRC/intrinsics/mod.rs:3786:21 | -3785 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { +3786 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { | ^^^^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 @@ -28,25 +28,25 @@ note: called by `main` error: cannot cast between pointer types from `*f32` to `*struct () { }` - --> $CORE_SRC/intrinsics/mod.rs:3793:9 + --> $CORE_SRC/intrinsics/mod.rs:3794:9 | -3793 | / ub_checks::assert_unsafe_precondition!( -3794 | | check_language_ub, -3795 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +3794 | / ub_checks::assert_unsafe_precondition!( +3795 | | check_language_ub, +3796 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -3803 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -3804 | | ); +3804 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +3805 | | ); | |_________^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:3793:9 + --> $CORE_SRC/intrinsics/mod.rs:3794:9 | -3793 | / ub_checks::assert_unsafe_precondition!( -3794 | | check_language_ub, -3795 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +3794 | / ub_checks::assert_unsafe_precondition!( +3795 | | check_language_ub, +3796 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -3803 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -3804 | | ); +3804 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +3805 | | ); | |_________^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 From c8503db66e994a35e109034cb9963a54a95d5d70 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 12 May 2025 17:41:40 +0300 Subject: [PATCH 33/38] abi: unhide `bool`'s niche, breaking `Option` for Rust-GPU but allowing libcore to build. --- crates/rustc_codegen_spirv/src/abi.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/rustc_codegen_spirv/src/abi.rs b/crates/rustc_codegen_spirv/src/abi.rs index 8a1851951f..0502b6a851 100644 --- a/crates/rustc_codegen_spirv/src/abi.rs +++ b/crates/rustc_codegen_spirv/src/abi.rs @@ -249,7 +249,14 @@ pub(crate) fn provide(providers: &mut Providers) { #[allow(clippy::match_like_matches_macro)] let hide_niche = match ty.kind() { - ty::Bool => true, + ty::Bool => { + // HACK(eddyb) we can't bypass e.g. `Option` being a byte, + // due to `core` PR https://github.com/rust-lang/rust/pull/138881 + // (which adds a new `transmute`, from `ControlFlow` to `u8`). + let libcore_needs_bool_niche = true; + + !libcore_needs_bool_niche + } _ => false, }; From 9e1605a0e23fb95e7b60979b48ebda8f340d28f3 Mon Sep 17 00:00:00 2001 From: Christian Legnitto Date: Wed, 30 Apr 2025 12:32:42 -0400 Subject: [PATCH 34/38] Switch all crates to Rust 2024 edition. --- Cargo.toml | 2 +- crates/rustc_codegen_spirv/Cargo.toml | 2 +- crates/spirv-std/src/arch.rs | 220 ++--- crates/spirv-std/src/arch/atomics.rs | 596 +++++++------ crates/spirv-std/src/arch/barrier.rs | 150 ++-- .../arch/demote_to_helper_invocation_ext.rs | 4 +- crates/spirv-std/src/arch/mesh_shading.rs | 40 +- crates/spirv-std/src/arch/primitive.rs | 36 +- crates/spirv-std/src/arch/ray_tracing.rs | 46 +- .../spirv-std/src/byte_addressable_buffer.rs | 56 +- crates/spirv-std/src/ray_tracing.rs | 818 ++++++++++-------- crates/spirv-std/src/runtime_array.rs | 52 +- examples/runners/ash/src/main.rs | 30 +- examples/runners/wgpu/src/lib.rs | 22 +- .../ui/arch/all_memory_barrier.stderr | 2 +- .../all_memory_barrier_with_group_sync.stderr | 2 +- .../ui/arch/device_memory_barrier.stderr | 2 +- ...vice_memory_barrier_with_group_sync.stderr | 2 +- .../ui/arch/workgroup_memory_barrier.stderr | 2 +- ...roup_memory_barrier_with_group_sync.stderr | 2 +- 20 files changed, 1134 insertions(+), 952 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 414f537e02..aa689a7da0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ members = [ [workspace.package] version = "0.9.0" authors = ["rust-gpu developers", "Embark "] -edition = "2021" +edition = "2024" license = "MIT OR Apache-2.0" repository = "https://github.com/rust-gpu/rust-gpu" diff --git a/crates/rustc_codegen_spirv/Cargo.toml b/crates/rustc_codegen_spirv/Cargo.toml index fe335cadb0..5af8dbea20 100644 --- a/crates/rustc_codegen_spirv/Cargo.toml +++ b/crates/rustc_codegen_spirv/Cargo.toml @@ -4,7 +4,7 @@ description = "SPIR-V code generator backend for rustc" documentation = "https://rust-gpu.github.io/rust-gpu/api/rustc_codegen_spirv/index.html" version.workspace = true authors.workspace = true -edition = "2024" +edition.workspace = true license.workspace = true repository.workspace = true diff --git a/crates/spirv-std/src/arch.rs b/crates/spirv-std/src/arch.rs index 95e7d908d8..df0d061c74 100644 --- a/crates/spirv-std/src/arch.rs +++ b/crates/spirv-std/src/arch.rs @@ -87,18 +87,20 @@ pub unsafe fn vector_extract_dynamic( vector: impl Vector, index: usize, ) -> T { - let mut result = T::default(); - - asm! { - "%vector = OpLoad _ {vector}", - "%element = OpVectorExtractDynamic _ %vector {index}", - "OpStore {element} %element", - vector = in(reg) &vector, - index = in(reg) index, - element = in(reg) &mut result - } + unsafe { + let mut result = T::default(); - result + asm! { + "%vector = OpLoad _ {vector}", + "%element = OpVectorExtractDynamic _ %vector {index}", + "OpStore {element} %element", + vector = in(reg) &vector, + index = in(reg) index, + element = in(reg) &mut result + } + + result + } } /// Make a copy of a vector, with a single, variably selected, @@ -115,20 +117,22 @@ pub unsafe fn vector_insert_dynamic, const N: usize>( index: usize, element: T, ) -> V { - let mut result = V::default(); - - asm! { - "%vector = OpLoad _ {vector}", - "%element = OpLoad _ {element}", - "%new_vector = OpVectorInsertDynamic _ %vector %element {index}", - "OpStore {result} %new_vector", - vector = in(reg) &vector, - index = in(reg) index, - element = in(reg) &element, - result = in(reg) &mut result, - } + unsafe { + let mut result = V::default(); - result + asm! { + "%vector = OpLoad _ {vector}", + "%element = OpLoad _ {element}", + "%new_vector = OpVectorInsertDynamic _ %vector %element {index}", + "OpStore {result} %new_vector", + vector = in(reg) &vector, + index = in(reg) index, + element = in(reg) &element, + result = in(reg) &mut result, + } + + result + } } /// Fragment-shader discard. Equivalvent to `discard()` from GLSL @@ -150,17 +154,19 @@ pub fn kill() -> ! { #[spirv_std_macros::gpu_only] #[doc(alias = "OpReadClockKHR")] pub unsafe fn read_clock_khr() -> u64 { - let mut result: u64; - - asm! { - "%uint = OpTypeInt 32 0", - "%scope = OpConstant %uint {scope}", - "{result} = OpReadClockKHR typeof*{result} %scope", - result = out(reg) result, - scope = const SCOPE, - }; + unsafe { + let mut result: u64; - result + asm! { + "%uint = OpTypeInt 32 0", + "%scope = OpConstant %uint {scope}", + "{result} = OpReadClockKHR typeof*{result} %scope", + result = out(reg) result, + scope = const SCOPE, + }; + + result + } } /// Like `read_clock_khr` but returns a vector to avoid requiring the `Int64` @@ -170,35 +176,39 @@ pub unsafe fn read_clock_khr() -> u64 { #[spirv_std_macros::gpu_only] #[doc(alias = "OpReadClockKHR")] pub unsafe fn read_clock_uvec2_khr, const SCOPE: u32>() -> V { - let mut result = V::default(); + unsafe { + let mut result = V::default(); - asm! { - "%uint = OpTypeInt 32 0", - "%scope = OpConstant %uint {scope}", - "%result = OpReadClockKHR typeof*{result} %scope", - "OpStore {result} %result", - result = in(reg) &mut result, - scope = const SCOPE, - }; + asm! { + "%uint = OpTypeInt 32 0", + "%scope = OpConstant %uint {scope}", + "%result = OpReadClockKHR typeof*{result} %scope", + "OpStore {result} %result", + result = in(reg) &mut result, + scope = const SCOPE, + }; - result + result + } } #[cfg(target_arch = "spirv")] unsafe fn call_glsl_op_with_ints(a: T, b: T) -> T { - let mut result = T::default(); - asm!( - "%glsl = OpExtInstImport \"GLSL.std.450\"", - "%a = OpLoad _ {a}", - "%b = OpLoad _ {b}", - "%result = OpExtInst typeof*{result} %glsl {op} %a %b", - "OpStore {result} %result", - a = in(reg) &a, - b = in(reg) &b, - result = in(reg) &mut result, - op = const OP - ); - result + unsafe { + let mut result = T::default(); + asm!( + "%glsl = OpExtInstImport \"GLSL.std.450\"", + "%a = OpLoad _ {a}", + "%b = OpLoad _ {b}", + "%result = OpExtInst typeof*{result} %glsl {op} %a %b", + "OpStore {result} %result", + a = in(reg) &a, + b = in(reg) &b, + result = in(reg) &mut result, + op = const OP + ); + result + } } /// Compute the minimum of two unsigned integers via a GLSL extended instruction. @@ -245,83 +255,91 @@ pub trait IndexUnchecked { impl IndexUnchecked for [T] { #[cfg(target_arch = "spirv")] unsafe fn index_unchecked(&self, index: usize) -> &T { - // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. - let mut result_slot = core::mem::MaybeUninit::uninit(); - asm! { - "%slice_ptr = OpLoad _ {slice_ptr_ptr}", - "%data_ptr = OpCompositeExtract _ %slice_ptr 0", - "%result = OpAccessChain _ %data_ptr {index}", - "OpStore {result_slot} %result", - slice_ptr_ptr = in(reg) &self, - index = in(reg) index, - result_slot = in(reg) result_slot.as_mut_ptr(), + unsafe { + // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. + let mut result_slot = core::mem::MaybeUninit::uninit(); + asm! { + "%slice_ptr = OpLoad _ {slice_ptr_ptr}", + "%data_ptr = OpCompositeExtract _ %slice_ptr 0", + "%result = OpAccessChain _ %data_ptr {index}", + "OpStore {result_slot} %result", + slice_ptr_ptr = in(reg) &self, + index = in(reg) index, + result_slot = in(reg) result_slot.as_mut_ptr(), + } + result_slot.assume_init() } - result_slot.assume_init() } #[cfg(not(target_arch = "spirv"))] unsafe fn index_unchecked(&self, index: usize) -> &T { - self.get_unchecked(index) + unsafe { self.get_unchecked(index) } } #[cfg(target_arch = "spirv")] unsafe fn index_unchecked_mut(&mut self, index: usize) -> &mut T { - // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. - let mut result_slot = core::mem::MaybeUninit::uninit(); - asm! { - "%slice_ptr = OpLoad _ {slice_ptr_ptr}", - "%data_ptr = OpCompositeExtract _ %slice_ptr 0", - "%result = OpAccessChain _ %data_ptr {index}", - "OpStore {result_slot} %result", - slice_ptr_ptr = in(reg) &self, - index = in(reg) index, - result_slot = in(reg) result_slot.as_mut_ptr(), + unsafe { + // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. + let mut result_slot = core::mem::MaybeUninit::uninit(); + asm! { + "%slice_ptr = OpLoad _ {slice_ptr_ptr}", + "%data_ptr = OpCompositeExtract _ %slice_ptr 0", + "%result = OpAccessChain _ %data_ptr {index}", + "OpStore {result_slot} %result", + slice_ptr_ptr = in(reg) &self, + index = in(reg) index, + result_slot = in(reg) result_slot.as_mut_ptr(), + } + result_slot.assume_init() } - result_slot.assume_init() } #[cfg(not(target_arch = "spirv"))] unsafe fn index_unchecked_mut(&mut self, index: usize) -> &mut T { - self.get_unchecked_mut(index) + unsafe { self.get_unchecked_mut(index) } } } impl IndexUnchecked for [T; N] { #[cfg(target_arch = "spirv")] unsafe fn index_unchecked(&self, index: usize) -> &T { - // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. - let mut result_slot = core::mem::MaybeUninit::uninit(); - asm! { - "%result = OpAccessChain _ {array_ptr} {index}", - "OpStore {result_slot} %result", - array_ptr = in(reg) self, - index = in(reg) index, - result_slot = in(reg) result_slot.as_mut_ptr(), + unsafe { + // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. + let mut result_slot = core::mem::MaybeUninit::uninit(); + asm! { + "%result = OpAccessChain _ {array_ptr} {index}", + "OpStore {result_slot} %result", + array_ptr = in(reg) self, + index = in(reg) index, + result_slot = in(reg) result_slot.as_mut_ptr(), + } + result_slot.assume_init() } - result_slot.assume_init() } #[cfg(not(target_arch = "spirv"))] unsafe fn index_unchecked(&self, index: usize) -> &T { - self.get_unchecked(index) + unsafe { self.get_unchecked(index) } } #[cfg(target_arch = "spirv")] unsafe fn index_unchecked_mut(&mut self, index: usize) -> &mut T { - // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. - let mut result_slot = core::mem::MaybeUninit::uninit(); - asm! { - "%result = OpAccessChain _ {array_ptr} {index}", - "OpStore {result_slot} %result", - array_ptr = in(reg) self, - index = in(reg) index, - result_slot = in(reg) result_slot.as_mut_ptr(), + unsafe { + // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. + let mut result_slot = core::mem::MaybeUninit::uninit(); + asm! { + "%result = OpAccessChain _ {array_ptr} {index}", + "OpStore {result_slot} %result", + array_ptr = in(reg) self, + index = in(reg) index, + result_slot = in(reg) result_slot.as_mut_ptr(), + } + result_slot.assume_init() } - result_slot.assume_init() } #[cfg(not(target_arch = "spirv"))] unsafe fn index_unchecked_mut(&mut self, index: usize) -> &mut T { - self.get_unchecked_mut(index) + unsafe { self.get_unchecked_mut(index) } } } diff --git a/crates/spirv-std/src/arch/atomics.rs b/crates/spirv-std/src/arch/atomics.rs index e03ebaa4c4..d818a0e0fd 100644 --- a/crates/spirv-std/src/arch/atomics.rs +++ b/crates/spirv-std/src/arch/atomics.rs @@ -14,21 +14,23 @@ use crate::{ #[doc(alias = "OpAtomicLoad")] #[inline] pub unsafe fn atomic_load(ptr: &N) -> N { - let mut result = N::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%result = OpAtomicLoad _ {ptr} %scope %semantics", - "OpStore {result} %result", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - result = in(reg) &mut result + unsafe { + let mut result = N::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%result = OpAtomicLoad _ {ptr} %scope %semantics", + "OpStore {result} %result", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + result = in(reg) &mut result + } + + result } - - result } /// Atomically store through `ptr` using the given `SEMANTICS`. All subparts of @@ -41,16 +43,18 @@ pub unsafe fn atomic_store( ptr: &mut N, value: N, ) { - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "OpAtomicStore {ptr} %scope %semantics %value", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - value = in(reg) &value + unsafe { + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "OpAtomicStore {ptr} %scope %semantics %value", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + value = in(reg) &value + } } } @@ -69,23 +73,25 @@ pub unsafe fn atomic_exchange ptr: &mut N, value: N, ) -> N { - let mut old = N::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicExchange _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = N::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicExchange _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -111,27 +117,29 @@ pub unsafe fn atomic_compare_exchange< value: I, comparator: I, ) -> I { - let mut old = I::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%equal = OpConstant %u32 {equal}", - "%unequal = OpConstant %u32 {unequal}", - "%value = OpLoad _ {value}", - "%comparator = OpLoad _ {comparator}", - "%old = OpAtomicCompareExchange _ {ptr} %scope %equal %unequal %value %comparator", - "OpStore {old} %old", - scope = const SCOPE, - equal = const EQUAL, - unequal = const UNEQUAL, - ptr = in(reg) ptr, - value = in(reg) &value, - comparator = in(reg) &comparator, - old = in(reg) &mut old, + unsafe { + let mut old = I::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%equal = OpConstant %u32 {equal}", + "%unequal = OpConstant %u32 {unequal}", + "%value = OpLoad _ {value}", + "%comparator = OpLoad _ {comparator}", + "%old = OpAtomicCompareExchange _ {ptr} %scope %equal %unequal %value %comparator", + "OpStore {old} %old", + scope = const SCOPE, + equal = const EQUAL, + unequal = const UNEQUAL, + ptr = in(reg) ptr, + value = in(reg) &value, + comparator = in(reg) &comparator, + old = in(reg) &mut old, + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -148,21 +156,23 @@ pub unsafe fn atomic_compare_exchange< pub unsafe fn atomic_i_increment( ptr: &mut I, ) -> I { - let mut old = I::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%old = OpAtomicIIncrement _ {ptr} %scope %semantics", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old + unsafe { + let mut old = I::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%old = OpAtomicIIncrement _ {ptr} %scope %semantics", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -179,21 +189,23 @@ pub unsafe fn atomic_i_increment( ptr: &mut I, ) -> I { - let mut old = I::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%old = OpAtomicIDecrement _ {ptr} %scope %semantics", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old + unsafe { + let mut old = I::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%old = OpAtomicIDecrement _ {ptr} %scope %semantics", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -211,23 +223,25 @@ pub unsafe fn atomic_i_add( ptr: &mut I, value: I, ) -> I { - let mut old = I::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicIAdd _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = I::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicIAdd _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -245,23 +259,25 @@ pub unsafe fn atomic_i_sub( ptr: &mut I, value: I, ) -> I { - let mut old = I::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicISub _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = I::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicISub _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -280,23 +296,25 @@ pub unsafe fn atomic_s_min S { - let mut old = S::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicSMin _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = S::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicSMin _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -315,23 +333,25 @@ pub unsafe fn atomic_u_min U { - let mut old = U::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicUMin _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = U::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicUMin _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -350,23 +370,25 @@ pub unsafe fn atomic_s_max S { - let mut old = S::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicSMax _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = S::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicSMax _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -385,23 +407,25 @@ pub unsafe fn atomic_u_max U { - let mut old = U::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicUMax _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = U::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicUMax _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -419,23 +443,25 @@ pub unsafe fn atomic_and( ptr: &mut I, value: I, ) -> I { - let mut old = I::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicAnd _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = I::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicAnd _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -453,23 +479,25 @@ pub unsafe fn atomic_or( ptr: &mut I, value: I, ) -> I { - let mut old = I::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicOr _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = I::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicOr _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -487,23 +515,25 @@ pub unsafe fn atomic_xor( ptr: &mut I, value: I, ) -> I { - let mut old = I::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicXor _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = I::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicXor _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -522,23 +552,25 @@ pub unsafe fn atomic_f_min( ptr: &mut F, value: F, ) -> F { - let mut old = F::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicFMinEXT _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = F::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicFMinEXT _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -557,23 +589,25 @@ pub unsafe fn atomic_f_max( ptr: &mut F, value: F, ) -> F { - let mut old = F::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicFMaxEXT _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = F::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicFMaxEXT _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } /// Perform the following steps atomically with respect to any other atomic @@ -591,21 +625,23 @@ pub unsafe fn atomic_f_add( ptr: &mut F, value: F, ) -> F { - let mut old = F::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%scope = OpConstant %u32 {scope}", - "%semantics = OpConstant %u32 {semantics}", - "%value = OpLoad _ {value}", - "%old = OpAtomicFAddEXT _ {ptr} %scope %semantics %value", - "OpStore {old} %old", - scope = const SCOPE, - semantics = const SEMANTICS, - ptr = in(reg) ptr, - old = in(reg) &mut old, - value = in(reg) &value + unsafe { + let mut old = F::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%scope = OpConstant %u32 {scope}", + "%semantics = OpConstant %u32 {semantics}", + "%value = OpLoad _ {value}", + "%old = OpAtomicFAddEXT _ {ptr} %scope %semantics %value", + "OpStore {old} %old", + scope = const SCOPE, + semantics = const SEMANTICS, + ptr = in(reg) ptr, + old = in(reg) &mut old, + value = in(reg) &value + } + + old } - - old } diff --git a/crates/spirv-std/src/arch/barrier.rs b/crates/spirv-std/src/arch/barrier.rs index 8b70a536f6..aa7df1746c 100644 --- a/crates/spirv-std/src/arch/barrier.rs +++ b/crates/spirv-std/src/arch/barrier.rs @@ -38,15 +38,17 @@ pub unsafe fn control_barrier< const MEMORY: u32, // Scope const SEMANTICS: u32, // Semantics >() { - asm! { - "%u32 = OpTypeInt 32 0", - "%execution = OpConstant %u32 {execution}", - "%memory = OpConstant %u32 {memory}", - "%semantics = OpConstant %u32 {semantics}", - "OpControlBarrier %execution %memory %semantics", - execution = const EXECUTION, - memory = const MEMORY, - semantics = const SEMANTICS, + unsafe { + asm! { + "%u32 = OpTypeInt 32 0", + "%execution = OpConstant %u32 {execution}", + "%memory = OpConstant %u32 {memory}", + "%semantics = OpConstant %u32 {semantics}", + "OpControlBarrier %execution %memory %semantics", + execution = const EXECUTION, + memory = const MEMORY, + semantics = const SEMANTICS, + } } } @@ -72,13 +74,15 @@ pub unsafe fn memory_barrier< const MEMORY: u32, // Scope const SEMANTICS: u32, // Semantics >() { - asm! { - "%u32 = OpTypeInt 32 0", - "%memory = OpConstant %u32 {memory}", - "%semantics = OpConstant %u32 {semantics}", - "OpMemoryBarrier %memory %semantics", - memory = const MEMORY, - semantics = const SEMANTICS, + unsafe { + asm! { + "%u32 = OpTypeInt 32 0", + "%memory = OpConstant %u32 {memory}", + "%semantics = OpConstant %u32 {semantics}", + "OpMemoryBarrier %memory %semantics", + memory = const MEMORY, + semantics = const SEMANTICS, + } } } @@ -90,13 +94,15 @@ pub unsafe fn memory_barrier< #[spirv_std_macros::gpu_only] #[inline] pub unsafe fn workgroup_memory_barrier() { - memory_barrier::< - { crate::memory::Scope::Workgroup as u32 }, - { - crate::memory::Semantics::WORKGROUP_MEMORY.bits() - | crate::memory::Semantics::ACQUIRE_RELEASE.bits() - }, - >(); + unsafe { + memory_barrier::< + { crate::memory::Scope::Workgroup as u32 }, + { + crate::memory::Semantics::WORKGROUP_MEMORY.bits() + | crate::memory::Semantics::ACQUIRE_RELEASE.bits() + }, + >(); + } } /// Blocks execution of all threads in a group until all group shared accesses have been completed and all threads in the group have reached this call. @@ -107,14 +113,16 @@ pub unsafe fn workgroup_memory_barrier() { #[spirv_std_macros::gpu_only] #[inline] pub unsafe fn workgroup_memory_barrier_with_group_sync() { - control_barrier::< - { crate::memory::Scope::Workgroup as u32 }, - { crate::memory::Scope::Workgroup as u32 }, - { - crate::memory::Semantics::WORKGROUP_MEMORY.bits() - | crate::memory::Semantics::ACQUIRE_RELEASE.bits() - }, - >(); + unsafe { + control_barrier::< + { crate::memory::Scope::Workgroup as u32 }, + { crate::memory::Scope::Workgroup as u32 }, + { + crate::memory::Semantics::WORKGROUP_MEMORY.bits() + | crate::memory::Semantics::ACQUIRE_RELEASE.bits() + }, + >(); + } } /// Blocks execution of all threads in a group until all device memory accesses have been completed. @@ -125,14 +133,16 @@ pub unsafe fn workgroup_memory_barrier_with_group_sync() { #[spirv_std_macros::gpu_only] #[inline] pub unsafe fn device_memory_barrier() { - memory_barrier::< - { crate::memory::Scope::Device as u32 }, - { - crate::memory::Semantics::IMAGE_MEMORY.bits() - | crate::memory::Semantics::UNIFORM_MEMORY.bits() - | crate::memory::Semantics::ACQUIRE_RELEASE.bits() - }, - >(); + unsafe { + memory_barrier::< + { crate::memory::Scope::Device as u32 }, + { + crate::memory::Semantics::IMAGE_MEMORY.bits() + | crate::memory::Semantics::UNIFORM_MEMORY.bits() + | crate::memory::Semantics::ACQUIRE_RELEASE.bits() + }, + >(); + } } /// Blocks execution of all threads in a group until all device memory accesses have been completed and all threads in the group have reached this call. @@ -143,15 +153,17 @@ pub unsafe fn device_memory_barrier() { #[spirv_std_macros::gpu_only] #[inline] pub unsafe fn device_memory_barrier_with_group_sync() { - control_barrier::< - { crate::memory::Scope::Workgroup as u32 }, - { crate::memory::Scope::Device as u32 }, - { - crate::memory::Semantics::IMAGE_MEMORY.bits() - | crate::memory::Semantics::UNIFORM_MEMORY.bits() - | crate::memory::Semantics::ACQUIRE_RELEASE.bits() - }, - >(); + unsafe { + control_barrier::< + { crate::memory::Scope::Workgroup as u32 }, + { crate::memory::Scope::Device as u32 }, + { + crate::memory::Semantics::IMAGE_MEMORY.bits() + | crate::memory::Semantics::UNIFORM_MEMORY.bits() + | crate::memory::Semantics::ACQUIRE_RELEASE.bits() + }, + >(); + } } /// Blocks execution of all threads in a group until all memory accesses have been completed. @@ -162,15 +174,17 @@ pub unsafe fn device_memory_barrier_with_group_sync() { #[spirv_std_macros::gpu_only] #[inline] pub unsafe fn all_memory_barrier() { - memory_barrier::< - { crate::memory::Scope::Device as u32 }, - { - crate::memory::Semantics::WORKGROUP_MEMORY.bits() - | crate::memory::Semantics::IMAGE_MEMORY.bits() - | crate::memory::Semantics::UNIFORM_MEMORY.bits() - | crate::memory::Semantics::ACQUIRE_RELEASE.bits() - }, - >(); + unsafe { + memory_barrier::< + { crate::memory::Scope::Device as u32 }, + { + crate::memory::Semantics::WORKGROUP_MEMORY.bits() + | crate::memory::Semantics::IMAGE_MEMORY.bits() + | crate::memory::Semantics::UNIFORM_MEMORY.bits() + | crate::memory::Semantics::ACQUIRE_RELEASE.bits() + }, + >(); + } } /// Blocks execution of all threads in a group until all memory accesses have been completed and all threads in the group have reached this call. @@ -181,14 +195,16 @@ pub unsafe fn all_memory_barrier() { #[spirv_std_macros::gpu_only] #[inline] pub unsafe fn all_memory_barrier_with_group_sync() { - control_barrier::< - { crate::memory::Scope::Workgroup as u32 }, - { crate::memory::Scope::Device as u32 }, - { - crate::memory::Semantics::WORKGROUP_MEMORY.bits() - | crate::memory::Semantics::IMAGE_MEMORY.bits() - | crate::memory::Semantics::UNIFORM_MEMORY.bits() - | crate::memory::Semantics::ACQUIRE_RELEASE.bits() - }, - >(); + unsafe { + control_barrier::< + { crate::memory::Scope::Workgroup as u32 }, + { crate::memory::Scope::Device as u32 }, + { + crate::memory::Semantics::WORKGROUP_MEMORY.bits() + | crate::memory::Semantics::IMAGE_MEMORY.bits() + | crate::memory::Semantics::UNIFORM_MEMORY.bits() + | crate::memory::Semantics::ACQUIRE_RELEASE.bits() + }, + >(); + } } diff --git a/crates/spirv-std/src/arch/demote_to_helper_invocation_ext.rs b/crates/spirv-std/src/arch/demote_to_helper_invocation_ext.rs index 3ac57894c8..2388fbcee9 100644 --- a/crates/spirv-std/src/arch/demote_to_helper_invocation_ext.rs +++ b/crates/spirv-std/src/arch/demote_to_helper_invocation_ext.rs @@ -20,7 +20,9 @@ use core::arch::asm; #[spirv_std_macros::gpu_only] #[doc(alias = "OpDemoteToHelperInvocationEXT", alias = "discard")] pub unsafe fn demote_to_helper_invocation() { - asm!("OpDemoteToHelperInvocationEXT"); + unsafe { + asm!("OpDemoteToHelperInvocationEXT"); + } } /// Returns `true` if the invocation is currently a helper invocation, otherwise diff --git a/crates/spirv-std/src/arch/mesh_shading.rs b/crates/spirv-std/src/arch/mesh_shading.rs index e3806ee86d..cc906a17cf 100644 --- a/crates/spirv-std/src/arch/mesh_shading.rs +++ b/crates/spirv-std/src/arch/mesh_shading.rs @@ -21,10 +21,12 @@ use core::arch::asm; #[doc(alias = "OpSetMeshOutputsEXT")] #[inline] pub unsafe fn set_mesh_outputs_ext(vertex_count: u32, primitive_count: u32) { - asm! { - "OpSetMeshOutputsEXT {vertex_count} {primitive_count}", - vertex_count = in(reg) vertex_count, - primitive_count = in(reg) primitive_count, + unsafe { + asm! { + "OpSetMeshOutputsEXT {vertex_count} {primitive_count}", + vertex_count = in(reg) vertex_count, + primitive_count = in(reg) primitive_count, + } } } @@ -56,12 +58,14 @@ pub unsafe fn set_mesh_outputs_ext(vertex_count: u32, primitive_count: u32) { #[doc(alias = "OpEmitMeshTasksEXT")] #[inline] pub unsafe fn emit_mesh_tasks_ext(group_count_x: u32, group_count_y: u32, group_count_z: u32) -> ! { - asm! { - "OpEmitMeshTasksEXT {group_count_x} {group_count_y} {group_count_z}", - group_count_x = in(reg) group_count_x, - group_count_y = in(reg) group_count_y, - group_count_z = in(reg) group_count_z, - options(noreturn), + unsafe { + asm! { + "OpEmitMeshTasksEXT {group_count_x} {group_count_y} {group_count_z}", + group_count_x = in(reg) group_count_x, + group_count_y = in(reg) group_count_y, + group_count_z = in(reg) group_count_z, + options(noreturn), + } } } @@ -98,12 +102,14 @@ pub unsafe fn emit_mesh_tasks_ext_payload( group_count_z: u32, payload: &mut T, ) -> ! { - asm! { - "OpEmitMeshTasksEXT {group_count_x} {group_count_y} {group_count_z} {payload}", - group_count_x = in(reg) group_count_x, - group_count_y = in(reg) group_count_y, - group_count_z = in(reg) group_count_z, - payload = in(reg) payload, - options(noreturn), + unsafe { + asm! { + "OpEmitMeshTasksEXT {group_count_x} {group_count_y} {group_count_z} {payload}", + group_count_x = in(reg) group_count_x, + group_count_y = in(reg) group_count_y, + group_count_z = in(reg) group_count_z, + payload = in(reg) payload, + options(noreturn), + } } } diff --git a/crates/spirv-std/src/arch/primitive.rs b/crates/spirv-std/src/arch/primitive.rs index 70c592192f..5953c99426 100644 --- a/crates/spirv-std/src/arch/primitive.rs +++ b/crates/spirv-std/src/arch/primitive.rs @@ -11,8 +11,10 @@ use core::arch::asm; #[doc(alias = "OpEmitVertex")] #[inline] pub unsafe fn emit_vertex() { - asm! { - "OpEmitVertex", + unsafe { + asm! { + "OpEmitVertex", + } } } @@ -25,8 +27,10 @@ pub unsafe fn emit_vertex() { #[doc(alias = "OpEndPrimitive")] #[inline] pub unsafe fn end_primitive() { - asm! { - "OpEndPrimitive", + unsafe { + asm! { + "OpEndPrimitive", + } } } @@ -44,11 +48,13 @@ pub unsafe fn end_primitive() { #[doc(alias = "OpEmitStreamVertex")] #[inline] pub unsafe fn emit_stream_vertex() { - asm! { - "%i64 = OpTypeInt 64 1", - "%stream = OpConstant %i64 {stream}", - "OpEmitStreamVertex %stream", - stream = const STREAM, + unsafe { + asm! { + "%i64 = OpTypeInt 64 1", + "%stream = OpConstant %i64 {stream}", + "OpEmitStreamVertex %stream", + stream = const STREAM, + } } } @@ -64,10 +70,12 @@ pub unsafe fn emit_stream_vertex() { #[doc(alias = "OpEndStreamPrimitive")] #[inline] pub unsafe fn end_stream_primitive() { - asm! { - "%i64 = OpTypeInt 64 1", - "%stream = OpConstant %i64 {stream}", - "OpEndStreamPrimitive %stream", - stream = const STREAM, + unsafe { + asm! { + "%i64 = OpTypeInt 64 1", + "%stream = OpConstant %i64 {stream}", + "OpEndStreamPrimitive %stream", + stream = const STREAM, + } } } diff --git a/crates/spirv-std/src/arch/ray_tracing.rs b/crates/spirv-std/src/arch/ray_tracing.rs index 04adaa4bf1..7612ffb3d3 100644 --- a/crates/spirv-std/src/arch/ray_tracing.rs +++ b/crates/spirv-std/src/arch/ray_tracing.rs @@ -22,18 +22,20 @@ use core::arch::asm; #[doc(alias = "OpReportIntersectionKHR")] #[inline] pub unsafe fn report_intersection(hit: f32, hit_kind: u32) -> bool { - let mut result = false; + unsafe { + let mut result = false; - asm! { - "%bool = OpTypeBool", - "%result = OpReportIntersectionKHR %bool {hit} {hit_kind}", - "OpStore {result} %result", - result = in(reg) &mut result, - hit = in(reg) hit, - hit_kind = in(reg) hit_kind, - }; + asm! { + "%bool = OpTypeBool", + "%result = OpReportIntersectionKHR %bool {hit} {hit_kind}", + "OpStore {result} %result", + result = in(reg) &mut result, + hit = in(reg) hit, + hit_kind = in(reg) hit_kind, + }; - result + result + } } /// Ignores the current potential intersection, terminating the invocation that @@ -43,7 +45,9 @@ pub unsafe fn report_intersection(hit: f32, hit_kind: u32) -> bool { #[doc(alias = "OpIgnoreIntersectionKHR")] #[inline] pub unsafe fn ignore_intersection() -> ! { - asm!("OpIgnoreIntersectionKHR", options(noreturn)); + unsafe { + asm!("OpIgnoreIntersectionKHR", options(noreturn)); + } } /// Terminates the invocation that executes it, stops the ray traversal, accepts @@ -54,7 +58,9 @@ pub unsafe fn ignore_intersection() -> ! { #[doc(alias = "OpTerminateRayKHR")] #[inline] pub unsafe fn terminate_ray() -> ! { - asm!("OpTerminateRayKHR", options(noreturn)); + unsafe { + asm!("OpTerminateRayKHR", options(noreturn)); + } } /// Invoke a callable shader. @@ -74,11 +80,13 @@ pub unsafe fn terminate_ray() -> ! { #[doc(alias = "OpExecuteCallableKHR")] #[inline] pub unsafe fn execute_callable(data: &T) { - asm! { - "%u32 = OpTypeInt 32 0", - "%id = OpConstant %u32 {id}", - "OpExecuteCallableKHR %id {data}", - id = const ID, - data = in(reg) data, - }; + unsafe { + asm! { + "%u32 = OpTypeInt 32 0", + "%id = OpConstant %u32 {id}", + "OpExecuteCallableKHR %id {data}", + id = const ID, + data = in(reg) data, + }; + } } diff --git a/crates/spirv-std/src/byte_addressable_buffer.rs b/crates/spirv-std/src/byte_addressable_buffer.rs index f4c6dba491..4a1949c713 100644 --- a/crates/spirv-std/src/byte_addressable_buffer.rs +++ b/crates/spirv-std/src/byte_addressable_buffer.rs @@ -11,15 +11,17 @@ unsafe fn buffer_load_intrinsic( // FIXME(eddyb) should be `usize`. offset: u32, ) -> T { - // NOTE(eddyb) this doesn't work with `rustc_codegen_spirv` and is only here - // for explanatory purposes, and to cause some kind of verbose error if - // `#[spirv(buffer_load_intrinsic)]` fails to replace calls to this function. - buffer - .as_ptr() - .cast::() - .add(offset as usize) - .cast::() - .read() + unsafe { + // NOTE(eddyb) this doesn't work with `rustc_codegen_spirv` and is only here + // for explanatory purposes, and to cause some kind of verbose error if + // `#[spirv(buffer_load_intrinsic)]` fails to replace calls to this function. + buffer + .as_ptr() + .cast::() + .add(offset as usize) + .cast::() + .read() + } } #[spirv(buffer_store_intrinsic)] @@ -32,15 +34,17 @@ unsafe fn buffer_store_intrinsic( offset: u32, value: T, ) { - // NOTE(eddyb) this doesn't work with `rustc_codegen_spirv` and is only here - // for explanatory purposes, and to cause some kind of verbose error if - // `#[spirv(buffer_store_intrinsic)]` fails to replace calls to this function. - buffer - .as_mut_ptr() - .cast::() - .add(offset as usize) - .cast::() - .write(value); + unsafe { + // NOTE(eddyb) this doesn't work with `rustc_codegen_spirv` and is only here + // for explanatory purposes, and to cause some kind of verbose error if + // `#[spirv(buffer_store_intrinsic)]` fails to replace calls to this function. + buffer + .as_mut_ptr() + .cast::() + .add(offset as usize) + .cast::() + .write(value); + } } /// `ByteAddressableBuffer` is a view to an untyped blob of data, allowing @@ -94,7 +98,7 @@ impl<'a> ByteAddressableBuffer<&'a [u32]> { /// See [`Self`]. pub unsafe fn load(&self, byte_index: u32) -> T { bounds_check::(self.data, byte_index); - buffer_load_intrinsic(self.data, byte_index) + unsafe { buffer_load_intrinsic(self.data, byte_index) } } /// Loads an arbitrary type from the buffer. `byte_index` must be a @@ -103,7 +107,7 @@ impl<'a> ByteAddressableBuffer<&'a [u32]> { /// # Safety /// See [`Self`]. Additionally, bounds or alignment checking is not performed. pub unsafe fn load_unchecked(&self, byte_index: u32) -> T { - buffer_load_intrinsic(self.data, byte_index) + unsafe { buffer_load_intrinsic(self.data, byte_index) } } } @@ -127,7 +131,7 @@ impl<'a> ByteAddressableBuffer<&'a mut [u32]> { /// See [`Self`]. #[inline] pub unsafe fn load(&self, byte_index: u32) -> T { - self.as_ref().load(byte_index) + unsafe { self.as_ref().load(byte_index) } } /// Loads an arbitrary type from the buffer. `byte_index` must be a @@ -137,7 +141,7 @@ impl<'a> ByteAddressableBuffer<&'a mut [u32]> { /// See [`Self`]. Additionally, bounds or alignment checking is not performed. #[inline] pub unsafe fn load_unchecked(&self, byte_index: u32) -> T { - self.as_ref().load_unchecked(byte_index) + unsafe { self.as_ref().load_unchecked(byte_index) } } /// Stores an arbitrary type into the buffer. `byte_index` must be a @@ -147,7 +151,9 @@ impl<'a> ByteAddressableBuffer<&'a mut [u32]> { /// See [`Self`]. pub unsafe fn store(&mut self, byte_index: u32, value: T) { bounds_check::(self.data, byte_index); - buffer_store_intrinsic(self.data, byte_index, value); + unsafe { + buffer_store_intrinsic(self.data, byte_index, value); + } } /// Stores an arbitrary type into the buffer. `byte_index` must be a @@ -156,6 +162,8 @@ impl<'a> ByteAddressableBuffer<&'a mut [u32]> { /// # Safety /// See [`Self`]. Additionally, bounds or alignment checking is not performed. pub unsafe fn store_unchecked(&mut self, byte_index: u32, value: T) { - buffer_store_intrinsic(self.data, byte_index, value); + unsafe { + buffer_store_intrinsic(self.data, byte_index, value); + } } } diff --git a/crates/spirv-std/src/ray_tracing.rs b/crates/spirv-std/src/ray_tracing.rs index f24de07bab..c35846eeac 100644 --- a/crates/spirv-std/src/ray_tracing.rs +++ b/crates/spirv-std/src/ray_tracing.rs @@ -27,16 +27,18 @@ impl AccelerationStructure { #[doc(alias = "OpConvertUToAccelerationStructureKHR")] #[inline] pub unsafe fn from_u64(id: u64) -> AccelerationStructure { - // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. - let mut result_slot = core::mem::MaybeUninit::uninit(); - asm! { - "%ret = OpTypeAccelerationStructureKHR", - "%result = OpConvertUToAccelerationStructureKHR %ret {id}", - "OpStore {result_slot} %result", - id = in(reg) id, - result_slot = in(reg) result_slot.as_mut_ptr(), + unsafe { + // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. + let mut result_slot = core::mem::MaybeUninit::uninit(); + asm! { + "%ret = OpTypeAccelerationStructureKHR", + "%result = OpConvertUToAccelerationStructureKHR %ret {id}", + "OpStore {result_slot} %result", + id = in(reg) id, + result_slot = in(reg) result_slot.as_mut_ptr(), + } + result_slot.assume_init() } - result_slot.assume_init() } /// Converts a vector of two 32 bit integers into an [`AccelerationStructure`]. @@ -46,17 +48,19 @@ impl AccelerationStructure { #[doc(alias = "OpConvertUToAccelerationStructureKHR")] #[inline] pub unsafe fn from_vec(id: impl Vector) -> AccelerationStructure { - // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. - let mut result_slot = core::mem::MaybeUninit::uninit(); - asm! { - "%ret = OpTypeAccelerationStructureKHR", - "%id = OpLoad _ {id}", - "%result = OpConvertUToAccelerationStructureKHR %ret %id", - "OpStore {result_slot} %result", - id = in(reg) &id, - result_slot = in(reg) result_slot.as_mut_ptr(), + unsafe { + // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. + let mut result_slot = core::mem::MaybeUninit::uninit(); + asm! { + "%ret = OpTypeAccelerationStructureKHR", + "%id = OpLoad _ {id}", + "%result = OpConvertUToAccelerationStructureKHR %ret %id", + "OpStore {result_slot} %result", + id = in(reg) &id, + result_slot = in(reg) result_slot.as_mut_ptr(), + } + result_slot.assume_init() } - result_slot.assume_init() } #[spirv_std_macros::gpu_only] @@ -103,33 +107,35 @@ impl AccelerationStructure { ray_tmax: f32, payload: &mut T, ) { - asm! { - "%acceleration_structure = OpLoad _ {acceleration_structure}", - "%ray_origin = OpLoad _ {ray_origin}", - "%ray_direction = OpLoad _ {ray_direction}", - "OpTraceRayKHR \ - %acceleration_structure \ - {ray_flags} \ - {cull_mask} \ - {sbt_offset} \ - {sbt_stride} \ - {miss_index} \ - %ray_origin \ - {ray_tmin} \ - %ray_direction \ - {ray_tmax} \ - {payload}", - acceleration_structure = in(reg) self, - ray_flags = in(reg) ray_flags.bits(), - cull_mask = in(reg) cull_mask, - sbt_offset = in(reg) sbt_offset, - sbt_stride = in(reg) sbt_stride, - miss_index = in(reg) miss_index, - ray_origin = in(reg) &ray_origin, - ray_tmin = in(reg) ray_tmin, - ray_direction = in(reg) &ray_direction, - ray_tmax = in(reg) ray_tmax, - payload = in(reg) payload, + unsafe { + asm! { + "%acceleration_structure = OpLoad _ {acceleration_structure}", + "%ray_origin = OpLoad _ {ray_origin}", + "%ray_direction = OpLoad _ {ray_direction}", + "OpTraceRayKHR \ + %acceleration_structure \ + {ray_flags} \ + {cull_mask} \ + {sbt_offset} \ + {sbt_stride} \ + {miss_index} \ + %ray_origin \ + {ray_tmin} \ + %ray_direction \ + {ray_tmax} \ + {payload}", + acceleration_structure = in(reg) self, + ray_flags = in(reg) ray_flags.bits(), + cull_mask = in(reg) cull_mask, + sbt_offset = in(reg) sbt_offset, + sbt_stride = in(reg) sbt_stride, + miss_index = in(reg) miss_index, + ray_origin = in(reg) &ray_origin, + ray_tmin = in(reg) ray_tmin, + ray_direction = in(reg) &ray_direction, + ray_tmax = in(reg) ray_tmax, + payload = in(reg) payload, + } } } } @@ -259,27 +265,29 @@ impl RayQuery { ray_direction: impl Vector, ray_tmax: f32, ) { - asm! { - "%acceleration_structure = OpLoad _ {acceleration_structure}", - "%origin = OpLoad _ {ray_origin}", - "%direction = OpLoad _ {ray_direction}", - "OpRayQueryInitializeKHR \ - {ray_query} \ - %acceleration_structure \ - {ray_flags} \ - {cull_mask} \ - %origin \ - {ray_tmin} \ - %direction \ - {ray_tmax}", - ray_query = in(reg) self, - acceleration_structure = in(reg) acceleration_structure, - ray_flags = in(reg) ray_flags.bits(), - cull_mask = in(reg) cull_mask, - ray_origin = in(reg) &ray_origin, - ray_tmin = in(reg) ray_tmin, - ray_direction = in(reg) &ray_direction, - ray_tmax = in(reg) ray_tmax, + unsafe { + asm! { + "%acceleration_structure = OpLoad _ {acceleration_structure}", + "%origin = OpLoad _ {ray_origin}", + "%direction = OpLoad _ {ray_direction}", + "OpRayQueryInitializeKHR \ + {ray_query} \ + %acceleration_structure \ + {ray_flags} \ + {cull_mask} \ + %origin \ + {ray_tmin} \ + %direction \ + {ray_tmax}", + ray_query = in(reg) self, + acceleration_structure = in(reg) acceleration_structure, + ray_flags = in(reg) ray_flags.bits(), + cull_mask = in(reg) cull_mask, + ray_origin = in(reg) &ray_origin, + ray_tmin = in(reg) ray_tmin, + ray_direction = in(reg) &ray_direction, + ray_tmax = in(reg) ray_tmax, + } } } @@ -290,17 +298,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryProceedKHR")] #[inline] pub unsafe fn proceed(&self) -> bool { - let mut result = false; + unsafe { + let mut result = false; + + asm! { + "%bool = OpTypeBool", + "%result = OpRayQueryProceedKHR %bool {ray_query}", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%bool = OpTypeBool", - "%result = OpRayQueryProceedKHR %bool {ray_query}", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Terminates further execution of a ray query; further calls to @@ -311,7 +321,7 @@ impl RayQuery { #[doc(alias = "OpRayQueryTerminateKHR")] #[inline] pub unsafe fn terminate(&self) { - asm!("OpRayQueryTerminateKHR {}", in(reg) self) + unsafe { asm!("OpRayQueryTerminateKHR {}", in(reg) self) } } /// Confirms a triangle intersection to be included in the determination @@ -325,7 +335,7 @@ impl RayQuery { #[doc(alias = "OpRayQueryConfirmIntersectionKHR")] #[inline] pub unsafe fn confirm_intersection(&self) { - asm!("OpRayQueryConfirmIntersectionKHR {}", in(reg) self) + unsafe { asm!("OpRayQueryConfirmIntersectionKHR {}", in(reg) self) } } /// Returns the type of the current candidate intersection. @@ -335,20 +345,22 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionTypeKHR")] #[inline] pub unsafe fn get_candidate_intersection_type(&self) -> CandidateIntersection { - let result: u32; - - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 0", - "{result} = OpRayQueryGetIntersectionTypeKHR %u32 {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, - } + unsafe { + let result: u32; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 0", + "{result} = OpRayQueryGetIntersectionTypeKHR %u32 {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - match result { - 0 => CandidateIntersection::Triangle, - 1 => CandidateIntersection::AABB, - _ => CandidateIntersection::Triangle, + match result { + 0 => CandidateIntersection::Triangle, + 1 => CandidateIntersection::AABB, + _ => CandidateIntersection::Triangle, + } } } @@ -357,21 +369,23 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionTypeKHR")] #[inline] pub unsafe fn get_committed_intersection_type(&self) -> CommittedIntersection { - let result: u32; - - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 1", - "{result} = OpRayQueryGetIntersectionTypeKHR %u32 {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, - } + unsafe { + let result: u32; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 1", + "{result} = OpRayQueryGetIntersectionTypeKHR %u32 {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - match result { - 0 => CommittedIntersection::None, - 1 => CommittedIntersection::Triangle, - 2 => CommittedIntersection::Generated, - _ => CommittedIntersection::None, + match result { + 0 => CommittedIntersection::None, + 1 => CommittedIntersection::Triangle, + 2 => CommittedIntersection::Generated, + _ => CommittedIntersection::None, + } } } @@ -380,16 +394,18 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetRayTMinKHR")] #[inline] pub unsafe fn get_ray_t_min(&self) -> f32 { - let result; + unsafe { + let result; + + asm! { + "%f32 = OpTypeFloat 32", + "{result} = OpRayQueryGetRayTMinKHR %f32 {ray_query}", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%f32 = OpTypeFloat 32", - "{result} = OpRayQueryGetRayTMinKHR %f32 {ray_query}", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Returns the "Ray Flags" value used by the ray query. @@ -397,15 +413,17 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetRayFlagsKHR")] #[inline] pub unsafe fn get_ray_flags(&self) -> RayFlags { - let result; + unsafe { + let result; - asm! { - "{result} = OpRayQueryGetRayFlagsKHR typeof{result} {ray_query}", - ray_query = in(reg) self, - result = out(reg) result, - } + asm! { + "{result} = OpRayQueryGetRayFlagsKHR typeof{result} {ray_query}", + ray_query = in(reg) self, + result = out(reg) result, + } - RayFlags::from_bits_truncate(result) + RayFlags::from_bits_truncate(result) + } } /// Gets the "T" value for the current or previous intersection considered @@ -418,17 +436,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionTKHR")] #[inline] pub unsafe fn get_candidate_intersection_t(&self) -> f32 { - let result; + unsafe { + let result; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 0", + "{result} = OpRayQueryGetIntersectionTKHR typeof{result} {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 0", - "{result} = OpRayQueryGetIntersectionTKHR typeof{result} {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Gets the "T" value for the current or previous intersection considered @@ -442,17 +462,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionTKHR")] #[inline] pub unsafe fn get_committed_intersection_t(&self) -> f32 { - let result; + unsafe { + let result; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 1", + "{result} = OpRayQueryGetIntersectionTKHR typeof{result} {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 1", - "{result} = OpRayQueryGetIntersectionTKHR typeof{result} {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Gets the custom index of the instance for the current intersection @@ -463,17 +485,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionInstanceCustomIndexKHR")] #[inline] pub unsafe fn get_candidate_intersection_instance_custom_index(&self) -> u32 { - let result; + unsafe { + let result; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 0", + "{result} = OpRayQueryGetIntersectionInstanceCustomIndexKHR %u32 {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 0", - "{result} = OpRayQueryGetIntersectionInstanceCustomIndexKHR %u32 {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Gets the custom index of the instance for the current intersection @@ -487,17 +511,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionInstanceCustomIndexKHR")] #[inline] pub unsafe fn get_committed_intersection_instance_custom_index(&self) -> u32 { - let result; + unsafe { + let result; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 1", + "{result} = OpRayQueryGetIntersectionInstanceCustomIndexKHR %u32 {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 1", - "{result} = OpRayQueryGetIntersectionInstanceCustomIndexKHR %u32 {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Gets the id of the instance for the current intersection considered in a @@ -508,17 +534,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionInstanceIdKHR")] #[inline] pub unsafe fn get_candidate_intersection_instance_id(&self) -> u32 { - let result; + unsafe { + let result; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 0", + "{result} = OpRayQueryGetIntersectionInstanceIdKHR %u32 {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 0", - "{result} = OpRayQueryGetIntersectionInstanceIdKHR %u32 {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Gets the id of the instance for the current intersection considered in a @@ -532,17 +560,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionInstanceIdKHR")] #[inline] pub unsafe fn get_committed_intersection_instance_id(&self) -> u32 { - let result; + unsafe { + let result; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 1", + "{result} = OpRayQueryGetIntersectionInstanceIdKHR %u32 {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 1", - "{result} = OpRayQueryGetIntersectionInstanceIdKHR %u32 {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Gets the shader binding table record offset for the current intersection @@ -553,17 +583,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR")] #[inline] pub unsafe fn get_candidate_intersection_shader_binding_table_record_offset(&self) -> u32 { - let result; + unsafe { + let result; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 0", + "{result} = OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR %u32 {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 0", - "{result} = OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR %u32 {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Gets the shader binding table record offset for the current intersection @@ -577,17 +609,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR")] #[inline] pub unsafe fn get_committed_intersection_shader_binding_table_record_offset(&self) -> u32 { - let result; + unsafe { + let result; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 1", + "{result} = OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR %u32 {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 1", - "{result} = OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR %u32 {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Gets the geometry index for the current intersection considered in a @@ -598,17 +632,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionGeometryIndexKHR")] #[inline] pub unsafe fn get_candidate_intersection_geometry_index(&self) -> u32 { - let result; + unsafe { + let result; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 0", + "{result} = OpRayQueryGetIntersectionGeometryIndexKHR %u32 {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 0", - "{result} = OpRayQueryGetIntersectionGeometryIndexKHR %u32 {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Gets the geometry index for the current intersection considered in a @@ -622,17 +658,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionGeometryIndexKHR")] #[inline] pub unsafe fn get_committed_intersection_geometry_index(&self) -> u32 { - let result; + unsafe { + let result; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 1", + "{result} = OpRayQueryGetIntersectionGeometryIndexKHR %u32 {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 1", - "{result} = OpRayQueryGetIntersectionGeometryIndexKHR %u32 {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Gets the primitive index for the current intersection considered in a @@ -643,17 +681,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionPrimitiveIndexKHR")] #[inline] pub unsafe fn get_candidate_intersection_primitive_index(&self) -> u32 { - let result; + unsafe { + let result; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 0", + "{result} = OpRayQueryGetIntersectionPrimitiveIndexKHR %u32 {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 0", - "{result} = OpRayQueryGetIntersectionPrimitiveIndexKHR %u32 {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Gets the primitive index for the current intersection considered in a @@ -667,17 +707,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionPrimitiveIndexKHR")] #[inline] pub unsafe fn get_committed_intersection_primitive_index(&self) -> u32 { - let result; + unsafe { + let result; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 1", + "{result} = OpRayQueryGetIntersectionPrimitiveIndexKHR %u32 {ray_query} %intersection", + ray_query = in(reg) self, + result = out(reg) result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 1", - "{result} = OpRayQueryGetIntersectionPrimitiveIndexKHR %u32 {ray_query} %intersection", - ray_query = in(reg) self, - result = out(reg) result, + result } - - result } /// Gets the second and third barycentric coordinates of the current @@ -690,18 +732,20 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionBarycentricsKHR")] #[inline] pub unsafe fn get_candidate_intersection_barycentrics>(&self) -> V { - let mut result = Default::default(); + unsafe { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 0", + "%result = OpRayQueryGetIntersectionBarycentricsKHR typeof*{result} {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 0", - "%result = OpRayQueryGetIntersectionBarycentricsKHR typeof*{result} {ray_query} %intersection", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Gets the second and third barycentric coordinates of the current @@ -716,18 +760,20 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionBarycentricsKHR")] #[inline] pub unsafe fn get_committed_intersection_barycentrics>(&self) -> V { - let mut result = Default::default(); + unsafe { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 1", + "%result = OpRayQueryGetIntersectionBarycentricsKHR typeof*{result} {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 1", - "%result = OpRayQueryGetIntersectionBarycentricsKHR typeof*{result} {ray_query} %intersection", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Returns whether the current intersection considered in a ray query was with @@ -740,19 +786,21 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionFrontFaceKHR")] #[inline] pub unsafe fn get_candidate_intersection_front_face(&self) -> bool { - let mut result = false; + unsafe { + let mut result = false; + + asm! { + "%bool = OpTypeBool", + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 0", + "%result = OpRayQueryGetIntersectionFrontFaceKHR %bool {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%bool = OpTypeBool", - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 0", - "%result = OpRayQueryGetIntersectionFrontFaceKHR %bool {ray_query} %intersection", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Returns whether the current intersection considered in a ray query was with @@ -767,19 +815,21 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionFrontFaceKHR")] #[inline] pub unsafe fn get_committed_intersection_front_face(&self) -> bool { - let mut result = false; + unsafe { + let mut result = false; + + asm! { + "%bool = OpTypeBool", + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 1", + "%result = OpRayQueryGetIntersectionFrontFaceKHR %bool {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%bool = OpTypeBool", - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 1", - "%result = OpRayQueryGetIntersectionFrontFaceKHR %bool {ray_query} %intersection", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Returns whether a candidate intersection considered in a ray query was with @@ -788,17 +838,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR")] #[inline] pub unsafe fn get_intersection_candidate_aabb_opaque(&self) -> bool { - let mut result = false; + unsafe { + let mut result = false; + + asm! { + "%bool = OpTypeBool", + "%result = OpRayQueryGetIntersectionCandidateAABBOpaqueKHR %bool {ray_query}", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%bool = OpTypeBool", - "%result = OpRayQueryGetIntersectionCandidateAABBOpaqueKHR %bool {ray_query}", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Gets the object-space ray direction for the current intersection considered @@ -809,18 +861,20 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionObjectRayDirectionKHR")] #[inline] pub unsafe fn get_candidate_intersection_object_ray_direction>(&self) -> V { - let mut result = Default::default(); + unsafe { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 0", + "%result = OpRayQueryGetIntersectionObjectRayDirectionKHR typeof*{result} {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 0", - "%result = OpRayQueryGetIntersectionObjectRayDirectionKHR typeof*{result} {ray_query} %intersection", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Gets the object-space ray direction for the current intersection considered @@ -834,18 +888,20 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionObjectRayDirectionKHR")] #[inline] pub unsafe fn get_committed_intersection_object_ray_direction>(&self) -> V { - let mut result = Default::default(); + unsafe { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 1", + "%result = OpRayQueryGetIntersectionObjectRayDirectionKHR typeof*{result} {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 1", - "%result = OpRayQueryGetIntersectionObjectRayDirectionKHR typeof*{result} {ray_query} %intersection", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Gets the object-space ray origin for the current intersection considered in @@ -856,18 +912,20 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionObjectRayOriginKHR")] #[inline] pub unsafe fn get_candidate_intersection_object_ray_origin>(&self) -> V { - let mut result = Default::default(); + unsafe { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 0", + "%result = OpRayQueryGetIntersectionObjectRayOriginKHR typeof*{result} {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 0", - "%result = OpRayQueryGetIntersectionObjectRayOriginKHR typeof*{result} {ray_query} %intersection", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Gets the object-space ray origin for the current intersection considered in @@ -881,18 +939,20 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionObjectRayOriginKHR")] #[inline] pub unsafe fn get_committed_intersection_object_ray_origin>(&self) -> V { - let mut result = Default::default(); + unsafe { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 1", + "%result = OpRayQueryGetIntersectionObjectRayOriginKHR typeof*{result} {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%intersection = OpConstant %u32 1", - "%result = OpRayQueryGetIntersectionObjectRayOriginKHR typeof*{result} {ray_query} %intersection", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Gets the world-space direction for the ray traced in a ray query. @@ -900,17 +960,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetWorldRayDirectionKHR")] #[inline] pub unsafe fn get_world_ray_direction>(&self) -> V { - let mut result = Default::default(); + unsafe { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%result = OpRayQueryGetWorldRayDirectionKHR typeof*{result} {ray_query}", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%result = OpRayQueryGetWorldRayDirectionKHR typeof*{result} {ray_query}", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Gets the world-space origin for the ray traced in a ray query. @@ -918,17 +980,19 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetWorldRayOriginKHR")] #[inline] pub unsafe fn get_world_ray_origin>(&self) -> V { - let mut result = Default::default(); + unsafe { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%result = OpRayQueryGetWorldRayOriginKHR typeof*{result} {ray_query}", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%result = OpRayQueryGetWorldRayOriginKHR typeof*{result} {ray_query}", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Gets a matrix that transforms values to world-space from the object-space of @@ -939,26 +1003,28 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionObjectToWorldKHR")] #[inline] pub unsafe fn get_candidate_intersection_object_to_world>(&self) -> [V; 4] { - let mut result = Default::default(); + unsafe { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%f32 = OpTypeFloat 32", + "%f32x3 = OpTypeVector %f32 3", + "%f32x3x4 = OpTypeMatrix %f32x3 4", + "%intersection = OpConstant %u32 0", + "%matrix = OpRayQueryGetIntersectionObjectToWorldKHR %f32x3x4 {ray_query} %intersection", + "%col0 = OpCompositeExtract %f32x3 %matrix 0", + "%col1 = OpCompositeExtract %f32x3 %matrix 1", + "%col2 = OpCompositeExtract %f32x3 %matrix 2", + "%col3 = OpCompositeExtract %f32x3 %matrix 3", + "%result = OpCompositeConstruct typeof*{result} %col0 %col1 %col2 %col3", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } - asm! { - "%u32 = OpTypeInt 32 0", - "%f32 = OpTypeFloat 32", - "%f32x3 = OpTypeVector %f32 3", - "%f32x3x4 = OpTypeMatrix %f32x3 4", - "%intersection = OpConstant %u32 0", - "%matrix = OpRayQueryGetIntersectionObjectToWorldKHR %f32x3x4 {ray_query} %intersection", - "%col0 = OpCompositeExtract %f32x3 %matrix 0", - "%col1 = OpCompositeExtract %f32x3 %matrix 1", - "%col2 = OpCompositeExtract %f32x3 %matrix 2", - "%col3 = OpCompositeExtract %f32x3 %matrix 3", - "%result = OpCompositeConstruct typeof*{result} %col0 %col1 %col2 %col3", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, + result } - - result } /// Gets a matrix that transforms values to world-space from the object-space of @@ -972,25 +1038,27 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionObjectToWorldKHR")] #[inline] pub unsafe fn get_committed_intersection_object_to_world>(&self) -> [V; 4] { - let mut result = Default::default(); - - asm! { - "%u32 = OpTypeInt 32 0", - "%f32 = OpTypeFloat 32", - "%f32x3 = OpTypeVector %f32 3", - "%f32x3x4 = OpTypeMatrix %f32x3 4", - "%intersection = OpConstant %u32 1", - "%matrix = OpRayQueryGetIntersectionObjectToWorldKHR %f32x3x4 {ray_query} %intersection", - "%col0 = OpCompositeExtract %f32x3 %matrix 0", - "%col1 = OpCompositeExtract %f32x3 %matrix 1", - "%col2 = OpCompositeExtract %f32x3 %matrix 2", - "%col3 = OpCompositeExtract %f32x3 %matrix 3", - "%result = OpCompositeConstruct typeof*{result} %col0 %col1 %col2 %col3", - "OpStore {result} %result", - ray_query = in(reg) self, - result = in(reg) &mut result, - } - - result + unsafe { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%f32 = OpTypeFloat 32", + "%f32x3 = OpTypeVector %f32 3", + "%f32x3x4 = OpTypeMatrix %f32x3 4", + "%intersection = OpConstant %u32 1", + "%matrix = OpRayQueryGetIntersectionObjectToWorldKHR %f32x3x4 {ray_query} %intersection", + "%col0 = OpCompositeExtract %f32x3 %matrix 0", + "%col1 = OpCompositeExtract %f32x3 %matrix 1", + "%col2 = OpCompositeExtract %f32x3 %matrix 2", + "%col3 = OpCompositeExtract %f32x3 %matrix 3", + "%result = OpCompositeConstruct typeof*{result} %col0 %col1 %col2 %col3", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } + + result + } } } diff --git a/crates/spirv-std/src/runtime_array.rs b/crates/spirv-std/src/runtime_array.rs index f94c166994..109754ea88 100644 --- a/crates/spirv-std/src/runtime_array.rs +++ b/crates/spirv-std/src/runtime_array.rs @@ -30,19 +30,21 @@ impl RuntimeArray { /// and lead to UB. #[spirv_std_macros::gpu_only] pub unsafe fn index(&self, index: usize) -> &T { - // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. - let mut result = core::mem::MaybeUninit::uninit(); - asm! { - "OpDecorate %index NonUniform", - "OpDecorate %result NonUniform", - "%index = OpLoad _ {index}", - "%result = OpAccessChain typeof*{result} {this} %index", - "OpStore {result} %result", - result = in(reg) result.as_mut_ptr(), - this = in(reg) self, - index = in(reg) &index, + unsafe { + // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. + let mut result = core::mem::MaybeUninit::uninit(); + asm! { + "OpDecorate %index NonUniform", + "OpDecorate %result NonUniform", + "%index = OpLoad _ {index}", + "%result = OpAccessChain typeof*{result} {this} %index", + "OpStore {result} %result", + result = in(reg) result.as_mut_ptr(), + this = in(reg) self, + index = in(reg) &index, + } + result.assume_init() } - result.assume_init() } /// Index the array, returning a mutable reference to an element. Unfortunately, because the @@ -54,18 +56,20 @@ impl RuntimeArray { /// and lead to UB. #[spirv_std_macros::gpu_only] pub unsafe fn index_mut(&mut self, index: usize) -> &mut T { - // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. - let mut result = core::mem::MaybeUninit::uninit(); - asm! { - "OpDecorate %index NonUniform", - "OpDecorate %result NonUniform", - "%index = OpLoad _ {index}", - "%result = OpAccessChain typeof*{result} {this} %index", - "OpStore {result} %result", - result = in(reg) result.as_mut_ptr(), - this = in(reg) self, - index = in(reg) &index, + unsafe { + // FIXME(eddyb) `let mut result = T::default()` uses (for `asm!`), with this. + let mut result = core::mem::MaybeUninit::uninit(); + asm! { + "OpDecorate %index NonUniform", + "OpDecorate %result NonUniform", + "%index = OpLoad _ {index}", + "%result = OpAccessChain typeof*{result} {this} %index", + "OpStore {result} %result", + result = in(reg) result.as_mut_ptr(), + this = in(reg) self, + index = in(reg) &index, + } + result.assume_init() } - result.assume_init() } } diff --git a/examples/runners/ash/src/main.rs b/examples/runners/ash/src/main.rs index 3e22f9c268..7896288ecd 100644 --- a/examples/runners/ash/src/main.rs +++ b/examples/runners/ash/src/main.rs @@ -104,6 +104,17 @@ pub struct Options { } pub fn main() { + // Hack: spirv_builder builds into a custom directory if running under cargo, to not + // deadlock, and the default target directory if not. However, packages like `proc-macro2` + // have different configurations when being built here vs. when building + // rustc_codegen_spirv normally, so we *want* to build into a separate target directory, to + // not have to rebuild half the crate graph every time we run. So, pretend we're running + // under cargo by setting these environment variables. + unsafe { + std::env::set_var("OUT_DIR", env!("OUT_DIR")); + std::env::set_var("PROFILE", env!("PROFILE")); + } + let options = Options::parse(); let shaders = compile_shaders(); @@ -239,15 +250,6 @@ pub fn main() { } pub fn compile_shaders() -> Vec { - // Hack: spirv_builder builds into a custom directory if running under cargo, to not - // deadlock, and the default target directory if not. However, packages like `proc-macro2` - // have different configurations when being built here vs. when building - // rustc_codegen_spirv normally, so we *want* to build into a separate target directory, to - // not have to rebuild half the crate graph every time we run. So, pretend we're running - // under cargo by setting these environment variables. - std::env::set_var("OUT_DIR", env!("OUT_DIR")); - std::env::set_var("PROFILE", env!("PROFILE")); - SpirvBuilder::new( concat!(env!("CARGO_MANIFEST_DIR"), "/../../shaders/sky-shader"), "spirv-unknown-vulkan1.1", @@ -1329,7 +1331,9 @@ pub struct FragmentShaderEntryPoint { } unsafe fn any_as_u8_slice(p: &T) -> &[u8] { - ::std::slice::from_raw_parts((p as *const T).cast::(), ::std::mem::size_of::()) + unsafe { + ::std::slice::from_raw_parts((p as *const T).cast::(), ::std::mem::size_of::()) + } } unsafe extern "system" fn vulkan_debug_callback( @@ -1338,19 +1342,19 @@ unsafe extern "system" fn vulkan_debug_callback( p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT<'_>, _user_data: *mut std::os::raw::c_void, ) -> vk::Bool32 { - let callback_data = *p_callback_data; + let callback_data = unsafe { *p_callback_data }; let message_id_number: i32 = callback_data.message_id_number; let message_id_name = if callback_data.p_message_id_name.is_null() { Cow::from("") } else { - CStr::from_ptr(callback_data.p_message_id_name).to_string_lossy() + unsafe { CStr::from_ptr(callback_data.p_message_id_name).to_string_lossy() } }; let message = if callback_data.p_message.is_null() { Cow::from("") } else { - CStr::from_ptr(callback_data.p_message).to_string_lossy() + unsafe { CStr::from_ptr(callback_data.p_message).to_string_lossy() } }; println!( diff --git a/examples/runners/wgpu/src/lib.rs b/examples/runners/wgpu/src/lib.rs index 446407fabb..f6e3401daf 100644 --- a/examples/runners/wgpu/src/lib.rs +++ b/examples/runners/wgpu/src/lib.rs @@ -127,14 +127,7 @@ fn maybe_watch( { use spirv_builder::{CompileResult, MetadataPrintout, SpirvBuilder}; use std::path::PathBuf; - // Hack: spirv_builder builds into a custom directory if running under cargo, to not - // deadlock, and the default target directory if not. However, packages like `proc-macro2` - // have different configurations when being built here vs. when building - // rustc_codegen_spirv normally, so we *want* to build into a separate target directory, to - // not have to rebuild half the crate graph every time we run. So, pretend we're running - // under cargo by setting these environment variables. - std::env::set_var("OUT_DIR", env!("OUT_DIR")); - std::env::set_var("PROFILE", env!("PROFILE")); + let crate_name = match options.shader { RustGPUShader::Simplest => "simplest-shader", RustGPUShader::Sky => "sky-shader", @@ -234,10 +227,21 @@ pub struct Options { force_spirv_passthru: bool, } -#[cfg_attr(target_os = "android", export_name = "android_main")] +#[cfg_attr(target_os = "android", unsafe(export_name = "android_main"))] pub fn main( #[cfg(target_os = "android")] android_app: winit::platform::android::activity::AndroidApp, ) { + // Hack: spirv_builder builds into a custom directory if running under cargo, to not + // deadlock, and the default target directory if not. However, packages like `proc-macro2` + // have different configurations when being built here vs. when building + // rustc_codegen_spirv normally, so we *want* to build into a separate target directory, to + // not have to rebuild half the crate graph every time we run. So, pretend we're running + // under cargo by setting these environment variables. + unsafe { + std::env::set_var("OUT_DIR", env!("OUT_DIR")); + std::env::set_var("PROFILE", env!("PROFILE")); + } + let options = Options::parse(); #[cfg(not(any(target_os = "android", target_arch = "wasm32")))] diff --git a/tests/compiletests/ui/arch/all_memory_barrier.stderr b/tests/compiletests/ui/arch/all_memory_barrier.stderr index 99a24af571..98eac4756b 100644 --- a/tests/compiletests/ui/arch/all_memory_barrier.stderr +++ b/tests/compiletests/ui/arch/all_memory_barrier.stderr @@ -1,6 +1,6 @@ %1 = OpFunction %2 None %3 %4 = OpLabel -OpLine %5 75 4 +OpLine %5 78 8 OpMemoryBarrier %6 %7 OpNoLine OpReturn diff --git a/tests/compiletests/ui/arch/all_memory_barrier_with_group_sync.stderr b/tests/compiletests/ui/arch/all_memory_barrier_with_group_sync.stderr index ce22a314ef..0b4f02ef01 100644 --- a/tests/compiletests/ui/arch/all_memory_barrier_with_group_sync.stderr +++ b/tests/compiletests/ui/arch/all_memory_barrier_with_group_sync.stderr @@ -1,6 +1,6 @@ %1 = OpFunction %2 None %3 %4 = OpLabel -OpLine %5 41 4 +OpLine %5 42 8 OpControlBarrier %6 %7 %8 OpNoLine OpReturn diff --git a/tests/compiletests/ui/arch/device_memory_barrier.stderr b/tests/compiletests/ui/arch/device_memory_barrier.stderr index 99a24af571..98eac4756b 100644 --- a/tests/compiletests/ui/arch/device_memory_barrier.stderr +++ b/tests/compiletests/ui/arch/device_memory_barrier.stderr @@ -1,6 +1,6 @@ %1 = OpFunction %2 None %3 %4 = OpLabel -OpLine %5 75 4 +OpLine %5 78 8 OpMemoryBarrier %6 %7 OpNoLine OpReturn diff --git a/tests/compiletests/ui/arch/device_memory_barrier_with_group_sync.stderr b/tests/compiletests/ui/arch/device_memory_barrier_with_group_sync.stderr index ce22a314ef..0b4f02ef01 100644 --- a/tests/compiletests/ui/arch/device_memory_barrier_with_group_sync.stderr +++ b/tests/compiletests/ui/arch/device_memory_barrier_with_group_sync.stderr @@ -1,6 +1,6 @@ %1 = OpFunction %2 None %3 %4 = OpLabel -OpLine %5 41 4 +OpLine %5 42 8 OpControlBarrier %6 %7 %8 OpNoLine OpReturn diff --git a/tests/compiletests/ui/arch/workgroup_memory_barrier.stderr b/tests/compiletests/ui/arch/workgroup_memory_barrier.stderr index 99a24af571..98eac4756b 100644 --- a/tests/compiletests/ui/arch/workgroup_memory_barrier.stderr +++ b/tests/compiletests/ui/arch/workgroup_memory_barrier.stderr @@ -1,6 +1,6 @@ %1 = OpFunction %2 None %3 %4 = OpLabel -OpLine %5 75 4 +OpLine %5 78 8 OpMemoryBarrier %6 %7 OpNoLine OpReturn diff --git a/tests/compiletests/ui/arch/workgroup_memory_barrier_with_group_sync.stderr b/tests/compiletests/ui/arch/workgroup_memory_barrier_with_group_sync.stderr index 37119b71c8..6d4fb50d6d 100644 --- a/tests/compiletests/ui/arch/workgroup_memory_barrier_with_group_sync.stderr +++ b/tests/compiletests/ui/arch/workgroup_memory_barrier_with_group_sync.stderr @@ -1,6 +1,6 @@ %1 = OpFunction %2 None %3 %4 = OpLabel -OpLine %5 41 4 +OpLine %5 42 8 OpControlBarrier %6 %6 %7 OpNoLine OpReturn From abaef1a42edd15a6b7626c0da991b3aa263bcb2b Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 12 May 2025 18:54:42 +0300 Subject: [PATCH 35/38] rustup: update to `nightly-2025-04-27`. --- .cargo/config.toml | 1 - crates/rustc_codegen_spirv/build.rs | 7 ++-- .../src/builder/builder_methods.rs | 18 +++-------- crates/rustc_codegen_spirv/src/lib.rs | 4 +-- crates/spirv-builder/src/lib.rs | 1 - crates/spirv-std/macros/src/lib.rs | 1 - crates/spirv-std/src/lib.rs | 1 - examples/runners/ash/src/main.rs | 1 - examples/runners/cpu/src/main.rs | 1 - rust-toolchain.toml | 4 +-- tests/compiletests/ui/dis/issue-1062.stderr | 2 +- .../ui/dis/ptr_copy.normal.stderr | 32 +++++++++---------- .../ui/lang/core/unwrap_or.stderr | 4 +-- 13 files changed, 31 insertions(+), 46 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index ab5eb3160a..624c0e4118 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -57,7 +57,6 @@ rustflags = [ "-Wclippy::map_err_ignore", "-Wclippy::map_flatten", "-Wclippy::map_unwrap_or", - "-Wclippy::match_on_vec_items", "-Wclippy::match_same_arms", "-Wclippy::match_wild_err_arm", "-Wclippy::match_wildcard_for_single_variants", diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 3b37830bea..2358a4af1d 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-04-14" +channel = "nightly-2025-04-27" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 092a284ba0421695f2032c947765429fd7095796"#; +# commit_hash = 10fa3c449f6b1613b352a6cbf78d3d91fd9a1d81"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); @@ -320,6 +320,9 @@ mod maybe_pqp_cg_ssa; // HACK(eddyb) `if cfg!(llvm_enzyme)` added upstream for autodiff support. println!("cargo::rustc-check-cfg=cfg(llvm_enzyme)"); + // HACK(eddyb) `cfg_attr(bootstrap, ...` used upstream temporarily. + println!("cargo::rustc-check-cfg=cfg(bootstrap)"); + Ok(()) } diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index 9a55369b17..c31ff65e8b 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -210,25 +210,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { )), }, SpirvType::Integer(width, true) => match width { - 8 => self - .constant_i8(self.span(), unsafe { - std::mem::transmute::(fill_byte) - }) - .def(self), + 8 => self.constant_i8(self.span(), fill_byte as i8).def(self), 16 => self - .constant_i16(self.span(), unsafe { - std::mem::transmute::(memset_fill_u16(fill_byte)) - }) + .constant_i16(self.span(), memset_fill_u16(fill_byte) as i16) .def(self), 32 => self - .constant_i32(self.span(), unsafe { - std::mem::transmute::(memset_fill_u32(fill_byte)) - }) + .constant_i32(self.span(), memset_fill_u32(fill_byte) as i32) .def(self), 64 => self - .constant_i64(self.span(), unsafe { - std::mem::transmute::(memset_fill_u64(fill_byte)) - }) + .constant_i64(self.span(), memset_fill_u64(fill_byte) as i64) .def(self), _ => self.fatal(format!( "memset on integer width {width} not implemented yet" diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs index 893a1724ac..28ea282c0e 100644 --- a/crates/rustc_codegen_spirv/src/lib.rs +++ b/crates/rustc_codegen_spirv/src/lib.rs @@ -2,12 +2,11 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 +#![cfg_attr(bootstrap, feature(let_chains))] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(file_buffered)] #![feature(if_let_guard)] -#![feature(let_chains)] #![feature(negative_impls)] #![feature(rustdoc_internals)] #![feature(string_from_utf8_lossy_owned)] @@ -37,7 +36,6 @@ // crate-specific exceptions: #![allow( unsafe_code, // rustc_codegen_ssa requires unsafe functions in traits to be impl'd - clippy::match_on_vec_items, // rustc_codegen_spirv has less strict panic requirements than other embark projects clippy::enum_glob_use, // pretty useful pattern with some codegen'd enums (e.g. rspirv::spirv::Op) clippy::todo, // still lots to implement :) diff --git a/crates/spirv-builder/src/lib.rs b/crates/spirv-builder/src/lib.rs index d9c0a353e5..966a621113 100644 --- a/crates/spirv-builder/src/lib.rs +++ b/crates/spirv-builder/src/lib.rs @@ -36,7 +36,6 @@ clippy::map_err_ignore, clippy::map_flatten, clippy::map_unwrap_or, - clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wildcard_for_single_variants, clippy::mem_forget, diff --git a/crates/spirv-std/macros/src/lib.rs b/crates/spirv-std/macros/src/lib.rs index 5651b394cf..940604bc16 100644 --- a/crates/spirv-std/macros/src/lib.rs +++ b/crates/spirv-std/macros/src/lib.rs @@ -36,7 +36,6 @@ clippy::map_err_ignore, clippy::map_flatten, clippy::map_unwrap_or, - clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wildcard_for_single_variants, clippy::mem_forget, diff --git a/crates/spirv-std/src/lib.rs b/crates/spirv-std/src/lib.rs index 61c84dfc47..4a4774823c 100644 --- a/crates/spirv-std/src/lib.rs +++ b/crates/spirv-std/src/lib.rs @@ -42,7 +42,6 @@ clippy::map_err_ignore, clippy::map_flatten, clippy::map_unwrap_or, - clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wildcard_for_single_variants, clippy::mem_forget, diff --git a/examples/runners/ash/src/main.rs b/examples/runners/ash/src/main.rs index 7896288ecd..0e67ec7c22 100644 --- a/examples/runners/ash/src/main.rs +++ b/examples/runners/ash/src/main.rs @@ -36,7 +36,6 @@ clippy::map_err_ignore, clippy::map_flatten, clippy::map_unwrap_or, - clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wildcard_for_single_variants, clippy::mem_forget, diff --git a/examples/runners/cpu/src/main.rs b/examples/runners/cpu/src/main.rs index 41737510c1..403f7972e1 100644 --- a/examples/runners/cpu/src/main.rs +++ b/examples/runners/cpu/src/main.rs @@ -36,7 +36,6 @@ clippy::map_err_ignore, clippy::map_flatten, clippy::map_unwrap_or, - clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wildcard_for_single_variants, clippy::mem_forget, diff --git a/rust-toolchain.toml b/rust-toolchain.toml index f881e6bba0..a44975354d 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2025-04-14" +channel = "nightly-2025-04-27" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 092a284ba0421695f2032c947765429fd7095796 +# commit_hash = 10fa3c449f6b1613b352a6cbf78d3d91fd9a1d81 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. diff --git a/tests/compiletests/ui/dis/issue-1062.stderr b/tests/compiletests/ui/dis/issue-1062.stderr index 355e065baa..50182936c7 100644 --- a/tests/compiletests/ui/dis/issue-1062.stderr +++ b/tests/compiletests/ui/dis/issue-1062.stderr @@ -4,7 +4,7 @@ OpLine %5 11 12 %6 = OpLoad %7 %8 OpLine %5 11 35 %9 = OpLoad %7 %10 -OpLine %11 1098 4 +OpLine %11 1108 4 %12 = OpBitwiseAnd %7 %9 %13 %14 = OpISub %7 %15 %12 %16 = OpShiftLeftLogical %7 %6 %12 diff --git a/tests/compiletests/ui/dis/ptr_copy.normal.stderr b/tests/compiletests/ui/dis/ptr_copy.normal.stderr index 10019c222f..70fb69cf23 100644 --- a/tests/compiletests/ui/dis/ptr_copy.normal.stderr +++ b/tests/compiletests/ui/dis/ptr_copy.normal.stderr @@ -1,13 +1,13 @@ error: cannot memcpy dynamically sized data - --> $CORE_SRC/intrinsics/mod.rs:3806:9 + --> $CORE_SRC/intrinsics/mod.rs:3851:9 | -3806 | copy(src, dst, count) +3851 | copy(src, dst, count) | ^^^^^^^^^^^^^^^^^^^^^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:3786:21 + --> $CORE_SRC/intrinsics/mod.rs:3831:21 | -3786 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { +3831 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { | ^^^^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 @@ -28,25 +28,25 @@ note: called by `main` error: cannot cast between pointer types from `*f32` to `*struct () { }` - --> $CORE_SRC/intrinsics/mod.rs:3794:9 + --> $CORE_SRC/intrinsics/mod.rs:3839:9 | -3794 | / ub_checks::assert_unsafe_precondition!( -3795 | | check_language_ub, -3796 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +3839 | / ub_checks::assert_unsafe_precondition!( +3840 | | check_language_ub, +3841 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -3804 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -3805 | | ); +3849 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +3850 | | ); | |_________^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:3794:9 + --> $CORE_SRC/intrinsics/mod.rs:3839:9 | -3794 | / ub_checks::assert_unsafe_precondition!( -3795 | | check_language_ub, -3796 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +3839 | / ub_checks::assert_unsafe_precondition!( +3840 | | check_language_ub, +3841 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -3804 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -3805 | | ); +3849 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +3850 | | ); | |_________^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 diff --git a/tests/compiletests/ui/lang/core/unwrap_or.stderr b/tests/compiletests/ui/lang/core/unwrap_or.stderr index 6e2009b4fb..acb13945ed 100644 --- a/tests/compiletests/ui/lang/core/unwrap_or.stderr +++ b/tests/compiletests/ui/lang/core/unwrap_or.stderr @@ -3,9 +3,9 @@ OpLine %5 13 11 %6 = OpCompositeInsert %7 %8 %9 0 %10 = OpCompositeExtract %11 %6 1 -OpLine %12 999 14 +OpLine %12 1024 14 %13 = OpBitcast %14 %8 -OpLine %12 999 8 +OpLine %12 1024 8 %15 = OpINotEqual %16 %13 %17 OpNoLine OpSelectionMerge %18 None From 6fa55f7eab021284086f309c931904bf00fec180 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 12 May 2025 22:39:28 +0300 Subject: [PATCH 36/38] Fix new `clippy::uninlined_format_args` warnings. --- crates/spirv-builder/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/spirv-builder/src/lib.rs b/crates/spirv-builder/src/lib.rs index 966a621113..9fd658e648 100644 --- a/crates/spirv-builder/src/lib.rs +++ b/crates/spirv-builder/src/lib.rs @@ -956,7 +956,7 @@ fn invoke_rustc(builder: &SpirvBuilder) -> Result { let mut cargo = Command::new("cargo"); if let Some(toolchain) = &builder.toolchain_overwrite { - cargo.arg(format!("+{}", toolchain)); + cargo.arg(format!("+{toolchain}")); } cargo.args([ "build", @@ -1137,7 +1137,7 @@ fn leaf_deps(artifact: &Path, mut handle: impl FnMut(&RawStr)) -> std::io::Resul pub fn query_rustc_version(toolchain: Option<&str>) -> std::io::Result { let mut cmd = Command::new("rustc"); if let Some(toolchain) = toolchain { - cmd.arg(format!("+{}", toolchain)); + cmd.arg(format!("+{toolchain}")); } cmd.arg("--version"); let output = cmd.output()?; @@ -1149,5 +1149,5 @@ pub fn query_rustc_version(toolchain: Option<&str>) -> std::io::Result Version::parse(version).ok() }; Ok(parse(&stdout) - .unwrap_or_else(|| panic!("failed parsing `rustc --version` output `{}`", stdout))) + .unwrap_or_else(|| panic!("failed parsing `rustc --version` output `{stdout}`"))) } From 8c122cbaac233011f7a370e30ea2b884586ad64a Mon Sep 17 00:00:00 2001 From: Christian Legnitto Date: Wed, 30 Apr 2025 12:32:42 -0400 Subject: [PATCH 37/38] rustup to `nightly-2025-04-28` --- crates/rustc_codegen_spirv/build.rs | 4 ++-- crates/rustc_codegen_spirv/src/codegen_cx/declare.rs | 12 +----------- rust-toolchain.toml | 4 ++-- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 2358a4af1d..707d54a8ef 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-04-27" +channel = "nightly-2025-04-28" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 10fa3c449f6b1613b352a6cbf78d3d91fd9a1d81"#; +# commit_hash = cb31a009e3e735ab08613cec2d8a5a754e65596f"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs b/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs index ff221f0ad9..c13e01d567 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/declare.rs @@ -12,7 +12,6 @@ use rspirv::spirv::{FunctionControl, LinkageType, StorageClass, Word}; use rustc_abi::Align; use rustc_attr_parsing::InlineAttr; use rustc_codegen_ssa::traits::{PreDefineCodegenMethods, StaticCodegenMethods}; -use rustc_hir::def::DefKind; use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility}; @@ -127,16 +126,7 @@ impl<'tcx> CodegenCx<'tcx> { let declared = fn_id.with_type(function_type); - let attrs = AggregatedSpirvAttributes::parse( - self, - match self.tcx.def_kind(def_id) { - // This was made to ICE cross-crate at some point, but then got - // reverted in https://github.com/rust-lang/rust/pull/111381. - // FIXME(eddyb) remove this workaround once we rustup past that. - DefKind::Closure => &[], - _ => self.tcx.get_attrs_unchecked(def_id), - }, - ); + let attrs = AggregatedSpirvAttributes::parse(self, self.tcx.get_attrs_unchecked(def_id)); if let Some(entry) = attrs.entry.map(|attr| attr.value) { let entry_name = entry .name diff --git a/rust-toolchain.toml b/rust-toolchain.toml index a44975354d..c0f8d6c5ab 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2025-04-27" +channel = "nightly-2025-04-28" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = 10fa3c449f6b1613b352a6cbf78d3d91fd9a1d81 +# commit_hash = cb31a009e3e735ab08613cec2d8a5a754e65596f # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. From 658e55b5d9756770a8c2b454b2bf69836a5cfd63 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 12 May 2025 19:50:09 +0300 Subject: [PATCH 38/38] rustup: update to `nightly-2025-05-09` (~1.88). --- crates/rustc_codegen_spirv/build.rs | 4 +- .../src/builder/intrinsics.rs | 2 +- .../rustc_codegen_spirv/src/codegen_cx/mod.rs | 2 +- crates/rustc_codegen_spirv/src/lib.rs | 51 +++++++++++++------ examples/runners/wgpu/src/lib.rs | 1 - rust-toolchain.toml | 4 +- .../ui/arch/debug_printf_type_checking.stderr | 20 ++++---- .../ui/dis/ptr_copy.normal.stderr | 32 ++++++------ tests/compiletests/ui/dis/ptr_read.stderr | 2 +- .../ui/dis/ptr_read_method.stderr | 2 +- tests/compiletests/ui/dis/ptr_write.stderr | 2 +- .../ui/dis/ptr_write_method.stderr | 2 +- 12 files changed, 71 insertions(+), 53 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index 707d54a8ef..7bb8ca3eed 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -18,9 +18,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-04-28" +channel = "nightly-2025-05-09" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = cb31a009e3e735ab08613cec2d8a5a754e65596f"#; +# commit_hash = 50aa04180709189a03dde5fd1c05751b2625ed37"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs index 36233f72fe..1f9b13962f 100644 --- a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs +++ b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs @@ -334,7 +334,7 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> { _ => { // Call the fallback body instead of generating the intrinsic code - return Err(ty::Instance::new(instance.def_id(), instance.args)); + return Err(ty::Instance::new_raw(instance.def_id(), instance.args)); } }; diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs b/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs index 0668314faa..19d365fdcb 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs @@ -971,7 +971,7 @@ impl<'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'tcx> { impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'tcx> { fn codegen_global_asm( - &self, + &mut self, _template: &[InlineAsmTemplatePiece], _operands: &[GlobalAsmOperandRef<'tcx>], _options: InlineAsmOptions, diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs index 28ea282c0e..c3b29b786a 100644 --- a/crates/rustc_codegen_spirv/src/lib.rs +++ b/crates/rustc_codegen_spirv/src/lib.rs @@ -12,6 +12,7 @@ #![feature(string_from_utf8_lossy_owned)] #![feature(trait_alias)] #![feature(try_blocks)] +#![recursion_limit = "256"] // HACK(eddyb) end of `rustc_codegen_ssa` crate-level attributes (see `build.rs`). //! Welcome to the API documentation for the `rust-gpu` project, this API is @@ -150,7 +151,7 @@ use maybe_pqp_cg_ssa::traits::{ CodegenBackend, ExtraBackendMethods, ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods, }; -use maybe_pqp_cg_ssa::{CodegenResults, CompiledModule, ModuleCodegen, ModuleKind}; +use maybe_pqp_cg_ssa::{CodegenResults, CompiledModule, ModuleCodegen, ModuleKind, TargetConfig}; use rspirv::binary::Assemble; use rustc_ast::expand::allocator::AllocatorKind; use rustc_ast::expand::autodiff_attrs::AutoDiffItem; @@ -222,11 +223,11 @@ impl CodegenBackend for SpirvCodegenBackend { rustc_errors::DEFAULT_LOCALE_RESOURCE } - fn target_features_cfg(&self, sess: &Session) -> (Vec, Vec) { + fn target_config(&self, sess: &Session) -> TargetConfig { let cmdline = sess.opts.cg.target_feature.split(','); let cfg = sess.target.options.features.split(','); - let all_target_features: Vec<_> = cfg + let target_features: Vec<_> = cfg .chain(cmdline) .filter(|l| l.starts_with('+')) .map(|l| &l[1..]) @@ -234,9 +235,21 @@ impl CodegenBackend for SpirvCodegenBackend { .map(Symbol::intern) .collect(); - // HACK(eddyb) the second list is "including unstable target features", + // HACK(eddyb) this should be a superset of `target_features`, + // which *additionally* also includes unstable target features, // but there is no reason to make a distinction for SPIR-V ones. - (all_target_features.clone(), all_target_features) + let unstable_target_features = target_features.clone(); + + TargetConfig { + target_features, + unstable_target_features, + + // FIXME(eddyb) support and/or emulate `f16` and `f128`. + has_reliable_f16: false, + has_reliable_f16_math: false, + has_reliable_f128: false, + has_reliable_f128_math: false, + } } fn provide(&self, providers: &mut rustc_middle::util::Providers) { @@ -438,8 +451,8 @@ impl ExtraBackendMethods for SpirvCodegenBackend { // TODO: Do dep_graph stuff let cgu = tcx.codegen_unit(cgu_name); - let cx = CodegenCx::new(tcx, cgu); - let do_codegen = || { + let mut cx = CodegenCx::new(tcx, cgu); + let do_codegen = |cx: &mut CodegenCx<'_>| { let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx); if let Some(dir) = &cx.codegen_args.dump_mir { @@ -448,27 +461,33 @@ impl ExtraBackendMethods for SpirvCodegenBackend { for &(mono_item, mono_item_data) in mono_items.iter() { mono_item.predefine::>( - &cx, + cx, mono_item_data.linkage, mono_item_data.visibility, ); } // ... and now that we have everything pre-defined, fill out those definitions. - for &(mono_item, _) in mono_items.iter() { - mono_item.define::>(&cx); + for &(mono_item, mono_item_data) in &mono_items { + mono_item.define::>(cx, mono_item_data); } - if let Some(_entry) = maybe_create_entry_wrapper::>(&cx) { + if let Some(_entry) = maybe_create_entry_wrapper::>(cx) { // attributes::sanitize(&cx, SanitizerSet::empty(), entry); } }; - if let Some(path) = &cx.codegen_args.dump_module_on_panic { - let module_dumper = DumpModuleOnPanic { cx: &cx, path }; - with_no_trimmed_paths!(do_codegen()); + // HACK(eddyb) mutable access needed for `mono_item.define::<...>(cx, ...)` + // but that alone leads to needless cloning and smuggling a mutable borrow + // through `DumpModuleOnPanic` (for both its `Drop` impl and `do_codegen`). + if let Some(path) = cx.codegen_args.dump_module_on_panic.clone() { + let module_dumper = DumpModuleOnPanic { + cx: &mut cx, + path: &path, + }; + with_no_trimmed_paths!(do_codegen(module_dumper.cx)); drop(module_dumper); } else { - with_no_trimmed_paths!(do_codegen()); + with_no_trimmed_paths!(do_codegen(&mut cx)); } let spirv_module = cx.finalize_module().assemble(); @@ -495,7 +514,7 @@ impl ExtraBackendMethods for SpirvCodegenBackend { } struct DumpModuleOnPanic<'a, 'cx, 'tcx> { - cx: &'cx CodegenCx<'tcx>, + cx: &'cx mut CodegenCx<'tcx>, path: &'a Path, } diff --git a/examples/runners/wgpu/src/lib.rs b/examples/runners/wgpu/src/lib.rs index f6e3401daf..fd66d33d90 100644 --- a/examples/runners/wgpu/src/lib.rs +++ b/examples/runners/wgpu/src/lib.rs @@ -36,7 +36,6 @@ clippy::map_err_ignore, clippy::map_flatten, clippy::map_unwrap_or, - clippy::match_on_vec_items, clippy::match_same_arms, clippy::match_wildcard_for_single_variants, clippy::mem_forget, diff --git a/rust-toolchain.toml b/rust-toolchain.toml index c0f8d6c5ab..174ba5c1f0 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2025-04-28" +channel = "nightly-2025-05-09" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = cb31a009e3e735ab08613cec2d8a5a754e65596f +# commit_hash = 50aa04180709189a03dde5fd1c05751b2625ed37 # Whenever changing the nightly channel, update the commit hash above, and make # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. diff --git a/tests/compiletests/ui/arch/debug_printf_type_checking.stderr b/tests/compiletests/ui/arch/debug_printf_type_checking.stderr index 5c1b487bde..faec0bc0c7 100644 --- a/tests/compiletests/ui/arch/debug_printf_type_checking.stderr +++ b/tests/compiletests/ui/arch/debug_printf_type_checking.stderr @@ -75,9 +75,9 @@ help: the return type of this call is `u32` due to the type of the argument pass | | | this argument influences the return type of `debug_printf_assert_is_type` note: function defined here - --> $SPIRV_STD_SRC/lib.rs:134:8 + --> $SPIRV_STD_SRC/lib.rs:133:8 | -134 | pub fn debug_printf_assert_is_type(ty: T) -> T { +133 | pub fn debug_printf_assert_is_type(ty: T) -> T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `debug_printf` (in Nightly builds, run with -Z macro-backtrace for more info) help: change the type of the numeric literal from `u32` to `f32` @@ -103,9 +103,9 @@ help: the return type of this call is `f32` due to the type of the argument pass | | | this argument influences the return type of `debug_printf_assert_is_type` note: function defined here - --> $SPIRV_STD_SRC/lib.rs:134:8 + --> $SPIRV_STD_SRC/lib.rs:133:8 | -134 | pub fn debug_printf_assert_is_type(ty: T) -> T { +133 | pub fn debug_printf_assert_is_type(ty: T) -> T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `debug_printf` (in Nightly builds, run with -Z macro-backtrace for more info) help: change the type of the numeric literal from `f32` to `u32` @@ -131,12 +131,12 @@ error[E0277]: the trait bound `{float}: Vector` is not satisfied `UVec3` implements `Vector` and 5 others note: required by a bound in `debug_printf_assert_is_vector` - --> $SPIRV_STD_SRC/lib.rs:141:8 + --> $SPIRV_STD_SRC/lib.rs:140:8 | -139 | pub fn debug_printf_assert_is_vector< +138 | pub fn debug_printf_assert_is_vector< | ----------------------------- required by a bound in this function -140 | TY: crate::scalar::Scalar, -141 | V: crate::vector::Vector, +139 | TY: crate::scalar::Scalar, +140 | V: crate::vector::Vector, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `debug_printf_assert_is_vector` = note: this error originates in the macro `debug_printf` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -157,9 +157,9 @@ help: the return type of this call is `Vec2` due to the type of the argument pas | | | this argument influences the return type of `debug_printf_assert_is_type` note: function defined here - --> $SPIRV_STD_SRC/lib.rs:134:8 + --> $SPIRV_STD_SRC/lib.rs:133:8 | -134 | pub fn debug_printf_assert_is_type(ty: T) -> T { +133 | pub fn debug_printf_assert_is_type(ty: T) -> T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `debug_printf` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/compiletests/ui/dis/ptr_copy.normal.stderr b/tests/compiletests/ui/dis/ptr_copy.normal.stderr index 70fb69cf23..994c1a6e8c 100644 --- a/tests/compiletests/ui/dis/ptr_copy.normal.stderr +++ b/tests/compiletests/ui/dis/ptr_copy.normal.stderr @@ -1,13 +1,13 @@ error: cannot memcpy dynamically sized data - --> $CORE_SRC/intrinsics/mod.rs:3851:9 + --> $CORE_SRC/intrinsics/mod.rs:3850:9 | -3851 | copy(src, dst, count) +3850 | copy(src, dst, count) | ^^^^^^^^^^^^^^^^^^^^^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:3831:21 + --> $CORE_SRC/intrinsics/mod.rs:3830:21 | -3831 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { +3830 | pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { | ^^^^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 @@ -28,25 +28,25 @@ note: called by `main` error: cannot cast between pointer types from `*f32` to `*struct () { }` - --> $CORE_SRC/intrinsics/mod.rs:3839:9 + --> $CORE_SRC/intrinsics/mod.rs:3838:9 | -3839 | / ub_checks::assert_unsafe_precondition!( -3840 | | check_language_ub, -3841 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +3838 | / ub_checks::assert_unsafe_precondition!( +3839 | | check_language_ub, +3840 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -3849 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -3850 | | ); +3848 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +3849 | | ); | |_________^ | note: used from within `core::intrinsics::copy::` - --> $CORE_SRC/intrinsics/mod.rs:3839:9 + --> $CORE_SRC/intrinsics/mod.rs:3838:9 | -3839 | / ub_checks::assert_unsafe_precondition!( -3840 | | check_language_ub, -3841 | | "ptr::copy requires that both pointer arguments are aligned and non-null", +3838 | / ub_checks::assert_unsafe_precondition!( +3839 | | check_language_ub, +3840 | | "ptr::copy requires that both pointer arguments are aligned and non-null", ... | -3849 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) -3850 | | ); +3848 | | && ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size) +3849 | | ); | |_________^ note: called by `ptr_copy::copy_via_raw_ptr` --> $DIR/ptr_copy.rs:28:18 diff --git a/tests/compiletests/ui/dis/ptr_read.stderr b/tests/compiletests/ui/dis/ptr_read.stderr index 6535a9f5f1..4d4ea6333d 100644 --- a/tests/compiletests/ui/dis/ptr_read.stderr +++ b/tests/compiletests/ui/dis/ptr_read.stderr @@ -2,7 +2,7 @@ %4 = OpFunctionParameter %5 %6 = OpFunctionParameter %5 %7 = OpLabel -OpLine %8 1420 8 +OpLine %8 1455 8 %9 = OpLoad %10 %4 OpLine %11 7 13 OpStore %6 %9 diff --git a/tests/compiletests/ui/dis/ptr_read_method.stderr b/tests/compiletests/ui/dis/ptr_read_method.stderr index 6535a9f5f1..4d4ea6333d 100644 --- a/tests/compiletests/ui/dis/ptr_read_method.stderr +++ b/tests/compiletests/ui/dis/ptr_read_method.stderr @@ -2,7 +2,7 @@ %4 = OpFunctionParameter %5 %6 = OpFunctionParameter %5 %7 = OpLabel -OpLine %8 1420 8 +OpLine %8 1455 8 %9 = OpLoad %10 %4 OpLine %11 7 13 OpStore %6 %9 diff --git a/tests/compiletests/ui/dis/ptr_write.stderr b/tests/compiletests/ui/dis/ptr_write.stderr index 69b26d117f..3b757241cc 100644 --- a/tests/compiletests/ui/dis/ptr_write.stderr +++ b/tests/compiletests/ui/dis/ptr_write.stderr @@ -4,7 +4,7 @@ %7 = OpLabel OpLine %8 7 35 %9 = OpLoad %10 %4 -OpLine %11 1620 8 +OpLine %11 1655 8 OpStore %6 %9 OpNoLine OpReturn diff --git a/tests/compiletests/ui/dis/ptr_write_method.stderr b/tests/compiletests/ui/dis/ptr_write_method.stderr index b8e0a95ff0..701ac3e759 100644 --- a/tests/compiletests/ui/dis/ptr_write_method.stderr +++ b/tests/compiletests/ui/dis/ptr_write_method.stderr @@ -4,7 +4,7 @@ %7 = OpLabel OpLine %8 7 37 %9 = OpLoad %10 %4 -OpLine %11 1620 8 +OpLine %11 1655 8 OpStore %6 %9 OpNoLine OpReturn