[Mlir-commits] [mlir] [MLIR] Enable import of non self referential alias scopes (PR #121987)
William Moses
llvmlistbot at llvm.org
Tue Jan 7 12:46:29 PST 2025
https://github.com/wsmoses updated https://github.com/llvm/llvm-project/pull/121987
>From 24f8c87f102297baca387954d73ee73f4db41145 Mon Sep 17 00:00:00 2001
From: "William S. Moses" <gh at wsmoses.com>
Date: Tue, 7 Jan 2025 14:44:19 -0500
Subject: [PATCH] [MLIR] Enable import of non self referential alias scopes
---
.../mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 6 ++-
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 48 +++++++++++++----
mlir/test/Dialect/LLVMIR/roundtrip.mlir | 10 ++++
.../LLVMIR/Import/metadata-alias-scopes.ll | 35 +++++++++++++
.../Target/LLVMIR/attribute-alias-scopes.mlir | 51 +++++++++++++++++++
5 files changed, 139 insertions(+), 11 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index e8eeafd09a9cba..68df6f64e51ea4 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -825,7 +825,7 @@ def LLVM_MemoryEffectsAttr : LLVM_Attr<"MemoryEffects", "memory_effects"> {
def LLVM_AliasScopeDomainAttr : LLVM_Attr<"AliasScopeDomain",
"alias_scope_domain"> {
let parameters = (ins
- "DistinctAttr":$id,
+ "Attribute":$id,
OptionalParameter<"StringAttr">:$description
);
@@ -853,7 +853,7 @@ def LLVM_AliasScopeDomainAttr : LLVM_Attr<"AliasScopeDomain",
def LLVM_AliasScopeAttr : LLVM_Attr<"AliasScope", "alias_scope"> {
let parameters = (ins
- "DistinctAttr":$id,
+ "Attribute":$id,
"AliasScopeDomainAttr":$domain,
OptionalParameter<"StringAttr">:$description
);
@@ -891,6 +891,8 @@ def LLVM_AliasScopeAttr : LLVM_Attr<"AliasScope", "alias_scope"> {
}
```
+ The first attribute can either be a DistinctAttribute or a StringAttribute.
+
See the following link for more details:
https://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata
}];
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 95fb673fc72e39..d90646db33e3de 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -438,8 +438,14 @@ ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) {
if (aliasDomain->getNumOperands() >= 2)
if (auto *operand = dyn_cast<llvm::MDString>(aliasDomain->getOperand(1)))
description = builder.getStringAttr(operand->getString());
- return builder.getAttr<AliasScopeDomainAttr>(
- DistinctAttr::create(builder.getUnitAttr()), description);
+ Attribute idattr;
+ if (verifySelfRef(aliasDomain))
+ idattr = DistinctAttr::create(builder.getUnitAttr());
+ else {
+ auto Name = cast<llvm::MDString>(aliasDomain->getOperand(0));
+ idattr = builder.getStringAttr(Name->getString());
+ }
+ return builder.getAttr<AliasScopeDomainAttr>(idattr, description);
};
// Collect the alias scopes and domains to translate them.
@@ -452,12 +458,28 @@ ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) {
// verifying its domain. Perform the verification before looking it up in
// the alias scope mapping since it could have been inserted as a domain
// node before.
- if (!verifySelfRef(scope) || !domain || !verifyDescription(scope, 2))
- return emitError(loc) << "unsupported alias scope node: "
+ if (!domain)
+ return emitError(loc) << "unsupported alias scope node (no domain): "
<< diagMD(scope, llvmModule.get());
- if (!verifySelfRef(domain) || !verifyDescription(domain, 1))
- return emitError(loc) << "unsupported alias domain node: "
- << diagMD(domain, llvmModule.get());
+ if (verifySelfRef(scope) && !verifyDescription(scope, 2))
+ return emitError(loc)
+ << "unsupported alias scope node (bad description): "
+ << diagMD(scope, llvmModule.get());
+ if (!verifySelfRef(scope) && (scope->getNumOperands() == 0 ||
+ !isa<llvm::MDString>(scope->getOperand(0))))
+ return emitError(loc)
+ << "unsupported alias scope node (not self-ref and no string): "
+ << diagMD(scope, llvmModule.get());
+ if (!verifyDescription(domain, 1))
+ return emitError(loc)
+ << "unsupported alias domain node (bad description): "
+ << diagMD(domain, llvmModule.get());
+ if (!verifySelfRef(domain) &&
+ (domain->getNumOperands() == 0 ||
+ !isa<llvm::MDString>(domain->getOperand(0))))
+ return emitError(loc)
+ << "unsupported alias domain node (not self ref and no string): "
+ << diagMD(scope, llvmModule.get());
if (aliasScopeMapping.contains(scope))
continue;
@@ -473,9 +495,17 @@ ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) {
StringAttr description = nullptr;
if (!aliasScope.getName().empty())
description = builder.getStringAttr(aliasScope.getName());
+ Attribute idattr;
+ if (verifySelfRef(scope))
+ idattr = DistinctAttr::create(builder.getUnitAttr());
+ else {
+ auto Name = cast<llvm::MDString>(scope->getOperand(0));
+ idattr = builder.getStringAttr(Name->getString());
+ }
+
auto aliasScopeOp = builder.getAttr<AliasScopeAttr>(
- DistinctAttr::create(builder.getUnitAttr()),
- cast<AliasScopeDomainAttr>(it->second), description);
+ idattr, cast<AliasScopeDomainAttr>(it->second), description);
+
aliasScopeMapping.try_emplace(aliasScope.getNode(), aliasScopeOp);
}
}
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index aebfd7492093c1..d2546019324753 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -750,6 +750,16 @@ llvm.func @experimental_noalias_scope_decl() {
llvm.return
}
+#alias_scope_domain2 = #llvm.alias_scope_domain<id = "domainid", description = "The domain">
+#alias_scope2 = #llvm.alias_scope<id = "stringid", domain = #alias_scope_domain2, description = "The domain">
+
+// CHECK-LABEL: @experimental_noalias_scope_decl
+llvm.func @experimental_noalias_scope_decl2() {
+ // CHECK: llvm.intr.experimental.noalias.scope.decl #{{.*}}
+ llvm.intr.experimental.noalias.scope.decl #alias_scope2
+ llvm.return
+}
+
// CHECK-LABEL: @experimental_constrained_fptrunc
llvm.func @experimental_constrained_fptrunc(%in: f64) {
// CHECK: llvm.intr.experimental.constrained.fptrunc %{{.*}} towardzero ignore : f64 to f32
diff --git a/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll b/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll
index f5128ff76bc5ff..bf4c85786216fd 100644
--- a/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll
+++ b/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll
@@ -92,3 +92,38 @@ declare void @foo(ptr %arg1)
!0 = distinct !{!0, !"The domain"}
!1 = !{!1, !0}
!2 = !{!1}
+
+; // -----
+
+; CHECK: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<id = "domain1">
+; CHECK: #[[$SCOPE0:.*]] = #llvm.alias_scope<id = "scopeid1", domain = #[[DOMAIN]], description = "The first scope">
+; CHECK: #[[$SCOPE1:.*]] = #llvm.alias_scope<id = "scopeid2", domain = #[[DOMAIN]]>
+; CHECK: #[[$SCOPE2:.*]] = #llvm.alias_scope<id = "scopeid3", domain = #[[DOMAIN]]>
+
+; CHECK-LABEL: llvm.func @alias_scope
+define void @alias_scope(ptr %arg1) {
+ ; CHECK: llvm.load
+ ; CHECK-SAME: alias_scopes = [#[[$SCOPE0]]]
+ ; CHECK-SAME: noalias_scopes = [#[[$SCOPE1]], #[[$SCOPE2]]]
+ %1 = load i32, ptr %arg1, !alias.scope !4, !noalias !7
+ ; CHECK: llvm.load
+ ; CHECK-SAME: alias_scopes = [#[[$SCOPE1]]]
+ ; CHECK-SAME: noalias_scopes = [#[[$SCOPE0]], #[[$SCOPE2]]]
+ %2 = load i32, ptr %arg1, !alias.scope !5, !noalias !8
+ ; CHECK: llvm.load
+ ; CHECK-SAME: alias_scopes = [#[[$SCOPE2]]]
+ ; CHECK-SAME: noalias_scopes = [#[[$SCOPE0]], #[[$SCOPE1]]]
+ %3 = load i32, ptr %arg1, !alias.scope !6, !noalias !9
+ ret void
+}
+
+!0 = !{!"domain1"}
+!1 = !{!"scopeid1", !0, !"The first scope"}
+!2 = !{!"scopeid2", !0}
+!3 = !{!"scopeid3", !0}
+!4 = !{!1}
+!5 = !{!2}
+!6 = !{!3}
+!7 = !{!2, !3}
+!8 = !{!1, !3}
+!9 = !{!1, !2}
diff --git a/mlir/test/Target/LLVMIR/attribute-alias-scopes.mlir b/mlir/test/Target/LLVMIR/attribute-alias-scopes.mlir
index fa3395533af220..fb71a51512aee3 100644
--- a/mlir/test/Target/LLVMIR/attribute-alias-scopes.mlir
+++ b/mlir/test/Target/LLVMIR/attribute-alias-scopes.mlir
@@ -104,3 +104,54 @@ llvm.func @self_reference() {
// CHECK-DAG: ![[SCOPES]] = !{![[SCOPE]]}
// CHECK-DAG: = !DISubroutineType(types: ![[TYPES:[0-9]+]])
// CHECK-DAG: ![[TYPES]] = !{null}
+
+// -----
+
+llvm.func @foo(%arg0: !llvm.ptr)
+
+#alias_scope_domain = #llvm.alias_scope_domain<id = "domain1", description = "The domain">
+#alias_scope1 = #llvm.alias_scope<id = "scope1", domain = #alias_scope_domain, description = "The first scope">
+#alias_scope2 = #llvm.alias_scope<id = "scope2", domain = #alias_scope_domain>
+#alias_scope3 = #llvm.alias_scope<id = "scope3", domain = #alias_scope_domain>
+
+// CHECK-LABEL: @alias_scopes
+llvm.func @alias_scopes(%arg1 : !llvm.ptr) {
+ %0 = llvm.mlir.constant(0 : i32) : i32
+ // CHECK: call void @llvm.experimental.noalias.scope.decl(metadata ![[SCOPES1:[0-9]+]])
+ llvm.intr.experimental.noalias.scope.decl #alias_scope1
+ // CHECK: store {{.*}}, !alias.scope ![[SCOPES1]], !noalias ![[SCOPES23:[0-9]+]]
+ llvm.store %0, %arg1 {alias_scopes = [#alias_scope1], noalias_scopes = [#alias_scope2, #alias_scope3]} : i32, !llvm.ptr
+ // CHECK: load {{.*}}, !alias.scope ![[SCOPES2:[0-9]+]], !noalias ![[SCOPES13:[0-9]+]]
+ %1 = llvm.load %arg1 {alias_scopes = [#alias_scope2], noalias_scopes = [#alias_scope1, #alias_scope3]} : !llvm.ptr -> i32
+ // CHECK: atomicrmw {{.*}}, !alias.scope ![[SCOPES3:[0-9]+]], !noalias ![[SCOPES12:[0-9]+]]
+ %2 = llvm.atomicrmw add %arg1, %0 monotonic {alias_scopes = [#alias_scope3], noalias_scopes = [#alias_scope1, #alias_scope2]} : !llvm.ptr, i32
+ // CHECK: cmpxchg {{.*}}, !alias.scope ![[SCOPES3]]
+ %3 = llvm.cmpxchg %arg1, %1, %2 acq_rel monotonic {alias_scopes = [#alias_scope3]} : !llvm.ptr, i32
+ %5 = llvm.mlir.constant(42 : i8) : i8
+ // CHECK: llvm.memcpy{{.*}}, !alias.scope ![[SCOPES3]]
+ "llvm.intr.memcpy"(%arg1, %arg1, %0) <{isVolatile = false}> {alias_scopes = [#alias_scope3]} : (!llvm.ptr, !llvm.ptr, i32) -> ()
+ // CHECK: llvm.memset{{.*}}, !noalias ![[SCOPES3]]
+ "llvm.intr.memset"(%arg1, %5, %0) <{isVolatile = false}> {noalias_scopes = [#alias_scope3]} : (!llvm.ptr, i8, i32) -> ()
+ // CHECK: call void @foo({{.*}} !alias.scope ![[SCOPES3]]
+ llvm.call @foo(%arg1) {alias_scopes = [#alias_scope3]} : (!llvm.ptr) -> ()
+ // CHECK: call void @foo({{.*}} !noalias ![[SCOPES3]]
+ llvm.call @foo(%arg1) {noalias_scopes = [#alias_scope3]} : (!llvm.ptr) -> ()
+ llvm.return
+}
+
+// Check the intrinsic declarations.
+// CHECK-DAG: declare void @llvm.experimental.noalias.scope.decl(metadata)
+// CHECK-DAG: declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg)
+// CHECK-DAG: declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg)
+
+// Check the translated metadata.
+// CHECK-DAG: ![[DOMAIN:[0-9]+]] = !{!"domain1", !"The domain"}
+// CHECK-DAG: ![[SCOPE1:[0-9]+]] = !{!"scope1", ![[DOMAIN]], !"The first scope"}
+// CHECK-DAG: ![[SCOPE2:[0-9]+]] = !{!"scope2", ![[DOMAIN]]}
+// CHECK-DAG: ![[SCOPE3:[0-9]+]] = !{!"scope3", ![[DOMAIN]]}
+// CHECK-DAG: ![[SCOPES1]] = !{![[SCOPE1]]}
+// CHECK-DAG: ![[SCOPES2]] = !{![[SCOPE2]]}
+// CHECK-DAG: ![[SCOPES3]] = !{![[SCOPE3]]}
+// CHECK-DAG: ![[SCOPES12]] = !{![[SCOPE1]], ![[SCOPE2]]}
+// CHECK-DAG: ![[SCOPES13]] = !{![[SCOPE1]], ![[SCOPE3]]}
+// CHECK-DAG: ![[SCOPES23]] = !{![[SCOPE2]], ![[SCOPE3]]}
More information about the Mlir-commits
mailing list