From 1f3d9ab295bf1e2646c5cef762aca7822fd73897 Mon Sep 17 00:00:00 2001 From: Mochalova Anastasiya Date: Mon, 30 Nov 2020 17:17:28 +0300 Subject: [PATCH] Add support for SPV_INTEL_fp_fast_math_mode (#822) Spec: https://github.com/KhronosGroup/SPIRV-Registry/pull/85 Signed-off-by: amochalo --- include/LLVMSPIRVExtensions.inc | 1 + lib/SPIRV/SPIRVReader.cpp | 4 ++ lib/SPIRV/SPIRVWriter.cpp | 11 ++++ lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h | 1 + lib/SPIRV/libSPIRV/spirv.hpp | 3 + .../fp_contract_reassoc_fast_mode.ll | 56 +++++++++++++++++++ 6 files changed, 76 insertions(+) create mode 100644 test/transcoding/fp_contract_reassoc_fast_mode.ll diff --git a/include/LLVMSPIRVExtensions.inc b/include/LLVMSPIRVExtensions.inc index 276807f337..9bd4a44a43 100644 --- a/include/LLVMSPIRVExtensions.inc +++ b/include/LLVMSPIRVExtensions.inc @@ -28,3 +28,4 @@ EXT(SPV_INTEL_fpga_buffer_location) EXT(SPV_INTEL_arbitrary_precision_fixed_point) EXT(SPV_INTEL_arbitrary_precision_floating_point) EXT(SPV_INTEL_variable_length_array) +EXT(SPV_INTEL_fp_fast_math_mode) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 2db8916b90..47f1bdc237 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -1129,6 +1129,10 @@ static void applyFPFastMathModeDecorations(const SPIRVValue *BV, FMF.setNoSignedZeros(); if (V & FPFastMathModeAllowRecipMask) FMF.setAllowReciprocal(); + if (V & FPFastMathModeAllowContractINTELMask) + FMF.setAllowContract(); + if (V & FPFastMathModeAllowReassocINTELMask) + FMF.setAllowReassoc(); if (V & FPFastMathModeFastMask) FMF.setFast(); Inst->setFastMathFlags(FMF); diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index af4448b243..54ee686a93 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -1690,6 +1690,17 @@ bool LLVMToSPIRV::transDecoration(Value *V, SPIRVValue *BV) { M |= FPFastMathModeNSZMask; if (FMF.allowReciprocal()) M |= FPFastMathModeAllowRecipMask; + if (BM->isAllowedToUseExtension( + ExtensionID::SPV_INTEL_fp_fast_math_mode)) { + if (FMF.allowContract()) { + M |= FPFastMathModeAllowContractINTELMask; + BM->addCapability(CapabilityFPFastMathModeINTEL); + } + if (FMF.allowReassoc()) { + M |= FPFastMathModeAllowReassocINTELMask; + BM->addCapability(CapabilityFPFastMathModeINTEL); + } + } } if (M != 0) BV->setFPFastMathMode(M); diff --git a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h index 9636c92c35..97fd901432 100644 --- a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h @@ -485,6 +485,7 @@ template <> inline void SPIRVMap::init() { add(CapabilityVariableLengthArrayINTEL, "VariableLengthArrayINTEL"); add(CapabilityFunctionFloatControlINTEL, "FunctionFloatControlINTEL"); add(CapabilityFPGAMemoryAttributesINTEL, "FPGAMemoryAttributesINTEL"); + add(CapabilityFPFastMathModeINTEL, "FPFastMathModeINTEL"); add(CapabilityArbitraryPrecisionIntegersINTEL, "ArbitraryPrecisionIntegersINTEL"); add(CapabilityArbitraryPrecisionFloatingPointINTEL, diff --git a/lib/SPIRV/libSPIRV/spirv.hpp b/lib/SPIRV/libSPIRV/spirv.hpp index fb593cc0cb..828b09be7c 100644 --- a/lib/SPIRV/libSPIRV/spirv.hpp +++ b/lib/SPIRV/libSPIRV/spirv.hpp @@ -376,6 +376,8 @@ enum FPFastMathModeMask { FPFastMathModeNotInfMask = 0x00000002, FPFastMathModeNSZMask = 0x00000004, FPFastMathModeAllowRecipMask = 0x00000008, + FPFastMathModeAllowContractINTELMask = 0x00010000, + FPFastMathModeAllowReassocINTELMask = 0x00020000, FPFastMathModeFastMask = 0x00000010, }; @@ -972,6 +974,7 @@ enum Capability { CapabilityVariableLengthArrayINTEL = 5817, CapabilityFunctionFloatControlINTEL = 5821, CapabilityFPGAMemoryAttributesINTEL = 5824, + CapabilityFPFastMathModeINTEL = 5837, CapabilityArbitraryPrecisionIntegersINTEL = 5844, CapabilityArbitraryPrecisionFloatingPointINTEL = 5845, CapabilityUnstructuredLoopControlsINTEL = 5886, diff --git a/test/transcoding/fp_contract_reassoc_fast_mode.ll b/test/transcoding/fp_contract_reassoc_fast_mode.ll new file mode 100644 index 0000000000..351654c639 --- /dev/null +++ b/test/transcoding/fp_contract_reassoc_fast_mode.ll @@ -0,0 +1,56 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv -spirv-text %t.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV-OFF +; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_fp_fast_math_mode -spirv-text %t.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV-ON +; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_fp_fast_math_mode %t.bc -o %t.spv +; RUN: llvm-spirv -r %t.spv -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK-LLVM + +; CHECK-SPIRV-ON: 2 Capability FPFastMathModeINTEL +; CHECK-SPIRV-ON: 3 Name [[mu:[0-9]+]] "mul" +; CHECK-SPIRV-ON: 3 Name [[su:[0-9]+]] "sub" +; CHECK-SPIRV-ON: 4 Decorate [[mu]] FPFastMathMode 65536 +; CHECK-SPIRV-ON: 4 Decorate [[su]] FPFastMathMode 131072 + +; CHECK-SPIRV-OFF-NOT: 2 Capability FPFastMathModeINTEL +; CHECK-SPIRV-OFF: 3 Name [[mu:[0-9]+]] "mul" +; CHECK-SPIRV-OFF: 3 Name [[su:[0-9]+]] "sub" +; CHECK-SPIRV-OFF-NOT: 4 Decorate [[mu]] FPFastMathMode 65536 +; CHECK-SPIRV-OFF-NOT: 4 Decorate [[su]] FPFastMathMode 131072 + +; CHECK-LLVM: %mul = fmul contract float %0, %1 +; CHECK-LLVM: %sub = fsub reassoc float %2, %3 + +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir" + +; Function Attrs: convergent noinline norecurse nounwind optnone +define spir_kernel void @test(float %a, float %b) #0 !kernel_arg_addr_space !3 !kernel_arg_access_qual !4 !kernel_arg_type !5 !kernel_arg_base_type !5 !kernel_arg_type_qual !6 { +entry: + %a.addr = alloca float, align 4 + %b.addr = alloca float, align 4 + store float %a, float* %a.addr, align 4 + store float %b, float* %b.addr, align 4 + %0 = load float, float* %a.addr, align 4 + %1 = load float, float* %a.addr, align 4 + %mul = fmul contract float %0, %1 + store float %mul, float* %b.addr, align 4 + %2 = load float, float* %b.addr, align 4 + %3 = load float, float* %b.addr, align 4 + %sub = fsub reassoc float %2, %3 + store float %sub, float* %b.addr, align 4 + ret void +} + +attributes #0 = { convergent noinline norecurse nounwind optnone "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "uniform-work-group-size"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!opencl.ocl.version = !{!1} +!opencl.spir.version = !{!1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 2, i32 0} +!2 = !{!"clang version 12.0.0 (https://github.com/intel/llvm.git 5cf8088c994778561c8584d5433d7d32618725b2)"} +!3 = !{i32 0, i32 0} +!4 = !{!"none", !"none"} +!5 = !{!"float", !"float"} +!6 = !{!"", !""}