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 = !{!"", !""}