[Mlir-commits] [mlir] [MLIR][NVVM] Fix crash on invalid optimization level in NVVMTargetAttr (PR #173280)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Mon Dec 22 08:25:04 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-llvm

Author: Akimasa Watanuki (Men-cotton)

<details>
<summary>Changes</summary>

Relax `NVVMTargetAttr::verify` to accept any integer value for `optLevel`, preventing parser crashes on invalid inputs (e.g., `O=4`).

Move the strict range check (0-3) to `NVVMTargetAttr::verifyTarget`. This ensures that invalid optimization levels are reported as graceful errors during module verification.

Add a regression test in `attach-targets.mlir`.

Fixes: https://github.com/llvm/llvm-project/issues/130014

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


2 Files Affected:

- (modified) mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp (+5-4) 
- (modified) mlir/test/Dialect/LLVMIR/attach-targets.mlir (+18-9) 


``````````diff
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>] {
+  }
+}

``````````

</details>


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


More information about the Mlir-commits mailing list