[llvm-branch-commits] [mlir] [mlir][LLVM] Add disjointScopes to AliasScopeDomainAttr (PR #218772)
Krzysztof Drewniak via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 25 21:38:49 PDT 2026
https://github.com/krzysz00 updated https://github.com/llvm/llvm-project/pull/218772
>From 8194eb265231562365dfb132544b4d1c2572e90a Mon Sep 17 00:00:00 2001
From: Krzysztof Drewniak <Krzysztof.Drewniak at amd.com>
Date: Thu, 20 Aug 2026 22:36:30 +0000
Subject: [PATCH] [mlir][LLVM] Add disjointScopes to AliasScopeDomainAttr
This also updates the MLIR-side inliner to clone disjoint domains
while cloning alias scopes, matching changes to LLVM.
AI disclosure: Claude wrote the code, I wrote the commit message and
looked at the code.
---
.../mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 19 ++++++++++++--
.../Transforms/InlinerInterfaceImpl.cpp | 5 +++-
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 6 +++--
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 4 +--
.../LLVMIR/Import/metadata-alias-scopes.ll | 25 +++++++++++++++++++
.../Target/LLVMIR/attribute-alias-scopes.mlir | 23 +++++++++++++++++
6 files changed, 75 insertions(+), 7 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 88888e5c462b9..0a719600b8764 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -1098,12 +1098,15 @@ def LLVM_AliasScopeDomainAttr : LLVM_Attr<"AliasScopeDomain",
"alias_scope_domain"> {
let parameters = (ins
"Attribute":$id,
+ DefaultValuedParameter<"bool", "false">:$disjointScopes,
OptionalParameter<"StringAttr">:$description
);
let builders = [
- AttrBuilder<(ins CArg<"StringAttr", "{}">:$description), [{
- return $_get($_ctxt, DistinctAttr::create(UnitAttr::get($_ctxt)), description);
+ AttrBuilder<(ins CArg<"StringAttr", "{}">:$description,
+ CArg<"bool", "false">:$disjointScopes), [{
+ return $_get($_ctxt, DistinctAttr::create(UnitAttr::get($_ctxt)),
+ disjointScopes, description);
}]>
];
@@ -1112,6 +1115,18 @@ def LLVM_AliasScopeDomainAttr : LLVM_Attr<"AliasScopeDomain",
let description = [{
Defines a domain that may be associated with an alias scope.
+ If `disjointScopes` is set, the scopes of this domain are disjoint: an
+ operation listing some of them in its `alias_scopes` is implicitly in the
+ `noalias_scopes` of every other scope of this domain, so those complements
+ need not be spelled out.
+
+ Example:
+ ```mlir
+ #domain = #llvm.alias_scope_domain<id = distinct[0]<>, disjointScopes = true>
+ #scope1 = #llvm.alias_scope<id = distinct[1]<>, domain = #domain>
+ #scope2 = #llvm.alias_scope<id = distinct[2]<>, domain = #domain>
+ ```
+
See the following link for more details:
https://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata
}];
diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
index 657835ae54149..a1b2a6adbfc9d 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
@@ -166,8 +166,11 @@ deepCloneAliasScopes(iterator_range<Region::iterator> inlinedBlocks) {
// attribute to make sure that new instances are always created by the
// uniquer.
walker.addWalk([&](LLVM::AliasScopeDomainAttr domainAttr) {
+ // The clones of a duplicated access have to stay noalias with each
+ // other, so the clone keeps whether the scopes are disjoint.
mapping[domainAttr] = LLVM::AliasScopeDomainAttr::get(
- domainAttr.getContext(), domainAttr.getDescription());
+ domainAttr.getContext(), domainAttr.getDescription(),
+ domainAttr.getDisjointScopes());
});
walker.addWalk([&](LLVM::AliasScopeAttr scopeAttr) {
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index bdd2a0b10ae1f..8d16e76474b90 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -562,12 +562,14 @@ ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) {
// Helper that creates an alias scope domain attribute.
auto createAliasScopeDomainOp = [&](const llvm::MDNode *aliasDomain) {
+ llvm::AliasScopeDomainNode domainNode(aliasDomain);
StringAttr description = nullptr;
- StringRef name = llvm::AliasScopeDomainNode(aliasDomain).getName();
+ StringRef name = domainNode.getName();
if (!name.empty())
description = builder.getStringAttr(name);
Attribute idAttr = getIdAttr(aliasDomain);
- return builder.getAttr<AliasScopeDomainAttr>(idAttr, description);
+ return builder.getAttr<AliasScopeDomainAttr>(
+ idAttr, domainNode.hasDisjointScopes(), description);
};
// Collect the alias scopes and domains to translate them.
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 59c88027585bb..a0f2d52f356c9 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -2289,8 +2289,8 @@ ModuleTranslation::getOrCreateAliasScope(AliasScopeAttr aliasScopeAttr) {
llvm::SmallVector<llvm::Metadata *, 3> operands;
// Placeholder for potential self-reference.
operands.push_back(dummy.get());
- operands.push_back(
- llvm::ConstantAsMetadata::get(llvm::ConstantInt::getFalse(ctx)));
+ operands.push_back(llvm::ConstantAsMetadata::get(llvm::ConstantInt::getBool(
+ ctx, aliasScopeAttr.getDomain().getDisjointScopes())));
if (StringAttr description = aliasScopeAttr.getDomain().getDescription())
operands.push_back(llvm::MDString::get(ctx, description));
domainIt->second = llvm::MDNode::get(ctx, operands);
diff --git a/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll b/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll
index fcdbcfcc7e499..cce35c7b74c19 100644
--- a/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll
+++ b/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll
@@ -127,3 +127,28 @@ define void @alias_scope(ptr %arg1) {
!7 = !{!2, !3}
!8 = !{!1, !3}
!9 = !{!1, !2}
+
+; // -----
+
+; CHECK: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<id = {{.*}}, disjointScopes = true, description = "The disjoint domain">
+; CHECK: #[[$SCOPE0:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]>
+; CHECK: #[[$SCOPE1:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]>
+
+; CHECK-LABEL: llvm.func @disjoint_domain
+define void @disjoint_domain(ptr %arg1) {
+ ; CHECK: llvm.load
+ ; CHECK-SAME: alias_scopes = [#[[$SCOPE0]]]
+ ; CHECK-NOT: noalias_scopes
+ %1 = load i32, ptr %arg1, !alias.scope !3
+ ; CHECK: llvm.load
+ ; CHECK-SAME: alias_scopes = [#[[$SCOPE1]]]
+ ; CHECK-NOT: noalias_scopes
+ %2 = load i32, ptr %arg1, !alias.scope !4
+ ret void
+}
+
+!0 = distinct !{!0, i1 true, !"The disjoint domain"}
+!1 = distinct !{!1, !0}
+!2 = distinct !{!2, !0}
+!3 = !{!1}
+!4 = !{!2}
diff --git a/mlir/test/Target/LLVMIR/attribute-alias-scopes.mlir b/mlir/test/Target/LLVMIR/attribute-alias-scopes.mlir
index 34a049f9c7cfe..aa632a809a7bb 100644
--- a/mlir/test/Target/LLVMIR/attribute-alias-scopes.mlir
+++ b/mlir/test/Target/LLVMIR/attribute-alias-scopes.mlir
@@ -155,3 +155,26 @@ llvm.func @alias_scopes(%arg1 : !llvm.ptr) {
// CHECK-DAG: ![[SCOPES12]] = !{![[SCOPE1]], ![[SCOPE2]]}
// CHECK-DAG: ![[SCOPES13]] = !{![[SCOPE1]], ![[SCOPE3]]}
// CHECK-DAG: ![[SCOPES23]] = !{![[SCOPE2]], ![[SCOPE3]]}
+
+// -----
+
+#alias_scope_domain = #llvm.alias_scope_domain<id = distinct[0]<>, disjointScopes = true, description = "The disjoint domain">
+#alias_scope1 = #llvm.alias_scope<id = distinct[1]<>, domain = #alias_scope_domain>
+#alias_scope2 = #llvm.alias_scope<id = distinct[2]<>, domain = #alias_scope_domain>
+
+// CHECK-LABEL: @disjoint_alias_scopes
+llvm.func @disjoint_alias_scopes(%arg1 : !llvm.ptr, %arg2 : !llvm.ptr) {
+ %0 = llvm.mlir.constant(0 : i32) : i32
+ // CHECK: store {{.*}}, !alias.scope ![[SCOPES1:[0-9]+]]{{$}}
+ llvm.store %0, %arg1 {alias_scopes = [#alias_scope1]} : i32, !llvm.ptr
+ // CHECK: store {{.*}}, !alias.scope ![[SCOPES2:[0-9]+]]{{$}}
+ llvm.store %0, %arg2 {alias_scopes = [#alias_scope2]} : i32, !llvm.ptr
+ llvm.return
+}
+
+// Check the translated metadata.
+// CHECK-DAG: ![[DOMAIN:[0-9]+]] = distinct !{![[DOMAIN]], i1 true, !"The disjoint domain"}
+// CHECK-DAG: ![[SCOPE1:[0-9]+]] = distinct !{![[SCOPE1]], ![[DOMAIN]]}
+// CHECK-DAG: ![[SCOPE2:[0-9]+]] = distinct !{![[SCOPE2]], ![[DOMAIN]]}
+// CHECK-DAG: ![[SCOPES1]] = !{![[SCOPE1]]}
+// CHECK-DAG: ![[SCOPES2]] = !{![[SCOPE2]]}
More information about the llvm-branch-commits
mailing list