[llvm] [SPIR-V] Add --spirv-fp-contract option to control kernel ContractionOff emission (PR #206404)

Arseniy Obolenskiy via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 29 05:43:55 PDT 2026


https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/206404

>From 3897c4359a44910f473c54f28bfba52bfc0f82c5 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Mon, 29 Jun 2026 08:04:57 +0200
Subject: [PATCH 1/2] [SPIR-V] Add --spirv-fp-contract option to control kernel
 ContractionOff emission

mirror the corresponding option from LLVM SPIR-V translator
---
 llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp     | 27 +++++++++++++++++--
 .../metadata/fp_contractions_metadata.ll      | 12 ++++++---
 .../metadata/no_fp_contractions_metadata.ll   | 12 ++++++---
 3 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
index f0296184dde49..30de972d4cd6b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
@@ -37,6 +37,7 @@
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -44,6 +45,22 @@ using namespace llvm;
 
 #define DEBUG_TYPE "asm-printer"
 
+namespace {
+enum class SPIRVFPContractMode { On, Off, Fast };
+} // namespace
+
+static cl::opt<SPIRVFPContractMode> SPIRVFPContract(
+    "spirv-fp-contract",
+    cl::desc("Override FP contraction policy for SPIR-V kernel entry points"),
+    cl::values(
+        clEnumValN(SPIRVFPContractMode::On, "on",
+                   "Follow IR metadata (default)"),
+        clEnumValN(SPIRVFPContractMode::Off, "off",
+                   "Force ContractionOff on all kernel entry points"),
+        clEnumValN(SPIRVFPContractMode::Fast, "fast",
+                   "Suppress ContractionOff on all kernel entry points")),
+    cl::init(SPIRVFPContractMode::On));
+
 namespace {
 class SPIRVAsmPrinter : public AsmPrinter {
   unsigned NLabels = 0;
@@ -643,8 +660,14 @@ void SPIRVAsmPrinter::outputExecutionMode(const Module &M) {
       Inst.addOperand(MCOperand::createImm(EM));
       outputMCInst(Inst);
     }
-    if (ST->isKernel() && !M.getNamedMetadata("spirv.ExecutionMode") &&
-        !M.getNamedMetadata("opencl.enable.FP_CONTRACT")) {
+    // --spirv-fp-contract=off forces to emit ContractionOff for this kernel
+    // entry point, --spirv-fp-contract=fast suppresses it.
+    bool EmitContractionOff =
+        ST->isKernel() && !M.getNamedMetadata("spirv.ExecutionMode") &&
+        SPIRVFPContract != SPIRVFPContractMode::Fast &&
+        (SPIRVFPContract == SPIRVFPContractMode::Off ||
+         !M.getNamedMetadata("opencl.enable.FP_CONTRACT"));
+    if (EmitContractionOff) {
       if (ST->canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
         // When SPV_KHR_float_controls2 is enabled, ContractionOff is
         // deprecated. We need to use FPFastMathDefault with the appropriate
diff --git a/llvm/test/CodeGen/SPIRV/opencl/metadata/fp_contractions_metadata.ll b/llvm/test/CodeGen/SPIRV/opencl/metadata/fp_contractions_metadata.ll
index 2b4c0bd8670e2..4bdf907bba135 100644
--- a/llvm/test/CodeGen/SPIRV/opencl/metadata/fp_contractions_metadata.ll
+++ b/llvm/test/CodeGen/SPIRV/opencl/metadata/fp_contractions_metadata.ll
@@ -1,8 +1,14 @@
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-DEFAULT
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-fp-contract=on %s -o - | FileCheck %s --check-prefix=CHECK-DEFAULT
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-fp-contract=fast %s -o - | FileCheck %s --check-prefix=CHECK-DEFAULT
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-fp-contract=off %s -o - | FileCheck %s --check-prefix=CHECK-OFF
 ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
-; CHECK: OpEntryPoint Kernel %[[#ENTRY:]] "foo"
-; CHECK-NOT: OpExecutionMode %[[#ENTRY]] ContractionOff
+; CHECK-DEFAULT: OpEntryPoint Kernel %[[#ENTRY:]] "foo"
+; CHECK-DEFAULT-NOT: OpExecutionMode %[[#ENTRY]] ContractionOff
+
+; CHECK-OFF: OpEntryPoint Kernel %[[#ENTRY:]] "foo"
+; CHECK-OFF: OpExecutionMode %[[#ENTRY]] ContractionOff
 define spir_kernel void @foo() {
 entry:
   ret void
diff --git a/llvm/test/CodeGen/SPIRV/opencl/metadata/no_fp_contractions_metadata.ll b/llvm/test/CodeGen/SPIRV/opencl/metadata/no_fp_contractions_metadata.ll
index dcceb9d3e3ccc..ebee07eb1529a 100644
--- a/llvm/test/CodeGen/SPIRV/opencl/metadata/no_fp_contractions_metadata.ll
+++ b/llvm/test/CodeGen/SPIRV/opencl/metadata/no_fp_contractions_metadata.ll
@@ -1,8 +1,14 @@
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-DEFAULT
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-fp-contract=on %s -o - | FileCheck %s --check-prefix=CHECK-DEFAULT
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-fp-contract=off %s -o - | FileCheck %s --check-prefix=CHECK-DEFAULT
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-fp-contract=fast %s -o - | FileCheck %s --check-prefix=CHECK-FAST
 ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
-; CHECK: OpEntryPoint Kernel %[[#ENTRY:]] "foo"
-; CHECK: OpExecutionMode %[[#ENTRY]] ContractionOff
+; CHECK-DEFAULT: OpEntryPoint Kernel %[[#ENTRY:]] "foo"
+; CHECK-DEFAULT: OpExecutionMode %[[#ENTRY]] ContractionOff
+
+; CHECK-FAST: OpEntryPoint Kernel %[[#ENTRY:]] "foo"
+; CHECK-FAST-NOT: OpExecutionMode %[[#ENTRY]] ContractionOff
 define spir_kernel void @foo() {
 entry:
   ret void

>From 18cb1adc700486cece8a6c24a7b8da2720731d1a Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <gooddoog at student.su>
Date: Mon, 29 Jun 2026 14:43:46 +0200
Subject: [PATCH 2/2] Update llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Juan Manuel Martinez CaamaƱo <jmartinezcaamao at gmail.com>
---
 llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
index 30de972d4cd6b..2a5d16a470c4a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
@@ -47,7 +47,6 @@ using namespace llvm;
 
 namespace {
 enum class SPIRVFPContractMode { On, Off, Fast };
-} // namespace
 
 static cl::opt<SPIRVFPContractMode> SPIRVFPContract(
     "spirv-fp-contract",
@@ -61,7 +60,6 @@ static cl::opt<SPIRVFPContractMode> SPIRVFPContract(
                    "Suppress ContractionOff on all kernel entry points")),
     cl::init(SPIRVFPContractMode::On));
 
-namespace {
 class SPIRVAsmPrinter : public AsmPrinter {
   unsigned NLabels = 0;
   SmallPtrSet<const MachineBasicBlock *, 8> LabeledMBB;



More information about the llvm-commits mailing list