From ccfab4e1c62dc557153c5aef9c60cdc989ee6960 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 13 Oct 2025 07:14:12 +0300 Subject: [PATCH] builder: implement pointer atomics (missing in SPIR-V) via integers. --- .../src/builder/builder_methods.rs | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index d86db1cbd0..3c93f39673 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -1850,7 +1850,12 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { order: AtomicOrdering, _size: Size, ) -> Self::Value { - let (ptr, access_ty) = self.adjust_pointer_for_typed_access(ptr, ty); + // HACK(eddyb) SPIR-V lacks pointer atomics, have to use integers instead. + let atomic_ty = match self.lookup_type(ty) { + SpirvType::Pointer { .. } => self.type_usize(), + _ => ty, + }; + let (ptr, access_ty) = self.adjust_pointer_for_typed_access(ptr, atomic_ty); // TODO: Default to device scope let memory = self.constant_u32(self.span(), Scope::Device as u32); @@ -1988,7 +1993,12 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { order: AtomicOrdering, _size: Size, ) { - let (ptr, access_ty) = self.adjust_pointer_for_typed_access(ptr, val.ty); + // HACK(eddyb) SPIR-V lacks pointer atomics, have to use integers instead. + let atomic_ty = match self.lookup_type(val.ty) { + SpirvType::Pointer { .. } => self.type_usize(), + _ => val.ty, + }; + let (ptr, access_ty) = self.adjust_pointer_for_typed_access(ptr, atomic_ty); let val = self.bitcast(val, access_ty); // TODO: Default to device scope @@ -3089,7 +3099,12 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { assert_ty_eq!(self, cmp.ty, src.ty); let ty = src.ty; - let (dst, access_ty) = self.adjust_pointer_for_typed_access(dst, ty); + // HACK(eddyb) SPIR-V lacks pointer atomics, have to use integers instead. + let atomic_ty = match self.lookup_type(ty) { + SpirvType::Pointer { .. } => self.type_usize(), + _ => ty, + }; + let (dst, access_ty) = self.adjust_pointer_for_typed_access(dst, atomic_ty); let cmp = self.bitcast(cmp, access_ty); let src = self.bitcast(src, access_ty); @@ -3115,7 +3130,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { .with_type(access_ty); let val = self.bitcast(result, ty); - let success = self.icmp(IntPredicate::IntEQ, val, cmp); + let success = self.icmp(IntPredicate::IntEQ, result, cmp); (val, success) } @@ -3130,7 +3145,12 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { ) -> Self::Value { let ty = src.ty; - let (dst, access_ty) = self.adjust_pointer_for_typed_access(dst, ty); + // HACK(eddyb) SPIR-V lacks pointer atomics, have to use integers instead. + let atomic_ty = match self.lookup_type(ty) { + SpirvType::Pointer { .. } => self.type_usize(), + _ => ty, + }; + let (dst, access_ty) = self.adjust_pointer_for_typed_access(dst, atomic_ty); let src = self.bitcast(src, access_ty); self.validate_atomic(access_ty, dst.def(self));