diff options
| author | Yong He <yonghe@outlook.com> | 2025-02-26 22:38:23 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-26 22:38:23 -0800 |
| commit | 60c5db5caba089bf879fc958f373137b3e12a2d8 (patch) | |
| tree | 696db2d9457d2453ef640c5f337ff3c7d078c50e /source/slang | |
| parent | 02706dfc5f0526f4f8ca337be16d7b00640ba168 (diff) | |
Fix regression when using Atomic<T> in struct. (#6472)
Diffstat (limited to 'source/slang')
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-emit-spirv.cpp | 114 |
2 files changed, 81 insertions, 38 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 1659a161b..f12d11bdf 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -12441,10 +12441,13 @@ bool SemanticsDeclAttributesVisitor::_synthesizeCtorSignature(StructDecl* struct { auto member = resultMembers[i]; auto parentAggDecl = getParentAggTypeDecl(member); - ; auto ctorParam = m_astBuilder->create<ParamDecl>(); ctorParam->type = (TypeExp)member->type; + if (auto atomicType = as<AtomicType>(ctorParam->type)) + { + ctorParam->type.type = atomicType->getElementType(); + } if (!stopProcessingDefaultValues) ctorParam->initExpr = _getParamDefaultValue(this, member); diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index bc90e3ac4..e0367be89 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -3407,6 +3407,25 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex return emitOpBitcast(parent, inst, inst->getDataType(), vec); } + bool isAtomicableAddressSpace(IRInst* type) + { + auto ptrType = as<IRPtrTypeBase>(type); + if (!ptrType) + return false; + switch (ptrType->getAddressSpace()) + { + case AddressSpace::Global: + case AddressSpace::StorageBuffer: + case AddressSpace::UserPointer: + case AddressSpace::GroupShared: + case AddressSpace::Image: + case AddressSpace::TaskPayloadWorkgroup: + return true; + default: + return false; + } + } + // The instructions that appear inside the basic blocks of // functions are what we will call "local" instructions. // @@ -3862,53 +3881,74 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex case kIROp_AtomicLoad: { IRBuilder builder{inst}; - const auto memoryScope = - emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType()); - const auto memorySemantics = - emitMemorySemanticMask(inst->getOperand(1), inst->getOperand(0)); - result = emitOpAtomicLoad( - parent, - inst, - inst->getFullType(), - inst->getOperand(0), - memoryScope, - memorySemantics); - ensureAtomicCapability(inst, SpvOpAtomicLoad); + if (isAtomicableAddressSpace(inst->getOperand(0)->getDataType())) + { + const auto memoryScope = + emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType()); + const auto memorySemantics = + emitMemorySemanticMask(inst->getOperand(1), inst->getOperand(0)); + result = emitOpAtomicLoad( + parent, + inst, + inst->getFullType(), + inst->getOperand(0), + memoryScope, + memorySemantics); + ensureAtomicCapability(inst, SpvOpAtomicLoad); + } + else + { + result = emitOpLoad(parent, inst, inst->getFullType(), inst->getOperand(0)); + } } break; case kIROp_AtomicStore: { IRBuilder builder{inst}; - const auto memoryScope = - emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType()); - const auto memorySemantics = - emitMemorySemanticMask(inst->getOperand(2), inst->getOperand(0)); - result = emitOpAtomicStore( - parent, - inst, - inst->getOperand(0), - memoryScope, - memorySemantics, - inst->getOperand(1)); - ensureAtomicCapability(inst, SpvOpAtomicStore); + if (isAtomicableAddressSpace(inst->getOperand(0)->getDataType())) + { + const auto memoryScope = + emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType()); + const auto memorySemantics = + emitMemorySemanticMask(inst->getOperand(2), inst->getOperand(0)); + result = emitOpAtomicStore( + parent, + inst, + inst->getOperand(0), + memoryScope, + memorySemantics, + inst->getOperand(1)); + ensureAtomicCapability(inst, SpvOpAtomicStore); + } + else + { + result = emitOpStore(parent, inst, inst->getOperand(0), inst->getOperand(1)); + } } break; case kIROp_AtomicExchange: { IRBuilder builder{inst}; - const auto memoryScope = - emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType()); - const auto memorySemantics = - emitMemorySemanticMask(inst->getOperand(2), inst->getOperand(0)); - result = emitOpAtomicExchange( - parent, - inst, - inst->getFullType(), - inst->getOperand(0), - memoryScope, - memorySemantics, - inst->getOperand(1)); - ensureAtomicCapability(inst, SpvOpAtomicExchange); + if (isAtomicableAddressSpace(inst->getOperand(0)->getDataType())) + { + const auto memoryScope = + emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType()); + const auto memorySemantics = + emitMemorySemanticMask(inst->getOperand(2), inst->getOperand(0)); + result = emitOpAtomicExchange( + parent, + inst, + inst->getFullType(), + inst->getOperand(0), + memoryScope, + memorySemantics, + inst->getOperand(1)); + ensureAtomicCapability(inst, SpvOpAtomicExchange); + } + else + { + result = emitOpStore(parent, inst, inst->getOperand(0), inst->getOperand(1)); + } } break; case kIROp_AtomicCompareExchange: |
