[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