[Mlir-commits] [mlir] [MLIR][NVVM] Fix crash on invalid optimization level in NVVMTargetAttr (PR #173280)
Akimasa Watanuki
llvmlistbot at llvm.org
Mon Jan 5 05:07:41 PST 2026
https://github.com/Men-cotton updated https://github.com/llvm/llvm-project/pull/173280
>From 170e79329d02ff4aa542446f378d924e32c7faf5 Mon Sep 17 00:00:00 2001
From: mencotton <mencotton0410 at gmail.com>
Date: Tue, 23 Dec 2025 01:22:01 +0900
Subject: [PATCH 1/3] [MLIR][NVVM] Fix crash on invalid optimization level in
NVVMTargetAttr
---
mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp | 9 ++++---
mlir/test/Dialect/LLVMIR/attach-targets.mlir | 27 +++++++++++++-------
2 files changed, 23 insertions(+), 13 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
index 331d7a244310f..95451c5c7f4d1 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
@@ -5537,10 +5537,6 @@ NVVMTargetAttr::verify(function_ref<InFlightDiagnostic()> emitError,
int optLevel, StringRef triple, StringRef chip,
StringRef features, DictionaryAttr flags,
ArrayAttr files, bool verifyTarget) {
- if (optLevel < 0 || optLevel > 3) {
- emitError() << "The optimization level must be a number between 0 and 3.";
- return failure();
- }
if (triple.empty()) {
emitError() << "The target triple cannot be empty.";
return failure();
@@ -5559,6 +5555,11 @@ NVVMTargetAttr::verify(function_ref<InFlightDiagnostic()> emitError,
}
LogicalResult NVVMTargetAttr::verifyTarget(Operation *gpuModule) {
+ if (getO() < 0 || getO() > 3) {
+ return emitError(
+ gpuModule->getLoc(),
+ "The optimization level must be a number between 0 and 3.");
+ }
if (!getVerifyTarget())
return success();
diff --git a/mlir/test/Dialect/LLVMIR/attach-targets.mlir b/mlir/test/Dialect/LLVMIR/attach-targets.mlir
index d1112f7411aae..753a00085d7bf 100644
--- a/mlir/test/Dialect/LLVMIR/attach-targets.mlir
+++ b/mlir/test/Dialect/LLVMIR/attach-targets.mlir
@@ -1,38 +1,47 @@
-// RUN: mlir-opt %s --nvvm-attach-target='module=nvvm.* O=3 chip=sm_90' --rocdl-attach-target='module=rocdl.* O=3 chip=gfx90a' --xevm-attach-target='module=xevm.* O=3 chip=pvc' | FileCheck %s
-// RUN: mlir-opt %s --nvvm-attach-target='module=options.* O=1 chip=sm_70 fast=true ftz=true' --rocdl-attach-target='module=options.* l=file1.bc,file2.bc wave64=false finite-only=true' --xevm-attach-target='module=options.* O=1 chip=pvc' | FileCheck %s --check-prefix=CHECK_OPTS
+// RUN: mlir-opt %s --nvvm-attach-target='module=nvvm.* O=3 chip=sm_90' --rocdl-attach-target='module=rocdl.* O=3 chip=gfx90a' --xevm-attach-target='module=xevm.* O=3 chip=pvc' -split-input-file -verify-diagnostics | FileCheck %s
+// RUN: mlir-opt %s --nvvm-attach-target='module=options.* O=1 chip=sm_70 fast=true ftz=true' --rocdl-attach-target='module=options.* l=file1.bc,file2.bc wave64=false finite-only=true' --xevm-attach-target='module=options.* O=1 chip=pvc' -split-input-file -verify-diagnostics | FileCheck %s --check-prefix=CHECK_OPTS
+// RUN: mlir-opt %s --nvvm-attach-target -verify-diagnostics -split-input-file
module attributes {gpu.container_module} {
// Verify the target is appended.
-// CHECK: @nvvm_module_1 [#nvvm.target<O = 3, chip = "sm_90">] {
+// CHECK: @nvvm_module_1 [#nvvm.target<O = 3, chip = "sm_90">]
gpu.module @nvvm_module_1 {
}
// Verify the target is appended.
-// CHECK: @nvvm_module_2 [#nvvm.target<chip = "sm_60">, #nvvm.target<O = 3, chip = "sm_90">] {
+// CHECK: @nvvm_module_2 [#nvvm.target<chip = "sm_60">, #nvvm.target<O = 3, chip = "sm_90">]
gpu.module @nvvm_module_2 [#nvvm.target<chip = "sm_60">] {
}
// Verify the target is not added multiple times.
-// CHECK: @nvvm_module_3 [#nvvm.target<O = 3, chip = "sm_90">] {
+// CHECK: @nvvm_module_3 [#nvvm.target<O = 3, chip = "sm_90">]
gpu.module @nvvm_module_3 [#nvvm.target<O = 3, chip = "sm_90">] {
}
// Verify the NVVM target is not added as it fails to match the regex, but the ROCDL does get appended.
-// CHECK: @rocdl_module [#rocdl.target<O = 3, chip = "gfx90a">] {
+// CHECK: @rocdl_module [#rocdl.target<O = 3, chip = "gfx90a">]
gpu.module @rocdl_module {
}
// Verify that other targets are not added as they fail to match the regex, but XeVM does get appended.
-// CHECK: @xevm_module [#xevm.target<O = 3, chip = "pvc">] {
+// CHECK: @xevm_module [#xevm.target<O = 3, chip = "pvc">]
gpu.module @xevm_module {
}
// Check the options were added.
// CHECK_OPTS: @options_module_1 [#nvvm.target<O = 1, chip = "sm_70", flags = {fast, ftz}>,
// CHECK_OPTS-SAME: #rocdl.target<flags = {finite_only, no_wave64}, link = ["file1.bc", "file2.bc"]>,
-// CHECK_OPTS-SAME: #xevm.target<O = 1, chip = "pvc">] {
+// CHECK_OPTS-SAME: #xevm.target<O = 1, chip = "pvc">]
gpu.module @options_module_1 {
}
// Check the options were added and that the first target was preserved.
// CHECK_OPTS: @options_module_2 [#nvvm.target<O = 3, chip = "sm_90">,
// CHECK_OPTS-SAME: #nvvm.target<O = 1, chip = "sm_70", flags = {fast, ftz}>,
// CHECK_OPTS-SAME: #rocdl.target<flags = {finite_only, no_wave64}, link = ["file1.bc", "file2.bc"]>,
-// CHECK_OPTS-SAME: #xevm.target<O = 1, chip = "pvc">] {
+// CHECK_OPTS-SAME: #xevm.target<O = 1, chip = "pvc">]
gpu.module @options_module_2 [#nvvm.target<O = 3, chip = "sm_90">] {
}
}
+
+// -----
+
+module attributes {gpu.container_module} {
+ // expected-error @+1 {{The optimization level must be a number between 0 and 3}}
+ gpu.module @nvvm_module_example_3 [#nvvm.target<chip = "sm_90", features = "ftz", O = 4>] {
+ }
+}
>From ca8498fe8ee8a8aa8bdd84c7ae0bf1cf5ade5237 Mon Sep 17 00:00:00 2001
From: mencotton <mencotton0410 at gmail.com>
Date: Mon, 5 Jan 2026 21:17:18 +0900
Subject: [PATCH 2/3] revert the patch
---
mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
index 95451c5c7f4d1..331d7a244310f 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
@@ -5537,6 +5537,10 @@ NVVMTargetAttr::verify(function_ref<InFlightDiagnostic()> emitError,
int optLevel, StringRef triple, StringRef chip,
StringRef features, DictionaryAttr flags,
ArrayAttr files, bool verifyTarget) {
+ if (optLevel < 0 || optLevel > 3) {
+ emitError() << "The optimization level must be a number between 0 and 3.";
+ return failure();
+ }
if (triple.empty()) {
emitError() << "The target triple cannot be empty.";
return failure();
@@ -5555,11 +5559,6 @@ NVVMTargetAttr::verify(function_ref<InFlightDiagnostic()> emitError,
}
LogicalResult NVVMTargetAttr::verifyTarget(Operation *gpuModule) {
- if (getO() < 0 || getO() > 3) {
- return emitError(
- gpuModule->getLoc(),
- "The optimization level must be a number between 0 and 3.");
- }
if (!getVerifyTarget())
return success();
>From 9c47500f312685abe2a340fea47c5ca0318a7045 Mon Sep 17 00:00:00 2001
From: mencotton <mencotton0410 at gmail.com>
Date: Mon, 5 Jan 2026 21:18:21 +0900
Subject: [PATCH 3/3] fix builder in NVVMOps.td to use `$_get`
---
mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
index 16133a2c135b7..3ba64cb9b3551 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
@@ -6357,7 +6357,7 @@ def NVVM_TargetAttr : NVVM_Attr<"NVVMTarget", "target",
CArg<"DictionaryAttr", "nullptr">:$targetFlags,
CArg<"ArrayAttr", "nullptr">:$linkFiles,
CArg<"bool", "true">:$verifyTarget), [{
- return Base::get($_ctxt, optLevel, triple, chip, features, targetFlags, linkFiles, verifyTarget);
+ return $_get($_ctxt, optLevel, triple, chip, features, targetFlags, linkFiles, verifyTarget);
}]>
];
let skipDefaultBuilders = 1;
More information about the Mlir-commits
mailing list