[llvm] [SPIR-V] Derive FPFastMathMode from nofpclass attributes on OpenCL builtins (PR #188984)

Arseniy Obolenskiy via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 31 04:28:26 PDT 2026


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

>From b0744caad93184a7ecf6575b5cd1a80791fc79c5 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Fri, 27 Mar 2026 13:09:33 +0100
Subject: [PATCH 1/6] [SPIR-V] Derive FPFastMathMode from nofpclass attributes
 on OpenCL builtins

Translate nofpclass(nan/inf) attributes on OpenCL extended instruction calls into MI flags and after that to SPIR-V OpDecorate
---
 llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp       | 19 ++++++++++
 .../SPIRV/opencl/nofpclass-fastmath.ll        | 36 +++++++++++++++++++
 2 files changed, 55 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 9b6b2c721ec2c..0240087fd65a5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -1279,6 +1279,25 @@ static bool generateExtInst(const SPIRV::IncomingCall *Call,
     MIB.getInstr()->setFlag(MachineInstr::MIFlag::FmNoNans);
     MIB.getInstr()->setFlag(MachineInstr::MIFlag::FmNoInfs);
   }
+
+  // Derive fast-math flags from nofpclass attributes on the called function.
+  if (const Function *F = CB.getCalledFunction()) {
+    bool AddNoNan = !!(CB.getRetNoFPClass() & fcNan);
+    bool AddNoInf = !!(CB.getRetNoFPClass() & fcInf);
+    for (unsigned I = 0, E = F->getFunctionType()->getNumParams();
+         I != E && (AddNoNan || AddNoInf); ++I) {
+      if (!F->getFunctionType()->getParamType(I)->isFloatingPointTy())
+        continue;
+      FPClassTest ArgTest = CB.getParamNoFPClass(I);
+      AddNoNan = AddNoNan && !!(ArgTest & fcNan);
+      AddNoInf = AddNoInf && !!(ArgTest & fcInf);
+    }
+    if (AddNoNan)
+      MIB.getInstr()->setFlag(MachineInstr::MIFlag::FmNoNans);
+    if (AddNoInf)
+      MIB.getInstr()->setFlag(MachineInstr::MIFlag::FmNoInfs);
+  }
+
   return true;
 }
 
