[Mlir-commits] [mlir] e646642 - [MLIR][LLVM] Allow strings in module flag value (#136793)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Apr 23 21:11:39 PDT 2025


Author: Bruno Cardoso Lopes
Date: 2025-04-23T21:11:36-07:00
New Revision: e6466420505d9940fda087f30a500fb03e5507b5

URL: https://github.com/llvm/llvm-project/commit/e6466420505d9940fda087f30a500fb03e5507b5
DIFF: https://github.com/llvm/llvm-project/commit/e6466420505d9940fda087f30a500fb03e5507b5.diff

LOG: [MLIR][LLVM] Allow strings in module flag value (#136793)

Expand support a bit beyond integers.

Next step is to support more complex metadata values (e.g. !"CG Profile"
and !"ProfileSummary"), but that's a bit more complex and deserves it
own PR.

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
    mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
    mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
    mlir/lib/Target/LLVMIR/ModuleImport.cpp
    mlir/test/Dialect/LLVMIR/invalid.mlir
    mlir/test/Dialect/LLVMIR/module-roundtrip.mlir
    mlir/test/Target/LLVMIR/Import/module-flags.ll
    mlir/test/Target/LLVMIR/llvmir.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 0f195ff82c3ff..f53f95ee9ba49 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -1332,18 +1332,21 @@ def ModuleFlagAttr
     Represents a single entry of llvm.module.flags metadata
     (llvm::Module::ModuleFlagEntry in LLVM). The first element is a behavior
     flag described by `ModFlagBehaviorAttr`, the second is a string ID
-    and third is the value of the flag (currently only integer constants
-    are supported).
+    and third is the value of the flag. Current supported types of values:
+      - Integer constants
+      - Strings
 
     Example:
     ```mlir
       #llvm.mlir.module_flag<error, "wchar_size", 4>
+      #llvm.mlir.module_flag<error, "probe-stack", "inline-asm">
     ```
   }];
   let parameters = (ins "ModFlagBehavior":$behavior,
                         "StringAttr":$key,
-                        "uint32_t":$value);
+                        "Attribute":$value);
   let assemblyFormat = "`<` $behavior `,` $key `,` $value `>`";
+  let genVerifyDecl = 1;
 }
 
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
index e4f9d6f987401..f3ebb8a565ea4 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
@@ -375,3 +375,13 @@ TargetFeaturesAttr TargetFeaturesAttr::featuresAt(Operation *op) {
   return parentFunction.getOperation()->getAttrOfType<TargetFeaturesAttr>(
       getAttributeName());
 }
+
+LogicalResult
+ModuleFlagAttr::verify(function_ref<InFlightDiagnostic()> emitError,
+                       LLVM::ModFlagBehavior flagBehavior, StringAttr key,
+                       Attribute value) {
+  if (!isa<IntegerAttr, StringAttr>(value))
+    return emitError()
+           << "only integer and string values are currently supported";
+  return success();
+}

diff  --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 7038b5d73d266..e816a3e218452 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -16,6 +16,7 @@
 #include "mlir/Support/LLVM.h"
 #include "mlir/Target/LLVMIR/ModuleTranslation.h"
 
+#include "llvm/ADT/TypeSwitch.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/MDBuilder.h"
@@ -273,10 +274,25 @@ static void convertLinkerOptionsOp(ArrayAttr options,
 static void convertModuleFlagsOp(ArrayAttr flags, llvm::IRBuilderBase &builder,
                                  LLVM::ModuleTranslation &moduleTranslation) {
   llvm::Module *llvmModule = moduleTranslation.getLLVMModule();
-  for (auto flagAttr : flags.getAsRange<ModuleFlagAttr>())
+  for (auto flagAttr : flags.getAsRange<ModuleFlagAttr>()) {
+    llvm::Metadata *valueMetadata =
+        llvm::TypeSwitch<Attribute, llvm::Metadata *>(flagAttr.getValue())
+            .Case<StringAttr>([&](auto strAttr) {
+              return llvm::MDString::get(builder.getContext(),
+                                         strAttr.getValue());
+            })
+            .Case<IntegerAttr>([&](auto intAttr) {
+              return llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
+                  llvm::Type::getInt32Ty(builder.getContext()),
+                  intAttr.getInt()));
+            })
+            .Default([](auto) { return nullptr; });
+
+    assert(valueMetadata && "expected valid metadata");
     llvmModule->addModuleFlag(
         convertModFlagBehaviorToLLVM(flagAttr.getBehavior()),
-        flagAttr.getKey().getValue(), flagAttr.getValue());
+        flagAttr.getKey().getValue(), valueMetadata);
+  }
 }
 
 static LogicalResult

