Closed giomasce closed 5 months ago
Is this fixable? Does it work if you reinterpret_cast texture2d<uint, access::read_write> to texture2d<int, access::read_write>?
Seems like this works ...
#pragma clang diagnostic ignored "-Wunused-variable"
#include <metal_stdlib>
#include <simd/simd.h>
#include <metal_atomic>
using namespace metal;
template <typename T, typename U>
static inline T texture_cast(U img)
{
return reinterpret_cast<thread const T &>(img);
}
kernel void main0(texture2d<uint, access::read_write> u0 [[texture(0)]])
{
uint _17 = uint(texture_cast<texture2d<int, access::read_write>>(u0).atomic_fetch_max(uint2(0, 1), int(4294967295u)).x);
}
; Function Attrs: mustprogress nounwind willreturn
define void @main0(%struct._texture_2d_t addrspace(1)* nocapture %0) local_unnamed_addr #0 {
%2 = tail call <4 x i32> @air.atomic_fetch_max_explicit_texture_2d.s.v4i32(%struct._texture_2d_t addrspace(1)* nocapture %0, <2 x i32> <i32 0, i32 1>, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, i32 0, i32 3) #2
ret void
}
This was initially reported as https://github.com/KhronosGroup/MoltenVK/issues/2194, where it was suggested to file it here.
It seems that the MSL 3.1 code generated for
OpAtomicSMax
treats the operation as unsigned rather than signed. I'm testing with the SPIR-V code (compiled for Vulkan 1.0):With MSL 3.1 this becomes:
I guess that here the implicit type for
atomic_fetch_max
is taken from the resource, not from the argument, as it would happen with usual C++ atomics.For MSL 3.0 this is generated instead:
This looks correct AFAICT, and works properly on MoltenVK.