[Mlir-commits] [mlir] [MLIR][NVVM] Add `nvvm.cos` OP (PR #193792)
Guray Ozen
llvmlistbot at llvm.org
Fri Apr 24 03:35:16 PDT 2026
https://github.com/grypp updated https://github.com/llvm/llvm-project/pull/193792
>From f883c2338c5a05d9a73cf3a25f322a814f971468 Mon Sep 17 00:00:00 2001
From: Guray Ozen <gozen at nvidia.com>
Date: Thu, 23 Apr 2026 17:59:06 +0200
Subject: [PATCH 1/2] [MLIR][NVVM] Add `nvvm.cos` OP
Implement `nvvm.cos` with ftz flag
---
mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td | 29 +++++++++++++++++++
.../Dialect/LLVMIR/nvvm-transcendentals.mlir | 15 ++++++++++
.../Target/LLVMIR/nvvm/transcendentals.mlir | 15 ++++++++++
3 files changed, 59 insertions(+)
create mode 100644 mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir
create mode 100644 mlir/test/Target/LLVMIR/nvvm/transcendentals.mlir
diff --git a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
index c892ee18166f2..360896db863c6 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
@@ -518,6 +518,35 @@ def NVVM_RcpApproxFtzF32Op : NVVM_IntrOp<"rcp.approx.ftz.f", [Pure], 1> {
let assemblyFormat = "$arg attr-dict `:` type($res)";
}
+//===----------------------------------------------------------------------===//
+// NVVM transcendental op definitions
+//===----------------------------------------------------------------------===//
+// PTX provides only fast approximations for sin/cos/lg2/ex2/tanh. Exposing
+// these as plain `nvvm.{sin,cos,lg2,ex2,tanh}` (without a `.approx` suffix)
+// keeps the NVVM dialect self-contained -- users don't need to reach for
+// `math.*` ops for something that already has a PTX instruction.
+
+def NVVM_CosOp : NVVM_Op<"cos", [Pure, SameOperandsAndResultType]> {
+ let summary = "Cosine (fast approximation)";
+ let description = [{
+ Computes a fast approximation of the cosine of the input value (in
+ radians). Lowers to PTX `cos.approx{.ftz}.f32`. The `ftz` attribute,
+ when set, flushes subnormal inputs and results to sign-preserving zero.
+
+ For more information, see PTX ISA:
+ [cos](https://docs.nvidia.com/cuda/parallel-thread-execution/#floating-point-instructions-cos)
+ }];
+ let arguments = (ins F32:$src,
+ DefaultValuedAttr<BoolAttr, "false">:$ftz);
+ let results = (outs F32:$res);
+ let assemblyFormat = "$src attr-dict `:` type($src)";
+ string llvmBuilder = [{
+ unsigned IID = $ftz ? llvm::Intrinsic::nvvm_cos_approx_ftz_f
+ : llvm::Intrinsic::nvvm_cos_approx_f;
+ $res = createIntrinsicCall(builder, IID, {$src});
+ }];
+}
+
//===----------------------------------------------------------------------===//
// NVVM redux op definitions
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir b/mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir
new file mode 100644
index 0000000000000..a30171dacb4f3
--- /dev/null
+++ b/mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir
@@ -0,0 +1,15 @@
+// RUN: mlir-opt %s -split-input-file -verify-diagnostics | FileCheck %s
+
+// CHECK-LABEL: @nvvm_cos_f32
+func.func @nvvm_cos_f32(%arg0: f32) -> f32 {
+ // CHECK: nvvm.cos {{.*}} : f32
+ %0 = nvvm.cos %arg0 : f32
+ return %0 : f32
+}
+
+// CHECK-LABEL: @nvvm_cos_ftz_f32
+func.func @nvvm_cos_ftz_f32(%arg0: f32) -> f32 {
+ // CHECK: nvvm.cos {{.*}} {ftz = true} : f32
+ %0 = nvvm.cos %arg0 {ftz = true} : f32
+ return %0 : f32
+}
diff --git a/mlir/test/Target/LLVMIR/nvvm/transcendentals.mlir b/mlir/test/Target/LLVMIR/nvvm/transcendentals.mlir
new file mode 100644
index 0000000000000..e11dab54cbb67
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/transcendentals.mlir
@@ -0,0 +1,15 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// CHECK-LABEL: @nvvm_cos
+llvm.func @nvvm_cos(%arg0: f32) -> f32 {
+ // CHECK: call float @llvm.nvvm.cos.approx.f(float %{{.*}})
+ %0 = nvvm.cos %arg0 : f32
+ llvm.return %0 : f32
+}
+
+// CHECK-LABEL: @nvvm_cos_ftz
+llvm.func @nvvm_cos_ftz(%arg0: f32) -> f32 {
+ // CHECK: call float @llvm.nvvm.cos.approx.ftz.f(float %{{.*}})
+ %0 = nvvm.cos %arg0 {ftz = true} : f32
+ llvm.return %0 : f32
+}
>From 2520e0028f3db77c18f374f7186691594c8babfb Mon Sep 17 00:00:00 2001
From: Guray Ozen <gozen at nvidia.com>
Date: Fri, 24 Apr 2026 12:35:04 +0200
Subject: [PATCH 2/2] [MLIR][NVVM] Address review comments on nvvm.cos
- Switch NVVM_CosOp to the NVVM_SingleResultIntrinsicOp wrapper; move
intrinsic-ID selection into getIntrinsicIDAndArgs.
- Drop -verify-diagnostics from the dialect test RUN line (no
expected-error directives in the file).
---
mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td | 8 ++------
mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp | 10 ++++++++++
mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir | 2 +-
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
index 360896db863c6..60856bc7e9c78 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
@@ -526,7 +526,8 @@ def NVVM_RcpApproxFtzF32Op : NVVM_IntrOp<"rcp.approx.ftz.f", [Pure], 1> {
// keeps the NVVM dialect self-contained -- users don't need to reach for
// `math.*` ops for something that already has a PTX instruction.
-def NVVM_CosOp : NVVM_Op<"cos", [Pure, SameOperandsAndResultType]> {
+def NVVM_CosOp : NVVM_SingleResultIntrinsicOp<"cos",
+ [Pure, SameOperandsAndResultType]> {
let summary = "Cosine (fast approximation)";
let description = [{
Computes a fast approximation of the cosine of the input value (in
@@ -540,11 +541,6 @@ def NVVM_CosOp : NVVM_Op<"cos", [Pure, SameOperandsAndResultType]> {
DefaultValuedAttr<BoolAttr, "false">:$ftz);
let results = (outs F32:$res);
let assemblyFormat = "$src attr-dict `:` type($src)";
- string llvmBuilder = [{
- unsigned IID = $ftz ? llvm::Intrinsic::nvvm_cos_approx_ftz_f
- : llvm::Intrinsic::nvvm_cos_approx_f;
- $res = createIntrinsicCall(builder, IID, {$src});
- }];
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
index 31e7ff209db5c..d137284628729 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
@@ -3464,6 +3464,16 @@ mlir::NVVM::IDArgPair NVVM::BarrierOp::getIntrinsicIDAndArgs(
return {id, std::move(args)};
}
+mlir::NVVM::IDArgPair
+CosOp::getIntrinsicIDAndArgs(Operation &op, LLVM::ModuleTranslation &mt,
+ llvm::IRBuilderBase &builder) {
+ auto thisOp = cast<NVVM::CosOp>(op);
+ llvm::Intrinsic::ID id = thisOp.getFtz()
+ ? llvm::Intrinsic::nvvm_cos_approx_ftz_f
+ : llvm::Intrinsic::nvvm_cos_approx_f;
+ return {id, {mt.lookupValue(thisOp.getSrc())}};
+}
+
mlir::NVVM::IDArgPair
PMEventOp::getIntrinsicIDAndArgs(Operation &op, LLVM::ModuleTranslation &mt,
llvm::IRBuilderBase &builder) {
diff --git a/mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir b/mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir
index a30171dacb4f3..7f8c84cdd1a70 100644
--- a/mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir
+++ b/mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir
@@ -1,4 +1,4 @@
-// RUN: mlir-opt %s -split-input-file -verify-diagnostics | FileCheck %s
+// RUN: mlir-opt %s -split-input-file | FileCheck %s
// CHECK-LABEL: @nvvm_cos_f32
func.func @nvvm_cos_f32(%arg0: f32) -> f32 {
More information about the Mlir-commits
mailing list