Skip to content

Commit 60c5db5

Browse files
authored
Fix regression when using Atomic<T> in struct. (shader-slang#6472)
1 parent 02706df commit 60c5db5

File tree

3 files changed

+96
-38
lines changed

3 files changed

+96
-38
lines changed

source/slang/slang-check-decl.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -12441,10 +12441,13 @@ bool SemanticsDeclAttributesVisitor::_synthesizeCtorSignature(StructDecl* struct
1244112441
{
1244212442
auto member = resultMembers[i];
1244312443
auto parentAggDecl = getParentAggTypeDecl(member);
12444-
;
1244512444

1244612445
auto ctorParam = m_astBuilder->create<ParamDecl>();
1244712446
ctorParam->type = (TypeExp)member->type;
12447+
if (auto atomicType = as<AtomicType>(ctorParam->type))
12448+
{
12449+
ctorParam->type.type = atomicType->getElementType();
12450+
}
1244812451

1244912452
if (!stopProcessingDefaultValues)
1245012453
ctorParam->initExpr = _getParamDefaultValue(this, member);

source/slang/slang-emit-spirv.cpp

+77-37
Original file line numberDiff line numberDiff line change
@@ -3407,6 +3407,25 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
34073407
return emitOpBitcast(parent, inst, inst->getDataType(), vec);
34083408
}
34093409

3410+
bool isAtomicableAddressSpace(IRInst* type)
3411+
{
3412+
auto ptrType = as<IRPtrTypeBase>(type);
3413+
if (!ptrType)
3414+
return false;
3415+
switch (ptrType->getAddressSpace())
3416+
{
3417+
case AddressSpace::Global:
3418+
case AddressSpace::StorageBuffer:
3419+
case AddressSpace::UserPointer:
3420+
case AddressSpace::GroupShared:
3421+
case AddressSpace::Image:
3422+
case AddressSpace::TaskPayloadWorkgroup:
3423+
return true;
3424+
default:
3425+
return false;
3426+
}
3427+
}
3428+
34103429
// The instructions that appear inside the basic blocks of
34113430
// functions are what we will call "local" instructions.
34123431
//
@@ -3862,53 +3881,74 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
38623881
case kIROp_AtomicLoad:
38633882
{
38643883
IRBuilder builder{inst};
3865-
const auto memoryScope =
3866-
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3867-
const auto memorySemantics =
3868-
emitMemorySemanticMask(inst->getOperand(1), inst->getOperand(0));
3869-
result = emitOpAtomicLoad(
3870-
parent,
3871-
inst,
3872-
inst->getFullType(),
3873-
inst->getOperand(0),
3874-
memoryScope,
3875-
memorySemantics);
3876-
ensureAtomicCapability(inst, SpvOpAtomicLoad);
3884+
if (isAtomicableAddressSpace(inst->getOperand(0)->getDataType()))
3885+
{
3886+
const auto memoryScope =
3887+
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3888+
const auto memorySemantics =
3889+
emitMemorySemanticMask(inst->getOperand(1), inst->getOperand(0));
3890+
result = emitOpAtomicLoad(
3891+
parent,
3892+
inst,
3893+
inst->getFullType(),
3894+
inst->getOperand(0),
3895+
memoryScope,
3896+
memorySemantics);
3897+
ensureAtomicCapability(inst, SpvOpAtomicLoad);
3898+
}
3899+
else
3900+
{
3901+
result = emitOpLoad(parent, inst, inst->getFullType(), inst->getOperand(0));
3902+
}
38773903
}
38783904
break;
38793905
case kIROp_AtomicStore:
38803906
{
38813907
IRBuilder builder{inst};
3882-
const auto memoryScope =
3883-
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3884-
const auto memorySemantics =
3885-
emitMemorySemanticMask(inst->getOperand(2), inst->getOperand(0));
3886-
result = emitOpAtomicStore(
3887-
parent,
3888-
inst,
3889-
inst->getOperand(0),
3890-
memoryScope,
3891-
memorySemantics,
3892-
inst->getOperand(1));
3893-
ensureAtomicCapability(inst, SpvOpAtomicStore);
3908+
if (isAtomicableAddressSpace(inst->getOperand(0)->getDataType()))
3909+
{
3910+
const auto memoryScope =
3911+
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3912+
const auto memorySemantics =
3913+
emitMemorySemanticMask(inst->getOperand(2), inst->getOperand(0));
3914+
result = emitOpAtomicStore(
3915+
parent,
3916+
inst,
3917+
inst->getOperand(0),
3918+
memoryScope,
3919+
memorySemantics,
3920+
inst->getOperand(1));
3921+
ensureAtomicCapability(inst, SpvOpAtomicStore);
3922+
}
3923+
else
3924+
{
3925+
result = emitOpStore(parent, inst, inst->getOperand(0), inst->getOperand(1));
3926+
}
38943927
}
38953928
break;
38963929
case kIROp_AtomicExchange:
38973930
{
38983931
IRBuilder builder{inst};
3899-
const auto memoryScope =
3900-
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3901-
const auto memorySemantics =
3902-
emitMemorySemanticMask(inst->getOperand(2), inst->getOperand(0));
3903-
result = emitOpAtomicExchange(
3904-
parent,
3905-
inst,
3906-
inst->getFullType(),
3907-
inst->getOperand(0),
3908-
memoryScope,
3909-
memorySemantics,
3910-
inst->getOperand(1));
3911-
ensureAtomicCapability(inst, SpvOpAtomicExchange);
3932+
if (isAtomicableAddressSpace(inst->getOperand(0)->getDataType()))
3933+
{
3934+
const auto memoryScope =
3935+
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3936+
const auto memorySemantics =
3937+
emitMemorySemanticMask(inst->getOperand(2), inst->getOperand(0));
3938+
result = emitOpAtomicExchange(
3939+
parent,
3940+
inst,
3941+
inst->getFullType(),
3942+
inst->getOperand(0),
3943+
memoryScope,
3944+
memorySemantics,
3945+
inst->getOperand(1));
3946+
ensureAtomicCapability(inst, SpvOpAtomicExchange);
3947+
}
3948+
else
3949+
{
3950+
result = emitOpStore(parent, inst, inst->getOperand(0), inst->getOperand(1));
3951+
}
39123952
}
39133953
break;
39143954
case kIROp_AtomicCompareExchange:
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//TEST:SIMPLE(filecheck=CHECK): -target spirv
2+
//CHECK: OpEntryPoint
3+
4+
struct Test {
5+
Atomic<int> test;
6+
}
7+
8+
RWStructuredBuffer<Test> data;
9+
10+
[shader("compute")]
11+
[numthreads(1,1,1)]
12+
public void main() {
13+
Test t = Test(1);
14+
data[0].test.increment();
15+
}

0 commit comments

Comments
 (0)