[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