diff  --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index df7c8d6ea3579..3f80002c15ebb 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -525,18 +525,20 @@ LogicalResult ModuleImport::convertModuleFlagsMetadata() {
 
   SmallVector<Attribute> moduleFlags;
   for (const auto [behavior, key, val] : llvmModuleFlags) {
-    // Currently only supports most common: int constant values.
-    auto *constInt = llvm::mdconst::dyn_extract<llvm::ConstantInt>(val);
-    if (!constInt) {
+    Attribute valAttr = nullptr;
+    if (auto *constInt = llvm::mdconst::dyn_extract<llvm::ConstantInt>(val)) {
+      valAttr = builder.getI32IntegerAttr(constInt->getZExtValue());
+    } else if (auto *mdString = dyn_cast<llvm::MDString>(val)) {
+      valAttr = builder.getStringAttr(mdString->getString());
+    } else {
       emitWarning(mlirModule.getLoc())
-          << "unsupported module flag value: " << diagMD(val, llvmModule.get())
-          << ", only constant integer currently supported";
+          << "unsupported module flag value: " << diagMD(val, llvmModule.get());
       continue;
     }
 
     moduleFlags.push_back(builder.getAttr<ModuleFlagAttr>(
         convertModFlagBehaviorFromLLVM(behavior),
-        builder.getStringAttr(key->getString()), constInt->getZExtValue()));
+        builder.getStringAttr(key->getString()), valAttr));
   }
 
   if (!moduleFlags.empty())

