[Mlir-commits] [mlir] [MLIR][NVVM] Add `nvvm.tanh` OP (PR #193791)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Apr 23 09:18:04 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir

Author: Guray Ozen (grypp)

<details>
<summary>Changes</summary>

Implement `nvvm.tanh` lowering to `llvm.tanh` with `afn` fast-math flag. NVPTX backend pattern-matches this into `tanh.approx.f32`. PTX does not expose an `ftz` modifier for `tanh.approx`, so the op has no `ftz` attribute.

---
Full diff: https://github.com/llvm/llvm-project/pull/193791.diff


3 Files Affected:

- (modified) mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td (+32) 
- (added) mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir (+8) 
- (added) mlir/test/Target/LLVMIR/nvvm/transcendentals.mlir (+8) 


``````````diff
diff --git a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
index c892ee18166f2..cf13136bc7735 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
@@ -518,6 +518,38 @@ 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_TanhOp : NVVM_Op<"tanh", [Pure, SameOperandsAndResultType]> {
+  let summary = "Hyperbolic tangent (fast approximation)";
+  let description = [{
+    Computes a fast approximation of the hyperbolic tangent of the input
+    value. Lowers to PTX `tanh.approx.f32` (sm_75+, PTX 7.0+). PTX does not
+    expose an `ftz` modifier for `tanh.approx`, so this op has no `ftz`
+    attribute.
+
+    For more information, see PTX ISA:
+    [tanh](https://docs.nvidia.com/cuda/parallel-thread-execution/#floating-point-instructions-tanh)
+  }];
+  let arguments = (ins F32:$src);
+  let results = (outs F32:$res);
+  let assemblyFormat = "$src attr-dict `:` type($src)";
+  string llvmBuilder = [{
+    llvm::CallInst *call = createIntrinsicCall(
+        builder, llvm::Intrinsic::tanh, {$src}, {$src->getType()});
+    llvm::FastMathFlags fmf;
+    fmf.setApproxFunc();
+    call->setFastMathFlags(fmf);
+    $res = call;
+  }];
+}
+
 //===----------------------------------------------------------------------===//
 // 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..b46e29e0bbb63
--- /dev/null
+++ b/mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir
@@ -0,0 +1,8 @@
+// RUN: mlir-opt %s -split-input-file -verify-diagnostics | FileCheck %s
+
+// CHECK-LABEL: @nvvm_tanh_f32
+func.func @nvvm_tanh_f32(%arg0: f32) -> f32 {
+  // CHECK: nvvm.tanh {{.*}} : f32
+  %0 = nvvm.tanh %arg0 : 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..eaddc07d164d0
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/transcendentals.mlir
@@ -0,0 +1,8 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// CHECK-LABEL: @nvvm_tanh
+llvm.func @nvvm_tanh(%arg0: f32) -> f32 {
+  // CHECK: call afn float @llvm.tanh.f32(float %{{.*}})
+  %0 = nvvm.tanh %arg0 : f32
+  llvm.return %0 : f32
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/193791


More information about the Mlir-commits mailing list