[Mlir-commits] [mlir] [MLIR][NVVM] Update redux.sync op (PR #166125)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sun Nov 2 22:46:10 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Srinivasa Ravi (Wolfram70)
<details>
<summary>Changes</summary>
This change:
- Updates the `redux.sync` NVVM Op input and output type constraints.
- Adds a verifier for the Op to prevent stack dumps and the
execution of an `llvm_unreachable` in certain cases of invalid
usage, and instead gracefully error out with an informative
error message.
---
Full diff: https://github.com/llvm/llvm-project/pull/166125.diff
4 Files Affected:
- (modified) mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td (+5-3)
- (modified) mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp (+26)
- (modified) mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp (-3)
- (added) mlir/test/Target/LLVMIR/nvvm/redux-sync-invalid.mlir (+41)
``````````diff
diff --git a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
index 4f483859ac18d..3a212f91760f2 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
@@ -476,9 +476,9 @@ def ReduxKind : I32EnumAttr<"ReduxKind", "NVVM redux kind",
def ReduxKindAttr : EnumAttr<NVVM_Dialect, ReduxKind, "redux_kind">;
def NVVM_ReduxOp :
- NVVM_Op<"redux.sync", [NVVMRequiresSM<80>]>,
- Results<(outs LLVM_Type:$res)>,
- Arguments<(ins LLVM_Type:$val,
+ NVVM_Op<"redux.sync", [NVVMRequiresSM<80>, AllTypesMatch<["res", "val"]>]>,
+ Results<(outs AnyTypeOf<[I32, F32]>:$res)>,
+ Arguments<(ins AnyTypeOf<[I32, F32]>:$val,
ReduxKindAttr:$kind,
I32:$mask_and_clamp,
DefaultValuedAttr<BoolAttr, "false">:$abs,
@@ -496,6 +496,8 @@ def NVVM_ReduxOp :
[For more information, see PTX ISA](https://docs.nvidia.com/cuda/parallel-thread-execution/#parallel-synchronization-and-communication-instructions-redux-sync)
}];
+ let hasVerifier = 1;
+
string llvmBuilder = [{
auto intId = getReduxIntrinsicId($_resultType, $kind, $abs, $nan);
$res = createIntrinsicCall(builder, intId, {$val, $mask_and_clamp});
diff --git a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
index f0de4dbcc1d4b..bd5a759d38faf 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
@@ -1563,6 +1563,32 @@ LogicalResult NVVM::ClusterLaunchControlQueryCancelOp::verify() {
return success();
}
+LogicalResult NVVM::ReduxOp::verify() {
+ mlir::Type reduxType = getType();
+
+ if (!reduxType.isF32() && getAbs())
+ return emitOpError("abs attribute is supported only for f32 type");
+
+ if (!reduxType.isF32() && getNan())
+ return emitOpError("nan attribute is supported only for f32 type");
+
+ NVVM::ReduxKind kind = getKind();
+ switch (kind) {
+ case NVVM::ReduxKind::FMIN:
+ case NVVM::ReduxKind::FMAX:
+ if (!reduxType.isF32())
+ return emitOpError("fmin and fmax redux kind must be used with f32 type");
+ break;
+ default:
+ if (reduxType.isF32())
+ return emitOpError(
+ "only fmin and fmax redux kinds are supported for f32 type");
+ break;
+ }
+
+ return success();
+}
+
/// Packs the given `field` into the `result`.
/// The `result` is 64-bits and each `field` can be 32-bits or narrower.
static llvm::Value *
diff --git a/mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp
index 3d86b09b32538..0964e1b8c5ef3 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp
@@ -36,9 +36,6 @@ using mlir::LLVM::detail::createIntrinsicCall;
static llvm::Intrinsic::ID getReduxIntrinsicId(llvm::Type *resultType,
NVVM::ReduxKind kind,
bool hasAbs, bool hasNaN) {
- if (!(resultType->isIntegerTy(32) || resultType->isFloatTy()))
- llvm_unreachable("unsupported data type for redux");
-
switch (kind) {
case NVVM::ReduxKind::ADD:
return llvm::Intrinsic::nvvm_redux_sync_add;
diff --git a/mlir/test/Target/LLVMIR/nvvm/redux-sync-invalid.mlir b/mlir/test/Target/LLVMIR/nvvm/redux-sync-invalid.mlir
new file mode 100644
index 0000000000000..26b274d390396
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/redux-sync-invalid.mlir
@@ -0,0 +1,41 @@
+// RUN: mlir-translate -verify-diagnostics -split-input-file -mlir-to-llvmir %s
+
+// -----
+
+llvm.func @redux_sync_i32_with_abs(%value: i32, %offset: i32) {
+ // expected-error at +1 {{abs attribute is supported only for f32 type}}
+ %res = nvvm.redux.sync add %value, %offset {abs = true}: i32 -> i32
+ llvm.return
+}
+
+// -----
+
+llvm.func @redux_sync_i32_with_nan(%value: i32, %offset: i32) {
+ // expected-error at +1 {{nan attribute is supported only for f32 type}}
+ %res = nvvm.redux.sync add %value, %offset {nan = true}: i32 -> i32
+ llvm.return
+}
+
+// -----
+
+llvm.func @redux_sync_f32_with_invalid_kind(%value: f32, %offset: i32) {
+ // expected-error at +1 {{only fmin and fmax redux kinds are supported for f32 type}}
+ %res = nvvm.redux.sync add %value, %offset: f32 -> f32
+ llvm.return
+}
+
+// -----
+
+llvm.func @redux_sync_i32_with_invalid_kind(%value: i32, %offset: i32) {
+ // expected-error at +1 {{fmin and fmax redux kind must be used with f32 type}}
+ %res = nvvm.redux.sync fmin %value, %offset: i32 -> i32
+ llvm.return
+}
+
+// -----
+
+llvm.func @redux_sync_non_matching_types(%value: i32, %offset: i32) {
+ // expected-error at +1 {{failed to verify that all of {res, val} have same type}}
+ %res = nvvm.redux.sync add %value, %offset: i32 -> f32
+ llvm.return
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/166125
More information about the Mlir-commits
mailing list