@@ -2964,8 +2964,16 @@ class SPIRVAtomicInstBase : public SPIRVInstTemplateBase {
29642964 // Besides, OpAtomicCompareExchangeWeak, OpAtomicFlagTestAndSet and
29652965 // OpAtomicFlagClear instructions require the "kernel" capability. But this
29662966 // capability should be added by setting the OpenCL memory model.
2967- if (hasType () && getType ()->isTypeInt (64 ))
2968- return {CapabilityInt64Atomics};
2967+ if (hasType ()) {
2968+ if (getType ()->isTypeInt (64 ))
2969+ return {CapabilityInt64Atomics};
2970+ if (getType ()->isTypeInt (16 ) &&
2971+ Module->isAllowedToUseExtension (
2972+ ExtensionID::SPV_INTEL_16bit_atomics)) {
2973+ Module->addExtension (ExtensionID::SPV_INTEL_16bit_atomics);
2974+ return {internal::CapabilityInt16AtomicsINTEL};
2975+ }
2976+ }
29692977 return {};
29702978 }
29712979
@@ -3003,7 +3011,24 @@ class SPIRVAtomicInstBase : public SPIRVInstTemplateBase {
30033011 }
30043012};
30053013
3006- class SPIRVAtomicStoreInst : public SPIRVAtomicInstBase {
3014+ // This specialization will handle smaller set of compare-and-swap instructions
3015+ // that require only one capability. The instructions are: OpAtomicLoad,
3016+ // OpAtomicStore, OpAtomicExchange, OpAtomicCompareExchange and
3017+ // OpAtomicCompareExchangeWeak.
3018+ class SPIRVAtomicCompareExchangeInstructions : public SPIRVAtomicInstBase {
3019+ public:
3020+ SPIRVCapVec getRequiredCapability () const override {
3021+ if (hasType () && getType ()->isTypeInt (16 ) &&
3022+ this ->getModule ()->isAllowedToUseExtension (
3023+ ExtensionID::SPV_INTEL_16bit_atomics)) {
3024+ Module->addExtension (ExtensionID::SPV_INTEL_16bit_atomics);
3025+ return {internal::CapabilityAtomicInt16CompareExchangeINTEL};
3026+ }
3027+ return SPIRVAtomicInstBase::getRequiredCapability ();
3028+ }
3029+ };
3030+
3031+ class SPIRVAtomicStoreInst : public SPIRVAtomicCompareExchangeInstructions {
30073032public:
30083033 // Overriding the following method because of 'const'-related
30093034 // issues with overriding getRequiredCapability(). TODO: Resolve.
@@ -3020,7 +3045,7 @@ class SPIRVAtomicFAddEXTInst : public SPIRVAtomicInstBase {
30203045 std::optional<ExtensionID> getRequiredExtension () const override {
30213046 assert (hasType ());
30223047 if (getType ()->isTypeFloat (16 , FPEncodingBFloat16KHR))
3023- return ExtensionID::SPV_INTEL_shader_atomic_bfloat16 ;
3048+ Module-> addExtension ( ExtensionID::SPV_INTEL_16bit_atomics) ;
30243049 if (getType ()->isTypeFloat (16 ))
30253050 return ExtensionID::SPV_EXT_shader_atomic_float16_add;
30263051 return ExtensionID::SPV_EXT_shader_atomic_float_add;
@@ -3045,7 +3070,7 @@ class SPIRVAtomicFMinMaxEXTBase : public SPIRVAtomicInstBase {
30453070public:
30463071 std::optional<ExtensionID> getRequiredExtension () const override {
30473072 if (getType ()->isTypeFloat (16 , FPEncodingBFloat16KHR))
3048- return ExtensionID::SPV_INTEL_shader_atomic_bfloat16 ;
3073+ Module-> addExtension ( ExtensionID::SPV_INTEL_16bit_atomics) ;
30493074 return ExtensionID::SPV_EXT_shader_atomic_float_min_max;
30503075 }
30513076
@@ -3069,10 +3094,6 @@ class SPIRVAtomicFMinMaxEXTBase : public SPIRVAtomicInstBase {
30693094// Atomic builtins
30703095_SPIRV_OP (AtomicFlagTestAndSet, true , 6 )
30713096_SPIRV_OP(AtomicFlagClear, false , 4 )
3072- _SPIRV_OP(AtomicLoad, true , 6 )
3073- _SPIRV_OP(AtomicExchange, true , 7 )
3074- _SPIRV_OP(AtomicCompareExchange, true , 9 )
3075- _SPIRV_OP(AtomicCompareExchangeWeak, true , 9 )
30763097_SPIRV_OP(AtomicIIncrement, true , 6 )
30773098_SPIRV_OP(AtomicIDecrement, true , 6 )
30783099_SPIRV_OP(AtomicIAdd, true , 7 )
@@ -3089,7 +3110,11 @@ _SPIRV_OP(MemoryBarrier, false, 3)
30893110#define _SPIRV_OP (x, BaseClass, ...) \
30903111 typedef SPIRVInstTemplate<SPIRV##BaseClass, Op##x, __VA_ARGS__> SPIRV##x;
30913112// Specialized atomic builtins
3113+ _SPIRV_OP (AtomicLoad, AtomicCompareExchangeInstructions, true , 6 )
30923114_SPIRV_OP(AtomicStore, AtomicStoreInst, false , 5 )
3115+ _SPIRV_OP(AtomicExchange, AtomicCompareExchangeInstructions, true , 7 )
3116+ _SPIRV_OP(AtomicCompareExchange, AtomicCompareExchangeInstructions, true , 9 )
3117+ _SPIRV_OP(AtomicCompareExchangeWeak, AtomicCompareExchangeInstructions, true , 9 )
30933118_SPIRV_OP(AtomicFAddEXT, AtomicFAddEXTInst, true , 7 )
30943119_SPIRV_OP(AtomicFMinEXT, AtomicFMinMaxEXTBase, true , 7 )
30953120_SPIRV_OP(AtomicFMaxEXT, AtomicFMinMaxEXTBase, true , 7 )
0 commit comments