[Mlir-commits] [mlir] [MLIR][NVVM] Add `nvvm.ex2` OP (PR #193790)
Guray Ozen
llvmlistbot at llvm.org
Fri Apr 24 08:43:46 PDT 2026
https://github.com/grypp updated https://github.com/llvm/llvm-project/pull/193790
>From 2c85fe12765044ef899cb793e7b5b39ddde6bd00 Mon Sep 17 00:00:00 2001
From: Guray Ozen <gozen at nvidia.com>
Date: Fri, 24 Apr 2026 12:43:02 +0200
Subject: [PATCH] [MLIR][NVVM] Add `nvvm.ex2` OP
Implement `nvvm.ex2` with ftz flag
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply at anthropic.com>
---
mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td | 14 ++++++++++++++
mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp | 10 ++++++++++
mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir | 14 ++++++++++++++
mlir/test/Target/LLVMIR/nvvm/transcendentals.mlir | 14 ++++++++++++++
4 files changed, 52 insertions(+)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
index 9e94477c3a60a..dafbd8085de60 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
@@ -543,6 +543,20 @@ def NVVM_SinOp : NVVM_SingleResultIntrinsicOp<"sin",
let assemblyFormat = "$src attr-dict `:` type($src)";
}
+def NVVM_Ex2Op : NVVM_SingleResultIntrinsicOp<"ex2",
+ [Pure, SameOperandsAndResultType]> {
+ let summary = "Base-2 exponential (fast approximation)";
+ let description = [{
+ Computes a fast approximation of 2 raised to the power of the input
+ value. The `ftz` attribute, when set, flushes subnormal inputs and
+ results to sign-preserving zero.
+ }];
+ let arguments = (ins F32:$src,
+ DefaultValuedAttr<BoolAttr, "false">:$ftz);
+ let results = (outs F32:$res);
+ let assemblyFormat = "$src attr-dict `:` type($src)";
+}
+
//===----------------------------------------------------------------------===//
// NVVM redux op definitions
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
index b0cebd45624a9..c8eac290bbf20 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
@@ -3474,6 +3474,16 @@ SinOp::getIntrinsicIDAndArgs(Operation &op, LLVM::ModuleTranslation &mt,
return {id, {mt.lookupValue(thisOp.getSrc())}};
}
+mlir::NVVM::IDArgPair
+Ex2Op::getIntrinsicIDAndArgs(Operation &op, LLVM::ModuleTranslation &mt,
+ llvm::IRBuilderBase &builder) {
+ auto thisOp = cast<NVVM::Ex2Op>(op);
+ llvm::Intrinsic::ID id = thisOp.getFtz()
+ ? llvm::Intrinsic::nvvm_ex2_approx_ftz
+ : llvm::Intrinsic::nvvm_ex2_approx;
+ 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 c773e3f06a612..5391db1c93640 100644
--- a/mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir
+++ b/mlir/test/Dialect/LLVMIR/nvvm-transcendentals.mlir
@@ -13,3 +13,17 @@ func.func @nvvm_sin_ftz_f32(%arg0: f32) -> f32 {
%0 = nvvm.sin %arg0 {ftz = true} : f32
return %0 : f32
}
+
+// CHECK-LABEL: @nvvm_ex2_f32
+func.func @nvvm_ex2_f32(%arg0: f32) -> f32 {
+ // CHECK: nvvm.ex2 {{.*}} : f32
+ %0 = nvvm.ex2 %arg0 : f32
+ return %0 : f32
+}
+
+// CHECK-LABEL: @nvvm_ex2_ftz_f32
+func.func @nvvm_ex2_ftz_f32(%arg0: f32) -> f32 {
+ // CHECK: nvvm.ex2 {{.*}} {ftz = true} : f32
+ %0 = nvvm.ex2 %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
index 65374c9bd5e87..4830bf79eacd0 100644
--- a/mlir/test/Target/LLVMIR/nvvm/transcendentals.mlir
+++ b/mlir/test/Target/LLVMIR/nvvm/transcendentals.mlir
@@ -13,3 +13,17 @@ llvm.func @nvvm_sin_ftz(%arg0: f32) -> f32 {
%0 = nvvm.sin %arg0 {ftz = true} : f32
llvm.return %0 : f32
}
+
+// CHECK-LABEL: @nvvm_ex2
+llvm.func @nvvm_ex2(%arg0: f32) -> f32 {
+ // CHECK: call float @llvm.nvvm.ex2.approx.f32(float %{{.*}})
+ %0 = nvvm.ex2 %arg0 : f32
+ llvm.return %0 : f32
+}
+
+// CHECK-LABEL: @nvvm_ex2_ftz
+llvm.func @nvvm_ex2_ftz(%arg0: f32) -> f32 {
+ // CHECK: call float @llvm.nvvm.ex2.approx.ftz.f32(float %{{.*}})
+ %0 = nvvm.ex2 %arg0 {ftz = true} : f32
+ llvm.return %0 : f32
+}
More information about the Mlir-commits
mailing list