Conversation
Firestar99
left a comment
There was a problem hiding this comment.
Rebased it on main, squashed the fmt fixes and added disassembly and arrays from consts to the compiletest.
Overall, I'm super impressed how simple this has turned out to be. I haven't looked at our existing pointer emulation too deeply before, but this seems quite logical.
@LegNeato But this also shows that I've been wrong about RuntimeArray only being used via spirv_std::RuntimeArray, it is also used to represent slices. Just that those slices get removed in the post-link legalization, since they contain a pointer, so you don't actually see them in the disassembly of the compiletest.
See:
rust-gpu/crates/rustc_codegen_spirv/src/abi.rs
Lines 637 to 646 in bdf8bae
|
@Firestar99 we should probably use |
eddyb
left a comment
There was a problem hiding this comment.
I'm not sure why this change even helps - is it hiding errors that don't end up mattering in the end?
One way you could check is compiling (using some Rust-GPU version without this change) with RUSTGPU_CODEGEN_ARGS=--no-early-report-zombies (which moves the "zombie" reporting much later, near the end of the SPIR-T part of the linker).
For the test, I believe this is equivalent:
// compile-flags: -C llvm-args=--no-early-report-zombies| // array -> element: *[T; N] -> *T | ||
| if let SpirvType::Array { | ||
| element: elem_ty, .. | ||
| } = src_pointee_ty | ||
| && elem_ty == dest_pointee | ||
| { | ||
| let zero = self.constant_u32(self.span(), 0).def(self); | ||
| return self | ||
| .emit() | ||
| .in_bounds_access_chain(dest_ty, None, ptr.def(self), [zero]) | ||
| .unwrap() | ||
| .with_type(dest_ty); | ||
| } |
There was a problem hiding this comment.
How come this is needed, won't recover_access_chain_from_offset produce the same effect?
| .with_type(dest_ty); | ||
| } | ||
|
|
||
| // array -> RuntimeArray: *[T; N] -> *[T] |
There was a problem hiding this comment.
Looks like this is doing *[T; N] -> *T -> *[T], using an OpInBoundsAccessChain for the first step, and OpBitcast for the second step, but:
- that
OpBitcastis illegal, but won't be seen by the same zombie-creating logic that would be triggered by usingself.pointercast(elem_ptr, dest_ty) - creating
SpirvValueKind::LogicalPtrCast(like callingpointercastrecursively would do) allows later stripping the cast, so it should be more helpful?
I can't see how this helps, other than hiding an error?
|
The test from this PR passes on --- a/tests/compiletests/ui/lang/core/array-slice-cast.rs
+++ b/tests/compiletests/ui/lang/core/array-slice-cast.rs
@@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
// build-pass
-// compile-flags: -C llvm-args=--disassemble
+// compile-flags: -C llvm-args=--disassemble -C llvm-args=--no-early-report-zombiesI've been meaning for a while to replace the old zombie system:
In this specific case, I am guessing inlining removes the need for a |
fixes casting array as a slice , or array to ptr :
*[T; N] -> *[T]
*[T; N] -> *T
fixes #465