summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-02-26 22:38:23 -0800
committerGitHub <noreply@github.com>2025-02-26 22:38:23 -0800
commit60c5db5caba089bf879fc958f373137b3e12a2d8 (patch)
tree696db2d9457d2453ef640c5f337ff3c7d078c50e /source/slang
parent02706dfc5f0526f4f8ca337be16d7b00640ba168 (diff)
Fix regression when using Atomic<T> in struct. (#6472)
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-check-decl.cpp5
-rw-r--r--source/slang/slang-emit-spirv.cpp114
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: