@@ -2827,8 +2827,16 @@ class SPIRVAtomicInstBase : public SPIRVInstTemplateBase {
28272827 // Besides, OpAtomicCompareExchangeWeak, OpAtomicFlagTestAndSet and
28282828 // OpAtomicFlagClear instructions require the "kernel" capability. But this
28292829 // capability should be added by setting the OpenCL memory model.
2830- if (hasType () && getType ()->isTypeInt (64 ))
2831- return {CapabilityInt64Atomics};
2830+ if (hasType ()) {
2831+ if (getType ()->isTypeInt (64 ))
2832+ return {CapabilityInt64Atomics};
2833+ if (getType ()->isTypeInt (16 ) &&
2834+ Module->isAllowedToUseExtension (
2835+ ExtensionID::SPV_INTEL_16bit_atomics)) {
2836+ Module->addExtension (ExtensionID::SPV_INTEL_16bit_atomics);
2837+ return {internal::CapabilityInt16AtomicsINTEL};
2838+ }
2839+ }
28322840 return {};
28332841 }
28342842
@@ -2842,7 +2850,24 @@ class SPIRVAtomicInstBase : public SPIRVInstTemplateBase {
28422850 }
28432851};
28442852
2845- class SPIRVAtomicStoreInst : public SPIRVAtomicInstBase {
2853+ // This specialization will handle smaller set of compare-and-swap instructions
2854+ // that require only one capability. The instructions are: OpAtomicLoad,
2855+ // OpAtomicStore, OpAtomicExchange, OpAtomicCompareExchange and
2856+ // OpAtomicCompareExchangeWeak.
2857+ class SPIRVAtomicCompareExchangeInstructions : public SPIRVAtomicInstBase {
2858+ public:
2859+ SPIRVCapVec getRequiredCapability () const override {
2860+ if (hasType () && getType ()->isTypeInt (16 ) &&
2861+ this ->getModule ()->isAllowedToUseExtension (
2862+ ExtensionID::SPV_INTEL_16bit_atomics)) {
2863+ Module->addExtension (ExtensionID::SPV_INTEL_16bit_atomics);
2864+ return {internal::CapabilityAtomicInt16CompareExchangeINTEL};
2865+ }
2866+ return SPIRVAtomicInstBase::getRequiredCapability ();
2867+ }
2868+ };
2869+
2870+ class SPIRVAtomicStoreInst : public SPIRVAtomicCompareExchangeInstructions {
28462871public:
28472872 // Overriding the following method because of 'const'-related
28482873 // issues with overriding getRequiredCapability(). TODO: Resolve.
@@ -2859,7 +2884,7 @@ class SPIRVAtomicFAddEXTInst : public SPIRVAtomicInstBase {
28592884 std::optional<ExtensionID> getRequiredExtension () const override {
28602885 assert (hasType ());
28612886 if (getType ()->isTypeFloat (16 , FPEncodingBFloat16KHR))
2862- return ExtensionID::SPV_INTEL_shader_atomic_bfloat16 ;
2887+ Module-> addExtension ( ExtensionID::SPV_INTEL_16bit_atomics) ;
28632888 if (getType ()->isTypeFloat (16 ))
28642889 return ExtensionID::SPV_EXT_shader_atomic_float16_add;
28652890 return ExtensionID::SPV_EXT_shader_atomic_float_add;
@@ -2884,7 +2909,7 @@ class SPIRVAtomicFMinMaxEXTBase : public SPIRVAtomicInstBase {
28842909public:
28852910 std::optional<ExtensionID> getRequiredExtension () const override {
28862911 if (getType ()->isTypeFloat (16 , FPEncodingBFloat16KHR))
2887- return ExtensionID::SPV_INTEL_shader_atomic_bfloat16 ;
2912+ Module-> addExtension ( ExtensionID::SPV_INTEL_16bit_atomics) ;
28882913 return ExtensionID::SPV_EXT_shader_atomic_float_min_max;
28892914 }
28902915
@@ -2908,10 +2933,6 @@ class SPIRVAtomicFMinMaxEXTBase : public SPIRVAtomicInstBase {
29082933// Atomic builtins
29092934_SPIRV_OP (AtomicFlagTestAndSet, true , 6 )
29102935_SPIRV_OP(AtomicFlagClear, false , 4 )
2911- _SPIRV_OP(AtomicLoad, true , 6 )
2912- _SPIRV_OP(AtomicExchange, true , 7 )
2913- _SPIRV_OP(AtomicCompareExchange, true , 9 )
2914- _SPIRV_OP(AtomicCompareExchangeWeak, true , 9 )
29152936_SPIRV_OP(AtomicIIncrement, true , 6 )
29162937_SPIRV_OP(AtomicIDecrement, true , 6 )
29172938_SPIRV_OP(AtomicIAdd, true , 7 )
@@ -2928,7 +2949,11 @@ _SPIRV_OP(MemoryBarrier, false, 3)
29282949#define _SPIRV_OP (x, BaseClass, ...) \
29292950 typedef SPIRVInstTemplate<SPIRV ##BaseClass, Op##x, __VA_ARGS__> SPIRV ##x;
29302951// Specialized atomic builtins
2952+ _SPIRV_OP (AtomicLoad, AtomicCompareExchangeInstructions, true , 6 )
29312953_SPIRV_OP(AtomicStore, AtomicStoreInst, false , 5 )
2954+ _SPIRV_OP(AtomicExchange, AtomicCompareExchangeInstructions, true , 7 )
2955+ _SPIRV_OP(AtomicCompareExchange, AtomicCompareExchangeInstructions, true , 9 )
2956+ _SPIRV_OP(AtomicCompareExchangeWeak, AtomicCompareExchangeInstructions, true , 9 )
29322957_SPIRV_OP(AtomicFAddEXT, AtomicFAddEXTInst, true , 7 )
29332958_SPIRV_OP(AtomicFMinEXT, AtomicFMinMaxEXTBase, true , 7 )
29342959_SPIRV_OP(AtomicFMaxEXT, AtomicFMinMaxEXTBase, true , 7 )
0 commit comments