[llvm] [SPIR-V] Add SPV_INTEL_bfloat16_arithmetic for Opencl.std instructions with bfloat16 type (PR #205128)

Qi Ye via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 2 07:23:10 PDT 2026


https://github.com/Qi-Ye-079 updated https://github.com/llvm/llvm-project/pull/205128

>From 3ee072571d41e770cafcda9fc85aa15f37f9a266 Mon Sep 17 00:00:00 2001
From: "Ye, Qi" <qi.ye at intel.com>
Date: Thu, 18 Jun 2026 15:48:18 -0700
Subject: [PATCH 1/7] Check Opencl extended instructions with bfloat16 type

---
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 34 ++++++++-
 .../bfloat16-ocl-ext.ll                       | 72 +++++++++++++++++++
 2 files changed, 104 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index aed16fd785af8..13148b43f7e15 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -1660,8 +1660,38 @@ void addInstrRequirements(const MachineInstr &MI,
       addPrintfRequirements(MI, Reqs, ST);
       break;
     }
-    // TODO: handle bfloat16 extended instructions when
-    // SPV_INTEL_bfloat16_arithmetic is enabled.
+    if (MI.getOperand(2).getImm() ==
+        static_cast<int64_t>(SPIRV::InstructionSet::OpenCL_std)) {
+      MachineFunction *MF = const_cast<MachineFunction *>(MI.getMF());
+      const MachineRegisterInfo &MRI = MF->getRegInfo();
+      SPIRVGlobalRegistry *GR = ST.getSPIRVGlobalRegistry();
+
+      auto IsBFloat16 = [&](SPIRVTypeInst TypeDef) {
+        if (TypeDef && TypeDef->getOpcode() == SPIRV::OpTypeVector)
+          TypeDef = MRI.getVRegDef(TypeDef->getOperand(1).getReg());
+        return isBFloat16Type(TypeDef);
+      };
+
+      // Result type is operand 1; arguments start at operand 4.
+      bool UsesBFloat16 = IsBFloat16(MRI.getVRegDef(MI.getOperand(1).getReg()));
+      for (unsigned I = 4, E = MI.getNumOperands(); I < E && !UsesBFloat16;
+           ++I) {
+        const MachineOperand &MO = MI.getOperand(I);
+        if (MO.isReg())
+          UsesBFloat16 = IsBFloat16(GR->getResultType(MO.getReg(), MF));
+      }
+
+      // The OpenCL extended instruction set can operates on IEEE-754 encoding only
+      if (UsesBFloat16) {
+        if (!ST.canUseExtension(
+                SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
+          report_fatal_error(
+              "Extended instructions with bfloat16 arguments require the "
+              "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
+              false);
+        Reqs.addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
+      }
+    }
     break;
   }
   case SPIRV::OpAliasDomainDeclINTEL:
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
new file mode 100644
index 0000000000000..58fe98107eceb
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
@@ -0,0 +1,72 @@
+; Without SPV_INTEL_bfloat16_arithmetic: report error.
+; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_bfloat16 %s -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+; CHECK-ERROR: LLVM ERROR: Extended instructions with bfloat16 arguments require the following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic
+
+; With the extension: emit OpExtInst with OpExtension
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %s -o - | FileCheck %s --check-prefixes=COMMON,CHECK-FABS
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %s -o - | FileCheck %s --check-prefixes=COMMON,CHECK-FABSV
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %s -o - | FileCheck %s --check-prefixes=COMMON,CHECK-ILOGB
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %s -o - | FileCheck %s --check-prefixes=COMMON,CHECK-ILOGBV
+
+; TODO: re-enable spirv-val once it can verify SPV_INTEL_bfloat16_arithmetic with bfloat16 type on ExtInst
+; RUNx: %if spirv-tools %{ llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %s -o - -filetype=obj | spirv-val %}
+
+; COMMON-NOT: OpCapability BFloat16ArithmeticINTEL
+; COMMON-DAG: OpCapability BFloat16TypeKHR
+; COMMON-DAG: OpExtension "SPV_KHR_bfloat16"
+; COMMON-DAG: OpExtension "SPV_INTEL_bfloat16_arithmetic"
+; COMMON-DAG: [[EXTSET:%.*]] = OpExtInstImport "OpenCL.std"
+; COMMON-DAG: [[BFLOAT:%.*]] = OpTypeFloat 16 0
+
+; Scalar bfloat16 result and argument.
+; CHECK-FABS: OpFunction [[BFLOAT]]
+; CHECK-FABS: [[X:%.*]] = OpFunctionParameter [[BFLOAT]]
+; CHECK-FABS: OpExtInst [[BFLOAT]] [[EXTSET]] fabs [[X]]
+define spir_func bfloat @test_fabs(bfloat %x) {
+entry:
+  %r = call bfloat @llvm.fabs.bf16(bfloat %x)
+  ret bfloat %r
+}
+
+declare bfloat @llvm.fabs.bf16(bfloat)
+
+; Vector bfloat16 result and argument.
+; CHECK-FABSV-DAG: [[BFLOATV:%.*]] = OpTypeVector [[BFLOAT]] 4
+; CHECK-FABSV: OpFunction [[BFLOATV]]
+; CHECK-FABSV: [[XV:%.*]] = OpFunctionParameter [[BFLOATV]]
+; CHECK-FABSV: OpExtInst [[BFLOATV]] [[EXTSET]] fabs [[XV]]
+define spir_func <4 x bfloat> @test_fabsv(<4 x bfloat> %x) {
+entry:
+  %r = call <4 x bfloat> @llvm.fabs.v4bf16(<4 x bfloat> %x)
+  ret <4 x bfloat> %r
+}
+
+declare <4 x bfloat> @llvm.fabs.v4bf16(<4 x bfloat>)
+
+; A non-bfloat16 (i32) result with a bfloat16 argument.
+; CHECK-ILOGB-DAG: [[INT:%.*]] = OpTypeInt 32 0
+; CHECK-ILOGB: OpFunction [[INT]]
+; CHECK-ILOGB: [[XI:%.*]] = OpFunctionParameter [[BFLOAT]]
+; CHECK-ILOGB: OpExtInst [[INT]] [[EXTSET]] ilogb [[XI]]
+define spir_func i32 @test_ilogb(bfloat %x) {
+entry:
+  %r = call i32 @_Z5ilogbDh(bfloat %x)
+  ret i32 %r
+}
+
+declare i32 @_Z5ilogbDh(bfloat)
+
+; Vector version of ilogb test.
+; CHECK-ILOGBV-DAG: [[INT:%.*]] = OpTypeInt 32 0
+; CHECK-ILOGBV-DAG: [[INTV:%.*]] = OpTypeVector [[INT]] 4
+; CHECK-ILOGBV-DAG: [[BFLOATV:%.*]] = OpTypeVector [[BFLOAT]] 4
+; CHECK-ILOGBV: OpFunction [[INTV]]
+; CHECK-ILOGBV: [[XIV:%.*]] = OpFunctionParameter [[BFLOATV]]
+; CHECK-ILOGBV: OpExtInst [[INTV]] [[EXTSET]] ilogb [[XIV]]
+define spir_func <4 x i32> @test_ilogbv(<4 x bfloat> %x) {
+entry:
+  %r = call <4 x i32> @_Z5ilogbDv4_Dh(<4 x bfloat> %x)
+  ret <4 x i32> %r
+}
+
+declare <4 x i32> @_Z5ilogbDv4_Dh(<4 x bfloat>)
\ No newline at end of file

>From 888d30a29d9ebfa0fa027e7ac549b16601dd1d86 Mon Sep 17 00:00:00 2001
From: "Ye, Qi" <qi.ye at intel.com>
Date: Mon, 22 Jun 2026 13:08:12 -0700
Subject: [PATCH 2/7] fix formatting

---
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 13148b43f7e15..de3c5e52a9f01 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -1681,7 +1681,6 @@ void addInstrRequirements(const MachineInstr &MI,
           UsesBFloat16 = IsBFloat16(GR->getResultType(MO.getReg(), MF));
       }
 
-      // The OpenCL extended instruction set can operates on IEEE-754 encoding only
       if (UsesBFloat16) {
         if (!ST.canUseExtension(
                 SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))

>From 6b6160b69775ffb8169a1a28e2d2560f39df41fb Mon Sep 17 00:00:00 2001
From: "Ye, Qi" <qi.ye at intel.com>
Date: Mon, 22 Jun 2026 13:09:40 -0700
Subject: [PATCH 3/7] Add reportSupported and split test file into 2

---
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 21 ++++--
 .../bfloat16-ocl-ext.ll                       | 72 ++++++++-----------
 2 files changed, 45 insertions(+), 48 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index de3c5e52a9f01..acc4132ccab10 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -16,7 +16,8 @@
 
 // TODO: uses or report_fatal_error (which is also deprecated) /
 //       ReportFatalUsageError in this file should be refactored, as per LLVM
-//       best practices, to rely on the Diagnostic infrastructure.
+//       best practices, to rely on the Diagnostic infrastructure (such as the
+//       reportUnsupported function below).
 
 #include "SPIRVModuleAnalysis.h"
 #include "MCTargetDesc/SPIRVBaseInfo.h"
@@ -56,6 +57,12 @@ char llvm::SPIRVModuleAnalysis::ID = 0;
 INITIALIZE_PASS(SPIRVModuleAnalysis, DEBUG_TYPE, "SPIRV module analysis", true,
                 true)
 
+static void reportUnsupported(const MachineInstr &MI, const char *Msg) {
+  const Function &Func = MI.getMF()->getFunction();
+  Func.getContext().diagnose(
+      DiagnosticInfoUnsupported(Func, Msg, MI.getDebugLoc()));
+}
+
 // Retrieve an unsigned from an MDNode with a list of them as operands.
 static unsigned getMetadataUInt(MDNode *MdNode, unsigned OpIndex,
                                 unsigned DefaultVal = 0) {
@@ -1662,7 +1669,7 @@ void addInstrRequirements(const MachineInstr &MI,
     }
     if (MI.getOperand(2).getImm() ==
         static_cast<int64_t>(SPIRV::InstructionSet::OpenCL_std)) {
-      MachineFunction *MF = const_cast<MachineFunction *>(MI.getMF());
+      const MachineFunction *MF = MI.getMF();
       const MachineRegisterInfo &MRI = MF->getRegInfo();
       SPIRVGlobalRegistry *GR = ST.getSPIRVGlobalRegistry();
 
@@ -1678,16 +1685,16 @@ void addInstrRequirements(const MachineInstr &MI,
            ++I) {
         const MachineOperand &MO = MI.getOperand(I);
         if (MO.isReg())
-          UsesBFloat16 = IsBFloat16(GR->getResultType(MO.getReg(), MF));
+          UsesBFloat16 = IsBFloat16(GR->getResultType(
+              MO.getReg(), const_cast<MachineFunction *>(MF)));
       }
 
       if (UsesBFloat16) {
         if (!ST.canUseExtension(
                 SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
-          report_fatal_error(
-              "Extended instructions with bfloat16 arguments require the "
-              "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
-              false);
+          reportUnsupported(
+              MI, "OpenCL Extended instructions with bfloat16 require the "
+                  "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic");
         Reqs.addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
       }
     }
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
index 58fe98107eceb..c25a81ed81326 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
@@ -1,15 +1,21 @@
-; Without SPV_INTEL_bfloat16_arithmetic: report error.
-; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_bfloat16 %s -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
-; CHECK-ERROR: LLVM ERROR: Extended instructions with bfloat16 arguments require the following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic
+; RUN: split-file %s %t
 
-; With the extension: emit OpExtInst with OpExtension
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %s -o - | FileCheck %s --check-prefixes=COMMON,CHECK-FABS
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %s -o - | FileCheck %s --check-prefixes=COMMON,CHECK-FABSV
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %s -o - | FileCheck %s --check-prefixes=COMMON,CHECK-ILOGB
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %s -o - | FileCheck %s --check-prefixes=COMMON,CHECK-ILOGBV
+; RUN: not --crash llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_bfloat16 %t/bf16_result.ll -o /dev/null 2>&1 | FileCheck %s --check-prefix=RESULT-ERROR
+; RESULT-ERROR:      error: <unknown>:0:0: in function test_fabs bfloat (bfloat): OpenCL Extended instructions with bfloat16 require the
+; RESULT-ERROR-SAME:   following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic
+
+; RUN: not --crash llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_bfloat16 %t/bf16_operand.ll -o /dev/null 2>&1 | FileCheck %s --check-prefix=OPERAND-ERROR
+; OPERAND-ERROR:      error: <unknown>:0:0: in function test_ilogb i32 (bfloat): OpenCL Extended instructions with bfloat16 require the
+; OPERAND-ERROR-SAME:   following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic
+
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_result.ll -o - | FileCheck %s \
+; RUN:   --check-prefixes=COMMON,BF16_RESULT
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_operand.ll -o - | FileCheck %s \
+; RUN:   --check-prefixes=COMMON,BF16_OPERAND
 
 ; TODO: re-enable spirv-val once it can verify SPV_INTEL_bfloat16_arithmetic with bfloat16 type on ExtInst
-; RUNx: %if spirv-tools %{ llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %s -o - -filetype=obj | spirv-val %}
+; RUNx: %if spirv-tools %{ llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_result.ll -o - -filetype=obj | spirv-val %}
+; RUNx: %if spirv-tools %{ llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_operand.ll -o - -filetype=obj | spirv-val %}
 
 ; COMMON-NOT: OpCapability BFloat16ArithmeticINTEL
 ; COMMON-DAG: OpCapability BFloat16TypeKHR
@@ -18,55 +24,39 @@
 ; COMMON-DAG: [[EXTSET:%.*]] = OpExtInstImport "OpenCL.std"
 ; COMMON-DAG: [[BFLOAT:%.*]] = OpTypeFloat 16 0
 
-; Scalar bfloat16 result and argument.
-; CHECK-FABS: OpFunction [[BFLOAT]]
-; CHECK-FABS: [[X:%.*]] = OpFunctionParameter [[BFLOAT]]
-; CHECK-FABS: OpExtInst [[BFLOAT]] [[EXTSET]] fabs [[X]]
+; BF16_RESULT-DAG: [[BFLOATV:%.*]] = OpTypeVector [[BFLOAT]] 4
+; BF16_RESULT: OpExtInst [[BFLOAT]] [[EXTSET]] fabs
+; BF16_RESULT: OpExtInst [[BFLOATV]] [[EXTSET]] fabs
+
+; BF16_OPERAND-DAG: [[INT:%.*]] = OpTypeInt 32 0
+; BF16_OPERAND-DAG: [[INTV:%.*]] = OpTypeVector [[INT]] 4
+; BF16_OPERAND: OpExtInst [[INT]] [[EXTSET]] ilogb
+; BF16_OPERAND: OpExtInst [[INTV]] [[EXTSET]] ilogb
+
+;--- bf16_result.ll
 define spir_func bfloat @test_fabs(bfloat %x) {
-entry:
   %r = call bfloat @llvm.fabs.bf16(bfloat %x)
   ret bfloat %r
 }
 
-declare bfloat @llvm.fabs.bf16(bfloat)
-
-; Vector bfloat16 result and argument.
-; CHECK-FABSV-DAG: [[BFLOATV:%.*]] = OpTypeVector [[BFLOAT]] 4
-; CHECK-FABSV: OpFunction [[BFLOATV]]
-; CHECK-FABSV: [[XV:%.*]] = OpFunctionParameter [[BFLOATV]]
-; CHECK-FABSV: OpExtInst [[BFLOATV]] [[EXTSET]] fabs [[XV]]
 define spir_func <4 x bfloat> @test_fabsv(<4 x bfloat> %x) {
-entry:
   %r = call <4 x bfloat> @llvm.fabs.v4bf16(<4 x bfloat> %x)
   ret <4 x bfloat> %r
 }
 
+declare bfloat @llvm.fabs.bf16(bfloat)
 declare <4 x bfloat> @llvm.fabs.v4bf16(<4 x bfloat>)
 
-; A non-bfloat16 (i32) result with a bfloat16 argument.
-; CHECK-ILOGB-DAG: [[INT:%.*]] = OpTypeInt 32 0
-; CHECK-ILOGB: OpFunction [[INT]]
-; CHECK-ILOGB: [[XI:%.*]] = OpFunctionParameter [[BFLOAT]]
-; CHECK-ILOGB: OpExtInst [[INT]] [[EXTSET]] ilogb [[XI]]
+;--- bf16_operand.ll
 define spir_func i32 @test_ilogb(bfloat %x) {
-entry:
-  %r = call i32 @_Z5ilogbDh(bfloat %x)
+  %r = call i32 @_Z5ilogbDF16_(bfloat %x)
   ret i32 %r
 }
 
-declare i32 @_Z5ilogbDh(bfloat)
-
-; Vector version of ilogb test.
-; CHECK-ILOGBV-DAG: [[INT:%.*]] = OpTypeInt 32 0
-; CHECK-ILOGBV-DAG: [[INTV:%.*]] = OpTypeVector [[INT]] 4
-; CHECK-ILOGBV-DAG: [[BFLOATV:%.*]] = OpTypeVector [[BFLOAT]] 4
-; CHECK-ILOGBV: OpFunction [[INTV]]
-; CHECK-ILOGBV: [[XIV:%.*]] = OpFunctionParameter [[BFLOATV]]
-; CHECK-ILOGBV: OpExtInst [[INTV]] [[EXTSET]] ilogb [[XIV]]
 define spir_func <4 x i32> @test_ilogbv(<4 x bfloat> %x) {
-entry:
-  %r = call <4 x i32> @_Z5ilogbDv4_Dh(<4 x bfloat> %x)
+  %r = call <4 x i32> @_Z5ilogbDv4_DF16_(<4 x bfloat> %x)
   ret <4 x i32> %r
 }
 
-declare <4 x i32> @_Z5ilogbDv4_Dh(<4 x bfloat>)
\ No newline at end of file
+declare i32 @_Z5ilogbDF16_(bfloat)
+declare <4 x i32> @_Z5ilogbDv4_DF16_(<4 x bfloat>)

>From 34ecf3175a65eda2c29fa525d6bc1ac99b80296e Mon Sep 17 00:00:00 2001
From: Qi Ye <qi.ye at intel.com>
Date: Tue, 23 Jun 2026 15:38:35 -0400
Subject: [PATCH 4/7] Reformat RUN lines

Co-authored-by: Viktoria Maximova <viktoria.maksimova at intel.com>
---
 .../SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll       | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
index c25a81ed81326..fffc76e33223f 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
@@ -8,10 +8,8 @@
 ; OPERAND-ERROR:      error: <unknown>:0:0: in function test_ilogb i32 (bfloat): OpenCL Extended instructions with bfloat16 require the
 ; OPERAND-ERROR-SAME:   following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic
 
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_result.ll -o - | FileCheck %s \
-; RUN:   --check-prefixes=COMMON,BF16_RESULT
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_operand.ll -o - | FileCheck %s \
-; RUN:   --check-prefixes=COMMON,BF16_OPERAND
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_result.ll -o - | FileCheck %s --check-prefixes=COMMON,BF16_RESULT
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_operand.ll -o - | FileCheck %s --check-prefixes=COMMON,BF16_OPERAND
 
 ; TODO: re-enable spirv-val once it can verify SPV_INTEL_bfloat16_arithmetic with bfloat16 type on ExtInst
 ; RUNx: %if spirv-tools %{ llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_result.ll -o - -filetype=obj | spirv-val %}

>From 83581a24522cd5e09586b181a01b451011a36306 Mon Sep 17 00:00:00 2001
From: "Ye, Qi" <qi.ye at intel.com>
Date: Wed, 24 Jun 2026 09:18:28 -0700
Subject: [PATCH 5/7] Add capability

---
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp                   | 1 +
 .../SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll           | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index acc4132ccab10..cafbb31105dde 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -1696,6 +1696,7 @@ void addInstrRequirements(const MachineInstr &MI,
               MI, "OpenCL Extended instructions with bfloat16 require the "
                   "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic");
         Reqs.addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
+        Reqs.addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
       }
     }
     break;
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
index fffc76e33223f..d0d32c456cebd 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
@@ -15,7 +15,7 @@
 ; RUNx: %if spirv-tools %{ llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_result.ll -o - -filetype=obj | spirv-val %}
 ; RUNx: %if spirv-tools %{ llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_operand.ll -o - -filetype=obj | spirv-val %}
 
-; COMMON-NOT: OpCapability BFloat16ArithmeticINTEL
+; COMMON-DAG: OpCapability BFloat16ArithmeticINTEL
 ; COMMON-DAG: OpCapability BFloat16TypeKHR
 ; COMMON-DAG: OpExtension "SPV_KHR_bfloat16"
 ; COMMON-DAG: OpExtension "SPV_INTEL_bfloat16_arithmetic"

>From 4459e437bf89280babc49289ef3ed692081914a8 Mon Sep 17 00:00:00 2001
From: "Ye, Qi" <qi.ye at intel.com>
Date: Fri, 26 Jun 2026 14:10:38 -0700
Subject: [PATCH 6/7] Check vector type operand in test

---
 .../SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll      | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
index d0d32c456cebd..2e946fa55cc3d 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
@@ -28,8 +28,11 @@
 
 ; BF16_OPERAND-DAG: [[INT:%.*]] = OpTypeInt 32 0
 ; BF16_OPERAND-DAG: [[INTV:%.*]] = OpTypeVector [[INT]] 4
-; BF16_OPERAND: OpExtInst [[INT]] [[EXTSET]] ilogb
-; BF16_OPERAND: OpExtInst [[INTV]] [[EXTSET]] ilogb
+; BF16_OPERAND-DAG: [[BFLOATV:%.*]] = OpTypeVector [[BFLOAT]] 4
+; BF16_OPERAND: [[OP:%.*]] = OpFunctionParameter [[BFLOAT]]
+; BF16_OPERAND: OpExtInst [[INT]] [[EXTSET]] ilogb [[OP]]
+; BF16_OPERAND: [[OPV:%.*]] = OpFunctionParameter [[BFLOATV]]
+; BF16_OPERAND: OpExtInst [[INTV]] [[EXTSET]] ilogb [[OPV]]
 
 ;--- bf16_result.ll
 define spir_func bfloat @test_fabs(bfloat %x) {

>From 4a0b3ce30d20aa819b7eca4cc1124e090214e8f2 Mon Sep 17 00:00:00 2001
From: "Ye, Qi" <qi.ye at intel.com>
Date: Thu, 2 Jul 2026 07:22:41 -0700
Subject: [PATCH 7/7] Improve error handling and testcase

---
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 11 ++---
 .../bfloat16-ocl-ext.ll                       | 40 ++++++++++++++++---
 2 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index cafbb31105dde..ed2790bc8c696 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -14,10 +14,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-// TODO: uses or report_fatal_error (which is also deprecated) /
-//       ReportFatalUsageError in this file should be refactored, as per LLVM
-//       best practices, to rely on the Diagnostic infrastructure (such as the
-//       reportUnsupported function below).
+// TODO: Per LLVM best practices, the report_fatal_error (deprecated) /
+//       ReportFatalUsageError calls in this file should be replaced with the
+//       Diagnostic infrastructure (e.g. the reportUnsupported function below).
 
 #include "SPIRVModuleAnalysis.h"
 #include "MCTargetDesc/SPIRVBaseInfo.h"
@@ -1691,10 +1690,12 @@ void addInstrRequirements(const MachineInstr &MI,
 
       if (UsesBFloat16) {
         if (!ST.canUseExtension(
-                SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
+                SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic)) {
           reportUnsupported(
               MI, "OpenCL Extended instructions with bfloat16 require the "
                   "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic");
+          break;
+        }
         Reqs.addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
         Reqs.addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
       }
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
index 2e946fa55cc3d..476e7bac3000b 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bfloat16_arithmetic/bfloat16-ocl-ext.ll
@@ -1,17 +1,23 @@
 ; RUN: split-file %s %t
 
-; RUN: not --crash llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_bfloat16 %t/bf16_result.ll -o /dev/null 2>&1 | FileCheck %s --check-prefix=RESULT-ERROR
-; RESULT-ERROR:      error: <unknown>:0:0: in function test_fabs bfloat (bfloat): OpenCL Extended instructions with bfloat16 require the
+; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_bfloat16 %t/bf16_result_operand.ll -o /dev/null 2>&1 | FileCheck %s --check-prefix=RESULT-OPERAND-ERROR
+; RESULT-OPERAND-ERROR:      error: <unknown>:0:0: in function test_fabs bfloat (bfloat): OpenCL Extended instructions with bfloat16 require the
+; RESULT-OPERAND-ERROR-SAME:   following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic
+
+; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_bfloat16 %t/bf16_result.ll -o /dev/null 2>&1 | FileCheck %s --check-prefix=RESULT-ERROR
+; RESULT-ERROR:      error: <unknown>:0:0: in function test_nan bfloat (i16): OpenCL Extended instructions with bfloat16 require the
 ; RESULT-ERROR-SAME:   following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic
 
-; RUN: not --crash llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_bfloat16 %t/bf16_operand.ll -o /dev/null 2>&1 | FileCheck %s --check-prefix=OPERAND-ERROR
+; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_bfloat16 %t/bf16_operand.ll -o /dev/null 2>&1 | FileCheck %s --check-prefix=OPERAND-ERROR
 ; OPERAND-ERROR:      error: <unknown>:0:0: in function test_ilogb i32 (bfloat): OpenCL Extended instructions with bfloat16 require the
 ; OPERAND-ERROR-SAME:   following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic
 
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_result_operand.ll -o - | FileCheck %s --check-prefixes=COMMON,BF16_RESULT_OPERAND
 ; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_result.ll -o - | FileCheck %s --check-prefixes=COMMON,BF16_RESULT
 ; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_operand.ll -o - | FileCheck %s --check-prefixes=COMMON,BF16_OPERAND
 
 ; TODO: re-enable spirv-val once it can verify SPV_INTEL_bfloat16_arithmetic with bfloat16 type on ExtInst
+; RUNx: %if spirv-tools %{ llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_result_operand.ll -o - -filetype=obj | spirv-val %}
 ; RUNx: %if spirv-tools %{ llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_result.ll -o - -filetype=obj | spirv-val %}
 ; RUNx: %if spirv-tools %{ llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bfloat16_arithmetic,+SPV_KHR_bfloat16 %t/bf16_operand.ll -o - -filetype=obj | spirv-val %}
 
@@ -22,9 +28,17 @@
 ; COMMON-DAG: [[EXTSET:%.*]] = OpExtInstImport "OpenCL.std"
 ; COMMON-DAG: [[BFLOAT:%.*]] = OpTypeFloat 16 0
 
+; BF16_RESULT_OPERAND-DAG: [[BFLOATV:%.*]] = OpTypeVector [[BFLOAT]] 4
+; BF16_RESULT_OPERAND: OpExtInst [[BFLOAT]] [[EXTSET]] fabs
+; BF16_RESULT_OPERAND: OpExtInst [[BFLOATV]] [[EXTSET]] fabs
+
+; BF16_RESULT-DAG: [[INT:%.*]] = OpTypeInt 16 0
+; BF16_RESULT-DAG: [[INTV:%.*]] = OpTypeVector [[INT]] 4
 ; BF16_RESULT-DAG: [[BFLOATV:%.*]] = OpTypeVector [[BFLOAT]] 4
-; BF16_RESULT: OpExtInst [[BFLOAT]] [[EXTSET]] fabs
-; BF16_RESULT: OpExtInst [[BFLOATV]] [[EXTSET]] fabs
+; BF16_RESULT: [[OP:%.*]] = OpFunctionParameter [[INT]]
+; BF16_RESULT: OpExtInst [[BFLOAT]] [[EXTSET]] nan [[OP]]
+; BF16_RESULT: [[OPV:%.*]] = OpFunctionParameter [[INTV]]
+; BF16_RESULT: OpExtInst [[BFLOATV]] [[EXTSET]] nan [[OPV]]
 
 ; BF16_OPERAND-DAG: [[INT:%.*]] = OpTypeInt 32 0
 ; BF16_OPERAND-DAG: [[INTV:%.*]] = OpTypeVector [[INT]] 4
@@ -34,7 +48,7 @@
 ; BF16_OPERAND: [[OPV:%.*]] = OpFunctionParameter [[BFLOATV]]
 ; BF16_OPERAND: OpExtInst [[INTV]] [[EXTSET]] ilogb [[OPV]]
 
-;--- bf16_result.ll
+;--- bf16_result_operand.ll
 define spir_func bfloat @test_fabs(bfloat %x) {
   %r = call bfloat @llvm.fabs.bf16(bfloat %x)
   ret bfloat %r
@@ -48,6 +62,20 @@ define spir_func <4 x bfloat> @test_fabsv(<4 x bfloat> %x) {
 declare bfloat @llvm.fabs.bf16(bfloat)
 declare <4 x bfloat> @llvm.fabs.v4bf16(<4 x bfloat>)
 
+;--- bf16_result.ll
+define spir_func bfloat @test_nan(i16 %x) {
+  %r = call bfloat @_Z3nant(i16 %x)
+  ret bfloat %r
+}
+
+define spir_func <4 x bfloat> @test_nanv(<4 x i16> %x) {
+  %r = call <4 x bfloat> @_Z3nanDv4_t(<4 x i16> %x)
+  ret <4 x bfloat> %r
+}
+
+declare bfloat @_Z3nant(i16)
+declare <4 x bfloat> @_Z3nanDv4_t(<4 x i16>)
+
 ;--- bf16_operand.ll
 define spir_func i32 @test_ilogb(bfloat %x) {
   %r = call i32 @_Z5ilogbDF16_(bfloat %x)



More information about the llvm-commits mailing list