From 756ce3d91faf80b6a3e6a695d0dec3968048c11e Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 8 May 2024 20:23:38 -0700 Subject: Fix legalization of `kIROp_GetLegalizedSPIRVGlobalParamAddr`. (#4141) --- source/slang/hlsl.meta.slang | 49 ++++++++++++++++++++++++++++++-- source/slang/slang-ir-spirv-legalize.cpp | 9 ++++-- 2 files changed, 54 insertions(+), 4 deletions(-) (limited to 'source') diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 6b3c5db59..b3e323bfc 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -7432,11 +7432,22 @@ void InterlockedAdd(__ref uint dest, uint value, out uint original_value) } [ForceInline] +[require(cuda_glsl_hlsl_spirv, atomic_glsl_hlsl_cuda)] void InterlockedAdd(__ref int64_t dest, int64_t value) { __target_switch { case hlsl: __intrinsic_asm "InterlockedAdd"; + case cuda: __intrinsic_asm "atomicAdd((uint64_t*)$0, $1)"; + case glsl: + __requireGLSLExtension("GL_EXT_shader_atomic_int64"); + __intrinsic_asm "$atomicAdd($A, $1)"; + case spirv: + spirv_asm + { + OpCapability Int64Atomics; + result:$$int64_t = OpAtomicIAdd &dest Device None $value; + }; } } @@ -7446,27 +7457,61 @@ void InterlockedAdd(__ref int64_t dest, int64_t value, out int64_t original_v __target_switch { case hlsl: __intrinsic_asm "InterlockedAdd"; + case cuda: __intrinsic_asm "atomicAdd((uint64_t*)$0, $1)"; + case glsl: + __requireGLSLExtension("GL_EXT_shader_atomic_int64"); + __intrinsic_asm "$atomicAdd($A, $1)"; + case spirv: + spirv_asm + { + OpCapability Int64Atomics; + %origin:$$int64_t = OpAtomicIAdd &dest Device None $value; + OpStore &original_value %origin + }; } } [ForceInline] -void InterlockedAdd(__ref uint64_t dest, uint64_t value) +[require(cuda_glsl_hlsl_spirv, atomic_glsl_hlsl_cuda)] +void InterlockedAdd(__ref uint64_t dest, uint64_t value) { __target_switch { case hlsl: __intrinsic_asm "InterlockedAdd"; + case cuda: __intrinsic_asm "atomicAdd($0, $1)"; + case glsl: + __requireGLSLExtension("GL_EXT_shader_atomic_int64"); + __intrinsic_asm "$atomicAdd($A, $1)"; + case spirv: + spirv_asm + { + OpCapability Int64Atomics; + result:$$uint64_t = OpAtomicIAdd &dest Device None $value; + }; } } [ForceInline] -void InterlockedAdd(__ref uint64_t dest, uint64_t value, out uint64_t original_value) +void InterlockedAdd(__ref uint64_t dest, uint64_t value, out uint64_t original_value) { __target_switch { case hlsl: __intrinsic_asm "InterlockedAdd"; + case cuda: __intrinsic_asm "atomicAdd($0, $1)"; + case glsl: + __requireGLSLExtension("GL_EXT_shader_atomic_int64"); + __intrinsic_asm "$atomicAdd($A, $1)"; + case spirv: + spirv_asm + { + OpCapability Int64Atomics; + %origin:$$uint64_t = OpAtomicIAdd &dest Device None $value; + OpStore &original_value %origin + }; } } + __glsl_version(430) [require(cuda_glsl_hlsl_spirv, atomic_glsl_hlsl_cuda)] void InterlockedAnd(__ref int dest, int value) diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp index 48a46f962..e863f279e 100644 --- a/source/slang/slang-ir-spirv-legalize.cpp +++ b/source/slang/slang-ir-spirv-legalize.cpp @@ -221,7 +221,7 @@ struct SPIRVLegalizationContext : public SourceEmitterBase if(user->getOp() == kIROp_GetLegalizedSPIRVGlobalParamAddr) { - user->replaceUsesWith(use->get()); + user->replaceUsesWith(addr); user->removeAndDeallocate(); } else if((as(user) || as(user)) && @@ -251,10 +251,13 @@ struct SPIRVLegalizationContext : public SourceEmitterBase { // Skip load's for referenced `Input` variables since a ref implies // passing as is, which needs to be a pointer (pass as is). - if (user->getDataType() + if (user->getDataType() && user->getDataType()->getOp() == kIROp_RefType && storageClass == SpvStorageClassInput) + { + builder.replaceOperand(use, addr); continue; + } // If this is being used in an asm block, insert the load to // just prior to the block. const auto asmBlock = spirvAsmOperand->getAsmBlock(); @@ -276,7 +279,9 @@ struct SPIRVLegalizationContext : public SourceEmitterBase } for (auto i : instsToRemove) + { i->removeAndDeallocate(); + } } // Returns true if the given type that should be decorated as in `UniformConstant` address space. -- cgit v1.2.3