From a35a761c18874dfe0326edeac4ce009ed29c8682 Mon Sep 17 00:00:00 2001 From: Ben Ashbaugh Date: Mon, 13 Jan 2025 03:11:31 -0800 Subject: [PATCH] adds support for SPV_EXT_arithmetic_fence (#2954) bashbaug Member bashbaug commented 4 days ago See: https://github.khronos.org/SPIRV-Registry/extensions/EXT/SPV_EXT_arithmetic_fence.html Removes all internal enums for the unpublished SPV_INTEL_arithmetic_fence extension and uses the SPV_EXT_arithmetic_fence support in the headers instead. Registers the SPV_EXT_arithmetic_fence extension. Uses the SPV_EXT_arithmetic_fence extension if it is enabled, otherwise uses the SPV_INTEL_arithmetic_fence extension if it is enabled (for compatibility), otherwise ignores the LLVM arithmetic fence intrinsic (the ignoring part is not new). Updates the arithmetic fence test: Ensures that the right extension support is declared, depending on the enabled extensions. Ensures that the ArithmeticFenceEXT capability is declared when either extension is enabled. Note, the spelling for the capability is unconditionally the EXT version. Ensures that the OpArithmeticFenceEXT is present when either extension is enabled. Ensures that no extension, capability, or instruction is generated when neither extension is enabled. --- include/LLVMSPIRVExtensions.inc | 1 + lib/SPIRV/SPIRVReader.cpp | 2 +- lib/SPIRV/SPIRVWriter.cpp | 11 +++++-- lib/SPIRV/libSPIRV/SPIRVInstruction.h | 4 +-- lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h | 2 +- lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h | 1 + lib/SPIRV/libSPIRV/SPIRVOpCodeEnumInternal.h | 1 - lib/SPIRV/libSPIRV/spirv_internal.hpp | 5 ---- .../arithmetic_fence.ll | 30 ++++++++++++------- 9 files changed, 34 insertions(+), 23 deletions(-) diff --git a/include/LLVMSPIRVExtensions.inc b/include/LLVMSPIRVExtensions.inc index 1a256b912..fa5c5bed6 100644 --- a/include/LLVMSPIRVExtensions.inc +++ b/include/LLVMSPIRVExtensions.inc @@ -54,6 +54,7 @@ EXT(SPV_INTEL_fpga_invocation_pipelining_attributes) EXT(SPV_INTEL_token_type) EXT(SPV_INTEL_debug_module) EXT(SPV_INTEL_runtime_aligned) +EXT(SPV_EXT_arithmetic_fence) EXT(SPV_INTEL_arithmetic_fence) EXT(SPV_INTEL_bfloat16_conversion) EXT(SPV_INTEL_joint_matrix) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 78cbbe55f..0d7161cd3 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -2910,7 +2910,7 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, return mapValue( BV, transArbFloatInst(static_cast(BV), BB, true)); - case internal::OpArithmeticFenceINTEL: { + case OpArithmeticFenceEXT: { IRBuilder<> Builder(BB); auto *BC = static_cast(BV); Type *RetTy = transType(BC->getType()); diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index ff0f56f89..594844e99 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -4930,10 +4930,17 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II, case Intrinsic::arithmetic_fence: { SPIRVType *Ty = transType(II->getType()); SPIRVValue *Op = transValue(II->getArgOperand(0), BB); + if (BM->isAllowedToUseExtension(ExtensionID::SPV_EXT_arithmetic_fence)) { + BM->addCapability(CapabilityArithmeticFenceEXT); + BM->addExtension(ExtensionID::SPV_EXT_arithmetic_fence); + return BM->addUnaryInst(OpArithmeticFenceEXT, Ty, Op, BB); + } if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_arithmetic_fence)) { - BM->addCapability(internal::CapabilityFPArithmeticFenceINTEL); + // Note: SPV_INTEL_arithmetic_fence was unpublished and superseded by + // SPV_EXT_arithmetic_fence. + BM->addCapability(CapabilityArithmeticFenceEXT); BM->addExtension(ExtensionID::SPV_INTEL_arithmetic_fence); - return BM->addUnaryInst(internal::OpArithmeticFenceINTEL, Ty, Op, BB); + return BM->addUnaryInst(OpArithmeticFenceEXT, Ty, Op, BB); } return Op; } diff --git a/lib/SPIRV/libSPIRV/SPIRVInstruction.h b/lib/SPIRV/libSPIRV/SPIRVInstruction.h index ab40d0829..f8b2ff35c 100644 --- a/lib/SPIRV/libSPIRV/SPIRVInstruction.h +++ b/lib/SPIRV/libSPIRV/SPIRVInstruction.h @@ -1707,10 +1707,8 @@ _SPIRV_OP(SignBitSet) _SPIRV_OP(Any) _SPIRV_OP(All) _SPIRV_OP(BitCount) +_SPIRV_OP(ArithmeticFenceEXT) #undef _SPIRV_OP -#define _SPIRV_OP_INTERNAL(x) typedef SPIRVUnaryInst SPIRV##x; -_SPIRV_OP_INTERNAL(ArithmeticFenceINTEL) -#undef _SPIRV_OP_INTERNAL class SPIRVAccessChainBase : public SPIRVInstTemplateBase { public: diff --git a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h index 8ec0f2b06..c2c6cb50c 100644 --- a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h @@ -640,10 +640,10 @@ template <> inline void SPIRVMap::init() { add(CapabilityFPGALatencyControlINTEL, "FPGALatencyControlINTEL"); add(CapabilityFPMaxErrorINTEL, "FPMaxErrorINTEL"); add(CapabilityRegisterLimitsINTEL, "RegisterLimitsINTEL"); + add(CapabilityArithmeticFenceEXT, "ArithmeticFenceEXT"); // From spirv_internal.hpp add(internal::CapabilityFastCompositeINTEL, "FastCompositeINTEL"); add(internal::CapabilityTokenTypeINTEL, "TokenTypeINTEL"); - add(internal::CapabilityFPArithmeticFenceINTEL, "FPArithmeticFenceINTEL"); add(internal::CapabilityBfloat16ConversionINTEL, "Bfloat16ConversionINTEL"); add(internal::CapabilityJointMatrixINTEL, "JointMatrixINTEL"); add(internal::CapabilityHWThreadQueryINTEL, "HWThreadQueryINTEL"); diff --git a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h index 1f0ffc457..9b6646c4b 100644 --- a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h @@ -570,6 +570,7 @@ _SPIRV_OP(ConstantCompositeContinuedINTEL, 6091) _SPIRV_OP(SpecConstantCompositeContinuedINTEL, 6092) _SPIRV_OP(ControlBarrierArriveINTEL, 6142) _SPIRV_OP(ControlBarrierWaitINTEL, 6143) +_SPIRV_OP(ArithmeticFenceEXT, 6145) _SPIRV_OP(GroupIMulKHR, 6401) _SPIRV_OP(GroupFMulKHR, 6402) _SPIRV_OP(GroupBitwiseAndKHR, 6403) diff --git a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnumInternal.h b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnumInternal.h index 5317be2f8..72f95d66a 100644 --- a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnumInternal.h +++ b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnumInternal.h @@ -2,7 +2,6 @@ _SPIRV_OP_INTERNAL(Forward, internal::OpForward) _SPIRV_OP_INTERNAL(TypeTokenINTEL, internal::OpTypeTokenINTEL) -_SPIRV_OP_INTERNAL(ArithmeticFenceINTEL, internal::OpArithmeticFenceINTEL) _SPIRV_OP_INTERNAL(ConvertFToBF16INTEL, internal::OpConvertFToBF16INTEL) _SPIRV_OP_INTERNAL(ConvertBF16ToFINTEL, internal::OpConvertBF16ToFINTEL) _SPIRV_OP_INTERNAL(TypeJointMatrixINTEL, internal::OpTypeJointMatrixINTEL) diff --git a/lib/SPIRV/libSPIRV/spirv_internal.hpp b/lib/SPIRV/libSPIRV/spirv_internal.hpp index d796e7e0d..d147c68f8 100644 --- a/lib/SPIRV/libSPIRV/spirv_internal.hpp +++ b/lib/SPIRV/libSPIRV/spirv_internal.hpp @@ -68,7 +68,6 @@ enum InternalOp { IOpJointMatrixSUMadINTEL = 6128, IOpJointMatrixUSMadINTEL = 6129, IOpJointMatrixUUMadINTEL = 6130, - IOpArithmeticFenceINTEL = 6145, IOpTaskSequenceCreateINTEL = 6163, IOpTaskSequenceAsyncINTEL = 6164, IOpTaskSequenceGetINTEL = 6165, @@ -111,7 +110,6 @@ enum InternalCapability { ICapBfloat16ConversionINTEL = 6115, ICapabilityJointMatrixINTEL = 6118, ICapabilityHWThreadQueryINTEL = 6134, - ICapFPArithmeticFenceINTEL = 6144, ICapGlobalVariableDecorationsINTEL = 6146, ICapabilityTaskSequenceINTEL = 6162, ICapabilityCooperativeMatrixCheckedInstructionsINTEL = 6192, @@ -269,7 +267,6 @@ constexpr SourceLanguage SourceLanguageCPP20 = constexpr Op OpForward = static_cast(IOpForward); constexpr Op OpTypeTokenINTEL = static_cast(IOpTypeTokenINTEL); -constexpr Op OpArithmeticFenceINTEL = static_cast(IOpArithmeticFenceINTEL); constexpr Op OpConvertFToBF16INTEL = static_cast(IOpConvertFToBF16INTEL); constexpr Op OpConvertBF16ToFINTEL = static_cast(IOpConvertBF16ToFINTEL); @@ -290,8 +287,6 @@ constexpr Capability CapabilityFastCompositeINTEL = static_cast(ICapFastCompositeINTEL); constexpr Capability CapabilityTokenTypeINTEL = static_cast(ICapTokenTypeINTEL); -constexpr Capability CapabilityFPArithmeticFenceINTEL = - static_cast(ICapFPArithmeticFenceINTEL); constexpr Capability CapabilityBfloat16ConversionINTEL = static_cast(ICapBfloat16ConversionINTEL); constexpr Capability CapabilityGlobalVariableDecorationsINTEL = diff --git a/test/extensions/INTEL/SPV_INTEL_arithmetic_fence/arithmetic_fence.ll b/test/extensions/INTEL/SPV_INTEL_arithmetic_fence/arithmetic_fence.ll index 3d90fba03..98b11a0c3 100644 --- a/test/extensions/INTEL/SPV_INTEL_arithmetic_fence/arithmetic_fence.ll +++ b/test/extensions/INTEL/SPV_INTEL_arithmetic_fence/arithmetic_fence.ll @@ -1,32 +1,42 @@ ; RUN: llvm-as %s -o %t.bc -; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_arithmetic_fence -o %t.spv -; RUN: llvm-spirv %t.spv --to-text -o %t.spt -; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV +; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_EXT_arithmetic_fence -spirv-text -o - | FileCheck %s --check-prefixes=CHECK-SPIRV-EXT,CHECK-SPIRV +; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_arithmetic_fence -spirv-text -o - | FileCheck %s --check-prefixes=CHECK-SPIRV-INTEL,CHECK-SPIRV +; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_EXT_arithmetic_fence,+SPV_INTEL_arithmetic_fence -spirv-text -o - | FileCheck %s --check-prefixes=CHECK-SPIRV-EXT,CHECK-SPIRV + +; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_EXT_arithmetic_fence -o %t.spv ; RUN: llvm-spirv -r %t.spv -o %t.rev.bc ; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM + ; RUN: llvm-spirv %t.bc -o %t.negative.spv -; RUN: llvm-spirv %t.negative.spv --to-text -o %t.negative.spt -; RUN: FileCheck < %t.negative.spt %s --check-prefix=CHECK-SPIRV-NEG +; RUN: llvm-spirv %t.negative.spv --to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV-NEG + ; RUN: llvm-spirv -r %t.negative.spv -o %t.negative.rev.bc ; RUN: llvm-dis < %t.negative.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM-NEG -; CHECK-SPIRV: Capability FPArithmeticFenceINTEL -; CHECK-SPIRV: Extension "SPV_INTEL_arithmetic_fence" + +; Note: The capability is unconditionally printed with the EXT suffix. +; CHECK-SPIRV: Capability ArithmeticFenceEXT + +; CHECK-SPIRV-EXT: Extension "SPV_EXT_arithmetic_fence" +; CHECK-SPIRV-INTEL: Extension "SPV_INTEL_arithmetic_fence" + ; CHECK-SPIRV: Name [[#Res:]] "t" ; CHECK-SPIRV: TypeFloat [[#ResTy:]] 64 ; CHECK-SPIRV: FAdd [[#ResTy]] [[#Target:]] -; CHECK-SPIRV: ArithmeticFenceINTEL [[#ResTy]] [[#Res]] [[#Target]] +; Note: The instruction is unconditional printed with the EXT suffix. +; CHECK-SPIRV: ArithmeticFenceEXT [[#ResTy]] [[#Res]] [[#Target]] ; CHECK-LLVM: [[#Op:]] = fadd fast double %a, %a ; CHECK-LLVM: %t = call double @llvm.arithmetic.fence.f64(double %[[#Op]]) ; CHECK-LLVM: declare double @llvm.arithmetic.fence.f64(double) -; CHECK-SPIRV-NEG-NOT: Capability FPArithmeticFenceINTEL +; CHECK-SPIRV-NEG-NOT: Capability ArithmeticFenceEXT +; CHECK-SPIRV-NEG-NOT: Extension "SPV_EXT_arithmetic_fence" ; CHECK-SPIRV-NEG-NOT: Extension "SPV_INTEL_arithmetic_fence" -; CHECK-SPIRV-NEG-NOT: ArithmeticFenceINTEL +; CHECK-SPIRV-NEG-NOT: ArithmeticFenceEXT ; CHECK-LLVM-NEG-NOT: declare double @llvm.arithmetic.fence.f64(double)