Skip to content

Commit 5d2743b

Browse files
committed
[MLIR][LLVM] Allow strings in module flag value
Expand support 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.
1 parent 8389d6f commit 5d2743b

File tree

7 files changed

+69
-39
lines changed

7 files changed

+69
-39
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,18 +1332,21 @@ def ModuleFlagAttr
13321332
Represents a single entry of llvm.module.flags metadata
13331333
(llvm::Module::ModuleFlagEntry in LLVM). The first element is a behavior
13341334
flag described by `ModFlagBehaviorAttr`, the second is a string ID
1335-
and third is the value of the flag (currently only integer constants
1336-
are supported).
1335+
and third is the value of the flag. Current supported types of values:
1336+
- Integer constants
1337+
- Strings
13371338

13381339
Example:
13391340
```mlir
13401341
#llvm.mlir.module_flag<error, "wchar_size", 4>
1342+
#llvm.mlir.module_flag<error, "probe-stack", "inline-asm">
13411343
```
13421344
}];
13431345
let parameters = (ins "ModFlagBehavior":$behavior,
13441346
"StringAttr":$key,
1345-
"uint32_t":$value);
1347+
"Attribute":$value);
13461348
let assemblyFormat = "`<` $behavior `,` $key `,` $value `>`";
1349+
let genVerifyDecl = 1;
13471350
}
13481351

13491352
//===----------------------------------------------------------------------===//

mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,13 @@ TargetFeaturesAttr TargetFeaturesAttr::featuresAt(Operation *op) {
375375
return parentFunction.getOperation()->getAttrOfType<TargetFeaturesAttr>(
376376
getAttributeName());
377377
}
378+
379+
LogicalResult
380+
ModuleFlagAttr::verify(function_ref<InFlightDiagnostic()> emitError,
381+
mlir::LLVM::ModFlagBehavior flagBehavior,
382+
mlir::StringAttr key, mlir::Attribute value) {
383+
if (!isa<mlir::IntegerAttr, mlir::StringAttr>(value))
384+
return emitError()
385+
<< "only integer and string values are currently supported";
386+
return success();
387+
}

mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,18 @@ static void convertLinkerOptionsOp(ArrayAttr options,
273273
static void convertModuleFlagsOp(ArrayAttr flags, llvm::IRBuilderBase &builder,
274274
LLVM::ModuleTranslation &moduleTranslation) {
275275
llvm::Module *llvmModule = moduleTranslation.getLLVMModule();
276-
for (auto flagAttr : flags.getAsRange<ModuleFlagAttr>())
277-
llvmModule->addModuleFlag(
278-
convertModFlagBehaviorToLLVM(flagAttr.getBehavior()),
279-
flagAttr.getKey().getValue(), flagAttr.getValue());
276+
for (auto flagAttr : flags.getAsRange<ModuleFlagAttr>()) {
277+
if (auto intAttr = dyn_cast<mlir::IntegerAttr>(flagAttr.getValue()))
278+
llvmModule->addModuleFlag(
279+
convertModFlagBehaviorToLLVM(flagAttr.getBehavior()),
280+
flagAttr.getKey().getValue(), intAttr.getUInt());
281+
else if (auto strAttr = dyn_cast<mlir::StringAttr>(flagAttr.getValue())) {
282+
llvmModule->addModuleFlag(
283+
convertModFlagBehaviorToLLVM(flagAttr.getBehavior()),
284+
flagAttr.getKey().getValue(),
285+
llvm::MDString::get(builder.getContext(), strAttr.getValue()));
286+
}
287+
}
280288
}
281289

282290
static LogicalResult

mlir/lib/Target/LLVMIR/ModuleImport.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -525,18 +525,22 @@ LogicalResult ModuleImport::convertModuleFlagsMetadata() {
525525

526526
SmallVector<Attribute> moduleFlags;
527527
for (const auto [behavior, key, val] : llvmModuleFlags) {
528-
// Currently only supports most common: int constant values.
529-
auto *constInt = llvm::mdconst::dyn_extract<llvm::ConstantInt>(val);
530-
if (!constInt) {
528+
Attribute valAttr = nullptr;
529+
if (auto *constInt = llvm::mdconst::dyn_extract<llvm::ConstantInt>(val)) {
530+
valAttr = builder.getI32IntegerAttr(constInt->getZExtValue());
531+
} else if (auto *mdString = dyn_cast<llvm::MDString>(val)) {
532+
valAttr = builder.getStringAttr(mdString->getString());
533+
} else {
531534
emitWarning(mlirModule.getLoc())
532-
<< "unsupported module flag value: " << diagMD(val, llvmModule.get())
533-
<< ", only constant integer currently supported";
534-
continue;
535+
<< "unsupported module flag value: " << diagMD(val, llvmModule.get());
535536
}
536537

538+
if (!valAttr)
539+
continue;
540+
537541
moduleFlags.push_back(builder.getAttr<ModuleFlagAttr>(
538542
convertModFlagBehaviorFromLLVM(behavior),
539-
builder.getStringAttr(key->getString()), constInt->getZExtValue()));
543+
builder.getStringAttr(key->getString()), valAttr));
540544
}
541545

542546
if (!moduleFlags.empty())

mlir/test/Dialect/LLVMIR/invalid.mlir

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1776,9 +1776,10 @@ llvm.mlir.alias external @y5 : i32 {
17761776
// -----
17771777

17781778
module {
1779-
// expected-error@+2 {{expected integer value}}
1780-
// expected-error@+1 {{failed to parse ModuleFlagAttr parameter 'value' which is to be a `uint32_t`}}
1781-
llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", "yolo">]
1779+
llvm.func @foo()
1780+
1781+
// expected-error@+1 {{only integer and string values are currently supported}}
1782+
llvm.module_flags [#llvm.mlir.module_flag<error, "yolo", @foo>]
17821783
}
17831784

17841785
// -----
Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
// RUN: mlir-opt %s | mlir-opt | FileCheck %s
22

33
module {
4-
llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", 4>,
5-
#llvm.mlir.module_flag<min, "PIC Level", 2>,
6-
#llvm.mlir.module_flag<max, "PIE Level", 2>,
7-
#llvm.mlir.module_flag<max, "uwtable", 2>,
8-
#llvm.mlir.module_flag<max, "frame-pointer", 1>]
4+
llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", 4 : i32>,
5+
#llvm.mlir.module_flag<min, "PIC Level", 2 : i32>,
6+
#llvm.mlir.module_flag<max, "PIE Level", 2 : i32>,
7+
#llvm.mlir.module_flag<max, "uwtable", 2 : i32>,
8+
#llvm.mlir.module_flag<max, "frame-pointer", 1 : i32>,
9+
#llvm.mlir.module_flag<override, "probe-stack", "inline-asm">]
910
}
1011

1112
// CHECK: llvm.module_flags [
12-
// CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4>,
13-
// CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2>,
14-
// CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2>,
15-
// CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2>,
16-
// CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1>]
13+
// CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4 : i32>,
14+
// CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2 : i32>,
15+
// CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2 : i32>,
16+
// CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2 : i32>,
17+
// CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1 : i32>,
18+
// CHECK-SAME: #llvm.mlir.module_flag<override, "probe-stack", "inline-asm">]
Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
11
; RUN: mlir-translate -import-llvm -split-input-file -verify-diagnostics %s | FileCheck %s
22

3-
!llvm.module.flags = !{!0, !1, !2, !3, !4}
3+
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
44

55
!0 = !{i32 1, !"wchar_size", i32 4}
66
!1 = !{i32 8, !"PIC Level", i32 2}
77
!2 = !{i32 7, !"PIE Level", i32 2}
88
!3 = !{i32 7, !"uwtable", i32 2}
99
!4 = !{i32 7, !"frame-pointer", i32 1}
10+
!5 = !{i32 4, !"probe-stack", !"inline-asm"}
1011

1112
; CHECK-LABEL: module attributes {{.*}} {
1213
; CHECK: llvm.module_flags [
13-
; CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4>,
14-
; CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2>,
15-
; CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2>,
16-
; CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2>,
17-
; CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1>]
18-
; CHECK: }
14+
; CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4 : i32>,
15+
; CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2 : i32>,
16+
; CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2 : i32>,
17+
; CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2 : i32>,
18+
; CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1 : i32>,
19+
; CHECK-SAME: #llvm.mlir.module_flag<override, "probe-stack", "inline-asm">]
1920

2021
; // -----
21-
22-
!llvm.module.flags = !{!0}
23-
24-
; expected-warning@-5{{unsupported module flag value: !"yolo_more", only constant integer currently supported}}
25-
!0 = !{i32 1, !"yolo", !"yolo_more"}
22+
; expected-warning@-2{{unsupported module flag value: !4 = !{!"foo", i32 1}}}
23+
!0 = !{ i32 1, !"foo", i32 1 }
24+
!1 = !{ i32 4, !"bar", i32 37 }
25+
!2 = !{ i32 2, !"qux", i32 42 }
26+
!3 = !{ i32 3, !"qux", !{ !"foo", i32 1 }}
27+
!llvm.module.flags = !{ !0, !1, !2, !3 }

0 commit comments

Comments
 (0)