@@ -3407,6 +3407,25 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
3407
3407
return emitOpBitcast (parent, inst, inst->getDataType (), vec);
3408
3408
}
3409
3409
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
+
3410
3429
// The instructions that appear inside the basic blocks of
3411
3430
// functions are what we will call "local" instructions.
3412
3431
//
@@ -3862,53 +3881,74 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
3862
3881
case kIROp_AtomicLoad :
3863
3882
{
3864
3883
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
+ }
3877
3903
}
3878
3904
break ;
3879
3905
case kIROp_AtomicStore :
3880
3906
{
3881
3907
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
+ }
3894
3927
}
3895
3928
break ;
3896
3929
case kIROp_AtomicExchange :
3897
3930
{
3898
3931
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
+ }
3912
3952
}
3913
3953
break ;
3914
3954
case kIROp_AtomicCompareExchange :
0 commit comments