[llvm-branch-commits] [mlir] [mlir][LLVM] Use a disjoint scope domain when inlining noalias (PR #218773)
Krzysztof Drewniak via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 25 21:38:50 PDT 2026
https://github.com/krzysz00 updated https://github.com/llvm/llvm-project/pull/218773
>From f50a689134a1b391655125be0d3201e8a40be3c1 Mon Sep 17 00:00:00 2001
From: Krzysztof Drewniak <Krzysztof.Drewniak at amd.com>
Date: Thu, 20 Aug 2026 22:54:40 +0000
Subject: [PATCH] [mlir][LLVM] Use a disjoint scope domain when inlining
noalias
This matches recent changes to the LLVM inliner.
AI disclosure: Claude wrote the code, I wrote the commit message and
have done initial review.
---
.../Transforms/InlinerInterfaceImpl.cpp | 53 ++++++++++---------
.../Dialect/LLVMIR/inlining-alias-scopes.mlir | 28 ++++------
2 files changed, 38 insertions(+), 43 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
index a1b2a6adbfc9d..e301da5338ca6 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
@@ -309,9 +309,12 @@ static void createNewAliasScopesFromNoAliasParameter(
return;
// Create a new domain for this specific inlining and a new scope for every
- // noalias parameter.
+ // noalias parameter. The scopes are disjoint, since an access based on one
+ // noalias parameter can't reach memory an access based on another one
+ // reaches.
auto functionDomain = LLVM::AliasScopeDomainAttr::get(
- call->getContext(), cast<LLVM::CallOp>(call).getCalleeAttr().getAttr());
+ call->getContext(), cast<LLVM::CallOp>(call).getCalleeAttr().getAttr(),
+ /*disjointScopes=*/true);
DenseMap<Value, LLVM::AliasScopeAttr> pointerScopes;
for (LLVM::SSACopyOp copyOp : noAliasParams) {
auto scope = LLVM::AliasScopeAttr::get(functionDomain);
@@ -369,21 +372,6 @@ static void createNewAliasScopesFromNoAliasParameter(
}))
return;
- // Add all noalias parameter scopes to the noalias scope list that we are
- // not based on.
- SmallVector<Attribute> noAliasScopes;
- for (LLVM::SSACopyOp noAlias : noAliasParams) {
- if (basedOnPointers.contains(noAlias))
- continue;
-
- noAliasScopes.push_back(pointerScopes[noAlias]);
- }
-
- if (!noAliasScopes.empty())
- aliasInterface.setNoAliasScopes(
- concatArrayAttr(aliasInterface.getNoAliasScopesOrNull(),
- ArrayAttr::get(call->getContext(), noAliasScopes)));
-
// Don't add alias scopes to call operations or operations that might
// operate on pointers not based on any noalias parameter.
// Since we add all scopes to an operation's noalias list that it
@@ -408,19 +396,34 @@ static void createNewAliasScopesFromNoAliasParameter(
// Call operations are included in this list since we do not know whether
// the callee accesses any memory besides the ones passed as its
// arguments.
- if (aliasesOtherKnownObject ||
- isa<LLVM::CallOp>(aliasInterface.getOperation()))
- return;
-
SmallVector<Attribute> aliasScopes;
- for (LLVM::SSACopyOp noAlias : noAliasParams)
- if (basedOnPointers.contains(noAlias))
- aliasScopes.push_back(pointerScopes[noAlias]);
+ if (!aliasesOtherKnownObject &&
+ !isa<LLVM::CallOp>(aliasInterface.getOperation()))
+ for (LLVM::SSACopyOp noAlias : noAliasParams)
+ if (basedOnPointers.contains(noAlias))
+ aliasScopes.push_back(pointerScopes[noAlias]);
- if (!aliasScopes.empty())
+ if (!aliasScopes.empty()) {
aliasInterface.setAliasScopes(
concatArrayAttr(aliasInterface.getAliasScopesOrNull(),
ArrayAttr::get(call->getContext(), aliasScopes)));
+ return;
+ }
+
+ // Add all noalias parameter scopes to the noalias scope list that we are
+ // not based on.
+ SmallVector<Attribute> noAliasScopes;
+ for (LLVM::SSACopyOp noAlias : noAliasParams) {
+ if (basedOnPointers.contains(noAlias))
+ continue;
+
+ noAliasScopes.push_back(pointerScopes[noAlias]);
+ }
+
+ if (!noAliasScopes.empty())
+ aliasInterface.setNoAliasScopes(
+ concatArrayAttr(aliasInterface.getNoAliasScopesOrNull(),
+ ArrayAttr::get(call->getContext(), noAliasScopes)));
});
}
}
diff --git a/mlir/test/Dialect/LLVMIR/inlining-alias-scopes.mlir b/mlir/test/Dialect/LLVMIR/inlining-alias-scopes.mlir
index 6b369c5012105..a4363b432d4a3 100644
--- a/mlir/test/Dialect/LLVMIR/inlining-alias-scopes.mlir
+++ b/mlir/test/Dialect/LLVMIR/inlining-alias-scopes.mlir
@@ -208,7 +208,7 @@ llvm.func @caller(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
// -----
-// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
+// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}disjointScopes = true{{.*}}>
// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
@@ -223,10 +223,8 @@ llvm.func @foo(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr {llvm.noalias})
// CHECK-LABEL: llvm.func @bar
// CHECK: llvm.load
// CHECK-SAME: alias_scopes = [#[[$ARG1_SCOPE]]]
-// CHECK-SAME: noalias_scopes = [#[[$ARG0_SCOPE]]]
// CHECK: llvm.store
// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]]]
-// CHECK-SAME: noalias_scopes = [#[[$ARG1_SCOPE]]]
llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
llvm.call @foo(%arg0, %arg2) : (!llvm.ptr, !llvm.ptr) -> ()
llvm.return
@@ -234,7 +232,7 @@ llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
// -----
-// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
+// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}disjointScopes = true{{.*}}>
// CHECK-DAG: #[[$ARG_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
llvm.func @foo(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr) {
@@ -257,7 +255,7 @@ llvm.func @missing_noalias_on_one_ptr(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2:
// -----
-// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
+// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}disjointScopes = true{{.*}}>
// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
@@ -284,7 +282,7 @@ llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
// -----
-// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
+// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}disjointScopes = true{{.*}}>
// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
@@ -313,7 +311,7 @@ llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
// -----
-// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
+// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}disjointScopes = true{{.*}}>
// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
@@ -338,7 +336,6 @@ llvm.func @region_branch(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr {llvm
// CHECK-LABEL: llvm.func @region_branch_inlining
// CHECK: llvm.store
// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]]]
-// CHECK-SAME: noalias_scopes = [#[[$ARG1_SCOPE]]]
llvm.func @region_branch_inlining(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
llvm.call @region_branch(%arg0, %arg2) : (!llvm.ptr, !llvm.ptr) -> ()
llvm.return
@@ -367,7 +364,7 @@ llvm.func @missing_region_branch_inlining(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %a
// -----
-// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
+// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}disjointScopes = true{{.*}}>
// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
@@ -399,7 +396,7 @@ llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
// -----
-// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
+// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}disjointScopes = true{{.*}}>
// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
@@ -434,7 +431,7 @@ llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
// -----
-// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
+// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}disjointScopes = true{{.*}}>
// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
@@ -455,10 +452,8 @@ llvm.func @supported_operations(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.pt
// CHECK-LABEL: llvm.func @bar
// CHECK: llvm.store
// CHECK-SAME: alias_scopes = [#[[$ARG1_SCOPE]]]
-// CHECK-SAME: noalias_scopes = [#[[$ARG0_SCOPE]]]
// CHECK: llvm.load
// CHECK-SAME: alias_scopes = [#[[$ARG1_SCOPE]]]
-// CHECK-SAME: noalias_scopes = [#[[$ARG0_SCOPE]]]
// CHECK: "llvm.intr.memcpy"
// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]], #[[$ARG1_SCOPE]]]
// CHECK-NOT: noalias_scopes
@@ -470,13 +465,10 @@ llvm.func @supported_operations(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.pt
// CHECK-NOT: noalias_scopes
// CHECK: "llvm.intr.memset"
// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]]]
-// CHECK-SAME: noalias_scopes = [#[[$ARG1_SCOPE]]]
// CHECK: llvm.cmpxchg
// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]]]
-// CHECK-SAME: noalias_scopes = [#[[$ARG1_SCOPE]]]
// CHECK: llvm.atomicrmw
// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]]]
-// CHECK-SAME: noalias_scopes = [#[[$ARG1_SCOPE]]]
llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
llvm.call @supported_operations(%arg0, %arg2) : (!llvm.ptr, !llvm.ptr) -> ()
llvm.return
@@ -484,7 +476,7 @@ llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
// -----
-// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
+// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}disjointScopes = true{{.*}}>
// CHECK-DAG: #[[$ARG_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
llvm.func @foo(%arg: i32)
@@ -511,7 +503,7 @@ llvm.func @noalias_with_region(%arg0: !llvm.ptr) {
// -----
-// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
+// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}disjointScopes = true{{.*}}>
// CHECK-DAG: #[[$ARG_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
llvm.func @foo(%arg: i32)
More information about the llvm-branch-commits
mailing list