Skip to content

Commit 6e862bb

Browse files
authored
[SPIRV]: Emit missing storage class in atomic insts. (#6456)
1 parent 86669cb commit 6e862bb

File tree

2 files changed

+70
-17
lines changed

2 files changed

+70
-17
lines changed

source/slang/slang-emit-spirv.cpp

+54-17
Original file line numberDiff line numberDiff line change
@@ -3118,31 +3118,56 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
31183118
return (isSpirv16OrLater() || m_useDemoteToHelperInvocationExtension);
31193119
}
31203120

3121-
SpvInst* emitMemorySemanticMask(IRInst* inst)
3121+
SpvInst* emitMemorySemanticMask(IRInst* memoryOrderInst, IRInst* ptrInst)
31223122
{
3123-
IRBuilder builder(inst);
3124-
auto memoryOrder = (IRMemoryOrder)getIntVal(inst);
3125-
switch (memoryOrder)
3123+
IRBuilder builder(memoryOrderInst);
3124+
auto memoryOrder = (IRMemoryOrder)getIntVal(memoryOrderInst);
3125+
if (memoryOrder == kIRMemoryOrder_Relaxed)
31263126
{
3127-
case kIRMemoryOrder_Relaxed:
31283127
return emitIntConstant(
31293128
IRIntegerValue{SpvMemorySemanticsMaskNone},
31303129
builder.getUIntType());
3130+
}
3131+
uint32_t memoryClass = 0;
3132+
if (auto ptrType = as<IRPtrTypeBase>(ptrInst->getDataType()))
3133+
{
3134+
if (ptrType->hasAddressSpace())
3135+
{
3136+
switch (ptrType->getAddressSpace())
3137+
{
3138+
case AddressSpace::StorageBuffer:
3139+
case AddressSpace::UserPointer:
3140+
memoryClass = SpvMemorySemanticsUniformMemoryMask;
3141+
break;
3142+
case AddressSpace::Image:
3143+
memoryClass = SpvMemorySemanticsImageMemoryMask;
3144+
break;
3145+
case AddressSpace::Output:
3146+
memoryClass = SpvMemorySemanticsOutputMemoryKHRMask;
3147+
break;
3148+
case AddressSpace::GroupShared:
3149+
memoryClass = SpvMemorySemanticsWorkgroupMemoryMask;
3150+
break;
3151+
}
3152+
}
3153+
}
3154+
switch (memoryOrder)
3155+
{
31313156
case kIRMemoryOrder_Acquire:
31323157
return emitIntConstant(
3133-
IRIntegerValue{SpvMemorySemanticsAcquireMask},
3158+
IRIntegerValue{SpvMemorySemanticsAcquireMask | memoryClass},
31343159
builder.getUIntType());
31353160
case kIRMemoryOrder_Release:
31363161
return emitIntConstant(
3137-
IRIntegerValue{SpvMemorySemanticsReleaseMask},
3162+
IRIntegerValue{SpvMemorySemanticsReleaseMask | memoryClass},
31383163
builder.getUIntType());
31393164
case kIRMemoryOrder_AcquireRelease:
31403165
return emitIntConstant(
3141-
IRIntegerValue{SpvMemorySemanticsAcquireReleaseMask},
3166+
IRIntegerValue{SpvMemorySemanticsAcquireReleaseMask | memoryClass},
31423167
builder.getUIntType());
31433168
case kIRMemoryOrder_SeqCst:
31443169
return emitIntConstant(
3145-
IRIntegerValue{SpvMemorySemanticsSequentiallyConsistentMask},
3170+
IRIntegerValue{SpvMemorySemanticsSequentiallyConsistentMask | memoryClass},
31463171
builder.getUIntType());
31473172
default:
31483173
SLANG_UNEXPECTED("unhandled memory order");
@@ -3805,7 +3830,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
38053830
IRBuilder builder{inst};
38063831
const auto memoryScope =
38073832
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3808-
const auto memorySemantics = emitMemorySemanticMask(inst->getOperand(1));
3833+
const auto memorySemantics =
3834+
emitMemorySemanticMask(inst->getOperand(1), inst->getOperand(0));
38093835
result = emitOpAtomicIIncrement(
38103836
parent,
38113837
inst,
@@ -3821,7 +3847,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
38213847
IRBuilder builder{inst};
38223848
const auto memoryScope =
38233849
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3824-
const auto memorySemantics = emitMemorySemanticMask(inst->getOperand(1));
3850+
const auto memorySemantics =
3851+
emitMemorySemanticMask(inst->getOperand(1), inst->getOperand(0));
38253852
result = emitOpAtomicIDecrement(
38263853
parent,
38273854
inst,
@@ -3837,7 +3864,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
38373864
IRBuilder builder{inst};
38383865
const auto memoryScope =
38393866
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3840-
const auto memorySemantics = emitMemorySemanticMask(inst->getOperand(1));
3867+
const auto memorySemantics =
3868+
emitMemorySemanticMask(inst->getOperand(1), inst->getOperand(0));
38413869
result = emitOpAtomicLoad(
38423870
parent,
38433871
inst,
@@ -3853,7 +3881,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
38533881
IRBuilder builder{inst};
38543882
const auto memoryScope =
38553883
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3856-
const auto memorySemantics = emitMemorySemanticMask(inst->getOperand(2));
3884+
const auto memorySemantics =
3885+
emitMemorySemanticMask(inst->getOperand(2), inst->getOperand(0));
38573886
result = emitOpAtomicStore(
38583887
parent,
38593888
inst,
@@ -3869,7 +3898,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
38693898
IRBuilder builder{inst};
38703899
const auto memoryScope =
38713900
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3872-
const auto memorySemantics = emitMemorySemanticMask(inst->getOperand(2));
3901+
const auto memorySemantics =
3902+
emitMemorySemanticMask(inst->getOperand(2), inst->getOperand(0));
38733903
result = emitOpAtomicExchange(
38743904
parent,
38753905
inst,
@@ -3886,8 +3916,10 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
38863916
IRBuilder builder{inst};
38873917
const auto memoryScope =
38883918
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3889-
const auto memorySemanticsEqual = emitMemorySemanticMask(inst->getOperand(3));
3890-
const auto memorySemanticsUnequal = emitMemorySemanticMask(inst->getOperand(4));
3919+
const auto memorySemanticsEqual =
3920+
emitMemorySemanticMask(inst->getOperand(3), inst->getOperand(0));
3921+
const auto memorySemanticsUnequal =
3922+
emitMemorySemanticMask(inst->getOperand(4), inst->getOperand(0));
38913923
result = emitOpAtomicCompareExchange(
38923924
parent,
38933925
inst,
@@ -3912,7 +3944,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
39123944
IRBuilder builder{inst};
39133945
const auto memoryScope =
39143946
emitIntConstant(IRIntegerValue{SpvScopeDevice}, builder.getUIntType());
3915-
const auto memorySemantics = emitMemorySemanticMask(inst->getOperand(2));
3947+
const auto memorySemantics =
3948+
emitMemorySemanticMask(inst->getOperand(2), inst->getOperand(0));
39163949
bool negateOperand = false;
39173950
auto spvOp = getSpvAtomicOp(inst, negateOperand);
39183951
auto operand = inst->getOperand(1);
@@ -5309,6 +5342,10 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
53095342
{
53105343
return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInInstanceIndex, inst);
53115344
}
5345+
else if (semanticName == "sv_baseinstanceid")
5346+
{
5347+
return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInBaseInstance, inst);
5348+
}
53125349
else if (semanticName == "sv_isfrontface")
53135350
{
53145351
return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInFrontFacing, inst);

tests/spirv/atomic-memory-class.slang

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//TEST:SIMPLE(filecheck=CHECK): -target spirv
2+
3+
uniform Atomic<int>* pInt;
4+
RWStructuredBuffer<Atomic<int>> bInt;
5+
static groupshared Atomic<int> sInt;
6+
7+
[numthreads(4,1,1)]
8+
void computeMain()
9+
{
10+
// CHECK: OpAtomicLoad {{.*}} %uint_258
11+
// CHECK: OpAtomicStore {{.*}} %uint_68
12+
// CHECK: OpAtomicStore {{.*}} %uint_260
13+
let v = sInt.load(MemoryOrder.Acquire);
14+
pInt->store(v, MemoryOrder.Release);
15+
sInt.store(v, MemoryOrder.Release);
16+
}

0 commit comments

Comments
 (0)