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 <[email protected]> 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]]} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