diff --git a/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll
new file mode 100644
index 0000000000000..808a5867e14d0
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll
@@ -0,0 +1,36 @@
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_float_controls2 %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_float_controls2 %s -o - -filetype=obj | spirv-val %}
+
+; Check that nofpclass attributes on OpenCL builtin calls are translated to
+; FPFastMathMode decorations on the corresponding OpExtInst instructions.
+
+; CHECK-DAG: OpDecorate %[[#FMAX_RES:]] FPFastMathMode NotNaN|NotInf
+; CHECK-DAG: OpDecorate %[[#FMIN_RES:]] FPFastMathMode NotInf
+; CHECK-DAG: OpDecorate %[[#LDEXP_RES:]] FPFastMathMode NotNaN|NotInf
+
+; CHECK: %[[#FMAX_RES]] = OpExtInst %[[#]] %[[#]] fmax
+; CHECK: %[[#FMIN_RES]] = OpExtInst %[[#]] %[[#]] fmin
+; CHECK: %[[#LDEXP_RES]] = OpExtInst %[[#]] %[[#]] ldexp
+
+; nofpclass(nan inf) on return and all float params -> NotNaN|NotInf
+declare spir_func noundef nofpclass(nan inf) float @_Z16__spirv_ocl_fmaxff(float noundef nofpclass(nan inf), float noundef nofpclass(nan inf))
+
+; nofpclass(inf) on first param only, nofpclass(nan inf) on second -> NotInf
+declare spir_func noundef nofpclass(nan inf) float @_Z16__spirv_ocl_fminff(float noundef nofpclass(inf), float noundef nofpclass(nan inf))
+
+; nofpclass(nan inf) on return and float param, i32 param skipped -> NotNaN|NotInf
+declare spir_func noundef nofpclass(nan inf) float @_Z17__spirv_ocl_ldexpfi(float noundef nofpclass(nan inf), i32 noundef)
+
+define spir_kernel void @test(ptr addrspace(1) %data, ptr addrspace(1) %a, ptr addrspace(1) %b) {
+entry:
+  %0 = load float, ptr addrspace(1) %a, align 4
+  %1 = load float, ptr addrspace(1) %b, align 4
+  %fmax = call spir_func noundef nofpclass(nan inf) float @_Z16__spirv_ocl_fmaxff(float noundef nofpclass(nan inf) %0, float noundef nofpclass(nan inf) %1)
+  store float %fmax, ptr addrspace(1) %data, align 4
+  %fmin = call spir_func noundef nofpclass(nan inf) float @_Z16__spirv_ocl_fminff(float noundef nofpclass(inf) %0, float noundef nofpclass(nan inf) %1)
+  store float %fmin, ptr addrspace(1) %data, align 4
+  %2 = load i32, ptr addrspace(1) %b, align 4
+  %ldexp = call spir_func noundef nofpclass(nan inf) float @_Z17__spirv_ocl_ldexpfi(float noundef nofpclass(nan inf) %0, i32 noundef %2)
+  store float %ldexp, ptr addrspace(1) %data, align 4
+  ret void
+}

>From 95223d6aea78888826b61c5b77b792c5198aac5b Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Fri, 27 Mar 2026 18:14:39 +0100
Subject: [PATCH 2/6] Address review comments

---
 llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp       | 31 ++++++++++---------
 .../opencl/nofpclass-fastmath-negative.ll     | 17 ++++++++++
 .../SPIRV/opencl/nofpclass-fastmath.ll        |  2 +-
 3 files changed, 35 insertions(+), 15 deletions(-)
 create mode 100644 llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-negative.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 0240087fd65a5..e5fca973dded5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -1281,21 +1281,24 @@ static bool generateExtInst(const SPIRV::IncomingCall *Call,
   }
 
   // Derive fast-math flags from nofpclass attributes on the called function.
-  if (const Function *F = CB.getCalledFunction()) {
-    bool AddNoNan = !!(CB.getRetNoFPClass() & fcNan);
-    bool AddNoInf = !!(CB.getRetNoFPClass() & fcInf);
-    for (unsigned I = 0, E = F->getFunctionType()->getNumParams();
-         I != E && (AddNoNan || AddNoInf); ++I) {
-      if (!F->getFunctionType()->getParamType(I)->isFloatingPointTy())
-        continue;
-      FPClassTest ArgTest = CB.getParamNoFPClass(I);
-      AddNoNan = AddNoNan && !!(ArgTest & fcNan);
-      AddNoInf = AddNoInf && !!(ArgTest & fcInf);
+  if (ST.isKernel() &&
+      ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
+    if (const Function *F = CB.getCalledFunction()) {
+      bool AddNoNan = !!(CB.getRetNoFPClass() & fcNan);
+      bool AddNoInf = !!(CB.getRetNoFPClass() & fcInf);
+      for (unsigned I = 0, E = F->getFunctionType()->getNumParams();
+           I != E && (AddNoNan || AddNoInf); ++I) {
+        if (!F->getFunctionType()->getParamType(I)->isFloatingPointTy())
+          continue;
+        FPClassTest ArgTest = CB.getParamNoFPClass(I);
+        AddNoNan = AddNoNan && !!(ArgTest & fcNan);
+        AddNoInf = AddNoInf && !!(ArgTest & fcInf);
+      }
+      if (AddNoNan)
+        MIB.getInstr()->setFlag(MachineInstr::MIFlag::FmNoNans);
+      if (AddNoInf)
+        MIB.getInstr()->setFlag(MachineInstr::MIFlag::FmNoInfs);
     }
-    if (AddNoNan)
-      MIB.getInstr()->setFlag(MachineInstr::MIFlag::FmNoNans);
-    if (AddNoInf)
-      MIB.getInstr()->setFlag(MachineInstr::MIFlag::FmNoInfs);
   }
 
   return true;
diff --git a/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-negative.ll b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-negative.ll
new file mode 100644
index 0000000000000..458d32208bd40
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-negative.ll
@@ -0,0 +1,17 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64v1.5-unknown-unknown %s -o - | FileCheck %s
+
+; Negative test: nofpclass attributes should NOT produce FPFastMathMode
+; decorations on OpExtInst when SPIR-V version < 1.6 and the
+; SPV_KHR_float_controls2 extension is not enabled.
+
+; CHECK-NOT: FPFastMathMode
+
+declare spir_func noundef nofpclass(nan inf) float @_Z16__spirv_ocl_fmaxff(float noundef nofpclass(nan inf), float noundef nofpclass(nan inf))
+
+define spir_kernel void @test(ptr addrspace(1) %data, ptr addrspace(1) %a) {
+entry:
+  %0 = load float, ptr addrspace(1) %a, align 4
+  %fmax = call spir_func noundef nofpclass(nan inf) float @_Z16__spirv_ocl_fmaxff(float noundef nofpclass(nan inf) %0, float noundef nofpclass(nan inf) %0)
+  store float %fmax, ptr addrspace(1) %data, align 4
+  ret void
+}
diff --git a/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll
index 808a5867e14d0..6f62de0548622 100644
--- a/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll
+++ b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll
@@ -1,4 +1,4 @@
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_float_controls2 %s -o - | FileCheck %s
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_float_controls2 %s -o - | FileCheck %s
 ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_float_controls2 %s -o - -filetype=obj | spirv-val %}
 
 ; Check that nofpclass attributes on OpenCL builtin calls are translated to

>From 8a19f7f047aa71733fa70fc2896714c81aba5fae Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Mon, 30 Mar 2026 10:51:37 +0200
Subject: [PATCH 3/6] Apply suggestion

---
 llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index e5fca973dded5..44a1b94bb4015 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -1286,9 +1286,10 @@ static bool generateExtInst(const SPIRV::IncomingCall *Call,
     if (const Function *F = CB.getCalledFunction()) {
       bool AddNoNan = !!(CB.getRetNoFPClass() & fcNan);
       bool AddNoInf = !!(CB.getRetNoFPClass() & fcInf);
-      for (unsigned I = 0, E = F->getFunctionType()->getNumParams();
+      FunctionType *FTy = F->getFunctionType();
+      for (unsigned I = 0, E = FTy->getNumParams();
            I != E && (AddNoNan || AddNoInf); ++I) {
-        if (!F->getFunctionType()->getParamType(I)->isFloatingPointTy())
+        if (!FTy->getParamType(I)->isFloatingPointTy())
           continue;
         FPClassTest ArgTest = CB.getParamNoFPClass(I);
         AddNoNan = AddNoNan && !!(ArgTest & fcNan);

>From cf0f5b2065d59b76dc992bf4e1d1c5cb873c7ef5 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Mon, 30 Mar 2026 12:46:54 +0200
Subject: [PATCH 4/6] Address review comments

---
 llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp                  | 4 +++-
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp            | 9 +++++++--
 ...th-negative.ll => nofpclass-fastmath-kernel-pre16.ll} | 8 ++++----
 llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll     | 7 +++++--
 4 files changed, 19 insertions(+), 9 deletions(-)
 rename llvm/test/CodeGen/SPIRV/opencl/{nofpclass-fastmath-negative.ll => nofpclass-fastmath-kernel-pre16.ll} (69%)

diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 44a1b94bb4015..61a0762ebe75a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -1281,7 +1281,9 @@ static bool generateExtInst(const SPIRV::IncomingCall *Call,
   }
 
   // Derive fast-math flags from nofpclass attributes on the called function.
-  if (ST.isKernel() &&
+  // FPFastMathMode decoration is valid on ExtInst in Kernel environments
+  // (SPIR-V core) or with SPV_KHR_float_controls2 for any environment.
+  if (ST.isKernel() ||
       ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
     if (const Function *F = CB.getCalledFunction()) {
       bool AddNoNan = !!(CB.getRetNoFPClass() & fcNan);
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 6bd2eb552a936..26dd34b7d573f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -2648,8 +2648,13 @@ static void handleMIFlagDecoration(
     buildOpDecorate(I.getOperand(0).getReg(), I, TII,
                     SPIRV::Decoration::NoUnsignedWrap, {});
   }
-  if (!TII.canUseFastMathFlags(
-          I, ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)))
+  // In Kernel environments, FPFastMathMode on OpExtInst is valid per core
+  // spec. For other instruction types, SPV_KHR_float_controls2 is required.
+  bool CanUseFM =
+      TII.canUseFastMathFlags(
+          I, ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) ||
+      (ST.isKernel() && I.getOpcode() == SPIRV::OpExtInst);
+  if (!CanUseFM)
     return;
 
   unsigned FMFlags = getFastMathFlags(I, ST);
diff --git a/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-negative.ll b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-kernel-pre16.ll
similarity index 69%
rename from llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-negative.ll
rename to llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-kernel-pre16.ll
index 458d32208bd40..b6c6dc93bb848 100644
--- a/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-negative.ll
+++ b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-kernel-pre16.ll
@@ -1,10 +1,10 @@
 ; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64v1.5-unknown-unknown %s -o - | FileCheck %s
 
-; Negative test: nofpclass attributes should NOT produce FPFastMathMode
-; decorations on OpExtInst when SPIR-V version < 1.6 and the
-; SPV_KHR_float_controls2 extension is not enabled.
+; Check that nofpclass attributes produce FPFastMathMode decorations on
+; OpExtInst in Kernel environments even for SPIR-V versions before 1.6,
+; because the Kernel capability makes FPFastMathMode available.
 
-; CHECK-NOT: FPFastMathMode
+; CHECK: OpDecorate %[[#]] FPFastMathMode NotNaN|NotInf
 
 declare spir_func noundef nofpclass(nan inf) float @_Z16__spirv_ocl_fmaxff(float noundef nofpclass(nan inf), float noundef nofpclass(nan inf))
 
diff --git a/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll
index 6f62de0548622..c0982027d40c0 100644
--- a/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll
+++ b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath.ll
@@ -1,5 +1,8 @@
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_float_controls2 %s -o - | FileCheck %s
-; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_float_controls2 %s -o - -filetype=obj | spirv-val %}
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64v1.5-unknown-unknown --spirv-ext=+SPV_KHR_float_controls2 %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64v1.5-unknown-unknown --spirv-ext=+SPV_KHR_float_controls2 %s -o - -filetype=obj | spirv-val %}
 
 ; Check that nofpclass attributes on OpenCL builtin calls are translated to
 ; FPFastMathMode decorations on the corresponding OpExtInst instructions.

>From f5d97c28a5567a0c6fcf8a720f97d064ff07097c Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Mon, 30 Mar 2026 15:31:49 +0200
Subject: [PATCH 5/6] remove git s

---
 llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 61a0762ebe75a..21ca1be62938e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -1286,16 +1286,16 @@ static bool generateExtInst(const SPIRV::IncomingCall *Call,
   if (ST.isKernel() ||
       ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
     if (const Function *F = CB.getCalledFunction()) {
-      bool AddNoNan = !!(CB.getRetNoFPClass() & fcNan);
-      bool AddNoInf = !!(CB.getRetNoFPClass() & fcInf);
+      bool AddNoNan = CB.getRetNoFPClass() & fcNan;
+      bool AddNoInf = CB.getRetNoFPClass() & fcInf;
       FunctionType *FTy = F->getFunctionType();
       for (unsigned I = 0, E = FTy->getNumParams();
            I != E && (AddNoNan || AddNoInf); ++I) {
         if (!FTy->getParamType(I)->isFloatingPointTy())
           continue;
         FPClassTest ArgTest = CB.getParamNoFPClass(I);
-        AddNoNan = AddNoNan && !!(ArgTest & fcNan);
-        AddNoInf = AddNoInf && !!(ArgTest & fcInf);
+        AddNoNan = AddNoNan && ArgTest & fcNan;
+        AddNoInf = AddNoInf && ArgTest & fcInf;
       }
       if (AddNoNan)
         MIB.getInstr()->setFlag(MachineInstr::MIFlag::FmNoNans);

>From 68f5cde7503a037eaf992560dc632c56f250e017 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Tue, 31 Mar 2026 13:28:12 +0200
Subject: [PATCH 6/6] Address review comments

---
 .../opencl/nofpclass-fastmath-kernel-pre16.ll |  1 +
 .../opencl/nofpclass-fastmath-non-extinst.ll  | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-non-extinst.ll

diff --git a/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-kernel-pre16.ll b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-kernel-pre16.ll
index b6c6dc93bb848..839dd3877d767 100644
--- a/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-kernel-pre16.ll
+++ b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-kernel-pre16.ll
@@ -1,4 +1,5 @@
 ; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64v1.5-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64v1.5-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
 ; Check that nofpclass attributes produce FPFastMathMode decorations on
 ; OpExtInst in Kernel environments even for SPIR-V versions before 1.6,
diff --git a/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-non-extinst.ll b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-non-extinst.ll
new file mode 100644
index 0000000000000..199c47c9c8d5c
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/opencl/nofpclass-fastmath-non-extinst.ll
@@ -0,0 +1,19 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64v1.5-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64v1.5-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; Check that nofpclass attributes on non-OpExtInst instructions (regular
+; function calls) do NOT produce FPFastMathMode decorations in Kernel
+; environments before SPIR-V 1.6 without SPV_KHR_float_controls2.
+
+; CHECK-NOT: FPFastMathMode
+; CHECK:     OpFunctionCall
+
+declare spir_func noundef nofpclass(nan inf) float @regular_func(float noundef nofpclass(nan inf))
+
+define spir_kernel void @test(ptr addrspace(1) %data, ptr addrspace(1) %a) {
+entry:
+  %0 = load float, ptr addrspace(1) %a, align 4
+  %reg = call spir_func noundef nofpclass(nan inf) float @regular_func(float noundef nofpclass(nan inf) %0)
+  store float %reg, ptr addrspace(1) %data, align 4
+  ret void
+}



More information about the llvm-commits mailing list