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