diff  --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index 0cd6b1f20a1bf..a3cd9572933ae 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -1776,9 +1776,10 @@ llvm.mlir.alias external @y5 : i32 {
 // -----
 
 module {
-  // expected-error at +2 {{expected integer value}}
-  // expected-error at +1 {{failed to parse ModuleFlagAttr parameter 'value' which is to be a `uint32_t`}}
-  llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", "yolo">]
+  llvm.func @foo()
+
+  // expected-error at below {{only integer and string values are currently supported}}
+  llvm.module_flags [#llvm.mlir.module_flag<error, "yolo", @foo>]
 }
 
 // -----

diff  --git a/mlir/test/Dialect/LLVMIR/module-roundtrip.mlir b/mlir/test/Dialect/LLVMIR/module-roundtrip.mlir
index d99a93c1e8565..a94514da9818f 100644
--- a/mlir/test/Dialect/LLVMIR/module-roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/module-roundtrip.mlir
@@ -1,16 +1,18 @@
 // RUN: mlir-opt %s | mlir-opt | FileCheck %s
 
 module {
-  llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", 4>,
-                     #llvm.mlir.module_flag<min, "PIC Level", 2>,
-                     #llvm.mlir.module_flag<max, "PIE Level", 2>,
-                     #llvm.mlir.module_flag<max, "uwtable", 2>,
-                     #llvm.mlir.module_flag<max, "frame-pointer", 1>]
+  llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", 4 : i32>,
+                     #llvm.mlir.module_flag<min, "PIC Level", 2 : i32>,
+                     #llvm.mlir.module_flag<max, "PIE Level", 2 : i32>,
+                     #llvm.mlir.module_flag<max, "uwtable", 2 : i32>,
+                     #llvm.mlir.module_flag<max, "frame-pointer", 1 : i32>,
+                     #llvm.mlir.module_flag<override, "probe-stack", "inline-asm">]
 }
 
 // CHECK: llvm.module_flags [
-// CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4>,
-// CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2>,
-// CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2>,
-// CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2>,
-// CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1>]
+// CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4 : i32>,
+// CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2 : i32>,
+// CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2 : i32>,
+// CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2 : i32>,
+// CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1 : i32>,
+// CHECK-SAME: #llvm.mlir.module_flag<override, "probe-stack", "inline-asm">]

diff  --git a/mlir/test/Target/LLVMIR/Import/module-flags.ll b/mlir/test/Target/LLVMIR/Import/module-flags.ll
index b7b686f94c7f4..e6bb2c0ffb32d 100644
--- a/mlir/test/Target/LLVMIR/Import/module-flags.ll
+++ b/mlir/test/Target/LLVMIR/Import/module-flags.ll
@@ -1,25 +1,27 @@
 ; RUN: mlir-translate -import-llvm -split-input-file -verify-diagnostics %s | FileCheck %s
 
-!llvm.module.flags = !{!0, !1, !2, !3, !4}
+!llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
 
 !0 = !{i32 1, !"wchar_size", i32 4}
 !1 = !{i32 8, !"PIC Level", i32 2}
 !2 = !{i32 7, !"PIE Level", i32 2}
 !3 = !{i32 7, !"uwtable", i32 2}
 !4 = !{i32 7, !"frame-pointer", i32 1}
+!5 = !{i32 4, !"probe-stack", !"inline-asm"}
 
 ; CHECK-LABEL: module attributes {{.*}} {
 ; CHECK: llvm.module_flags [
-; CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4>,
-; CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2>,
-; CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2>,
-; CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2>,
-; CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1>]
-; CHECK: }
+; CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4 : i32>,
+; CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2 : i32>,
+; CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2 : i32>,
+; CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2 : i32>,
+; CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1 : i32>,
+; CHECK-SAME: #llvm.mlir.module_flag<override, "probe-stack", "inline-asm">]
 
 ; // -----
-
-!llvm.module.flags = !{!0}
-
-; expected-warning at -5{{unsupported module flag value: !"yolo_more", only constant integer currently supported}}
-!0 = !{i32 1, !"yolo", !"yolo_more"}
+; expected-warning at -2 {{unsupported module flag value: !4 = !{!"foo", i32 1}}}
+!10 = !{ i32 1, !"foo", i32 1 }
+!11 = !{ i32 4, !"bar", i32 37 }
+!12 = !{ i32 2, !"qux", i32 42 }
+!13 = !{ i32 3, !"qux", !{ !"foo", i32 1 }}
+!llvm.module.flags = !{ !10, !11, !12, !13 }

diff  --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 3cf08dbeeac8c..74fa327809864 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -2809,11 +2809,11 @@ llvm.func @call_intrin_with_opbundle(%arg0 : !llvm.ptr) {
 // -----
 
 module {
-  llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", 4>,
-                     #llvm.mlir.module_flag<min, "PIC Level", 2>,
-                     #llvm.mlir.module_flag<max, "PIE Level", 2>,
-                     #llvm.mlir.module_flag<max, "uwtable", 2>,
-                     #llvm.mlir.module_flag<max, "frame-pointer", 1>]
+  llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", 4 : i32>,
+                     #llvm.mlir.module_flag<min, "PIC Level", 2 : i32>,
+                     #llvm.mlir.module_flag<max, "PIE Level", 2 : i32>,
+                     #llvm.mlir.module_flag<max, "uwtable", 2 : i32>,
+                     #llvm.mlir.module_flag<max, "frame-pointer", 1 : i32>]
 }
 
 // CHECK: !llvm.module.flags = !{![[#WCHAR:]], ![[#PIC:]], ![[#PIE:]], ![[#UWTABLE:]], ![[#FrameP:]], ![[#DBG:]]}
@@ -2830,7 +2830,7 @@ module {
 // Verifies that the debug info version is not added twice, if it's already present initially.
 
 module {
-  llvm.module_flags [#llvm.mlir.module_flag<warning, "Debug Info Version", 3>]
+  llvm.module_flags [#llvm.mlir.module_flag<warning, "Debug Info Version", 3 : i32>]
 }
 
 // CHECK: !llvm.module.flags = !{![[#DBG:]]}


        


More information about the Mlir-commits mailing list