[Mlir-commits] [mlir] 56d94a9 - [mlir][llvm] Add experimental alias scope decl intrinsic.
Tobias Gysi
llvmlistbot at llvm.org
Wed Mar 22 02:26:20 PDT 2023
Author: Tobias Gysi
Date: 2023-03-22T10:21:09+01:00
New Revision: 56d94a90dbbf1845ec71cd749691c74c1dd8a3ef
URL: https://github.com/llvm/llvm-project/commit/56d94a90dbbf1845ec71cd749691c74c1dd8a3ef
DIFF: https://github.com/llvm/llvm-project/commit/56d94a90dbbf1845ec71cd749691c74c1dd8a3ef.diff
LOG: [mlir][llvm] Add experimental alias scope decl intrinsic.
The revision adds the llvm.experimental.noalias.scope.decl intrinsic
to the LLVM dialect and updates the import and export accordingly.
Reviewed By: Dinistro
Differential Revision: https://reviews.llvm.org/D146504
Added:
Modified:
mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
mlir/include/mlir/Target/LLVMIR/ModuleImport.h
mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
mlir/lib/Target/LLVMIR/ModuleImport.cpp
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
mlir/test/Dialect/LLVMIR/roundtrip.mlir
mlir/test/Target/LLVMIR/Import/import-failure.ll
mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll
mlir/test/Target/LLVMIR/llvmir.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index 1b62ce0ca3e6e..391de1ffaa5dc 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -167,6 +167,31 @@ def LLVM_MemsetOp : LLVM_ZeroResultIntrOp<"memset", [0, 2], [],
>];
}
+def LLVM_NoAliasScopeDeclOp
+ : LLVM_ZeroResultIntrOp<"experimental.noalias.scope.decl"> {
+ let arguments = (ins SymbolRefAttr:$scope);
+ string llvmBuilder = [{
+ // Wrap the scope argument into a list since the LLVM IR intrinsic takes
+ // a list containing exactly one scope rather than a scope itself.
+ llvm::MDNode* node = moduleTranslation.getAliasScopes(op, {$scope});
+ builder.CreateNoAliasScopeDeclaration(node);
+ }];
+ string mlirBuilder = [{
+ FailureOr<SmallVector<SymbolRefAttr>> scopeAttrs =
+ moduleImport.matchAliasScopeAttrs(llvmOperands[0]);
+ // Drop the intrinsic if the alias scope translation fails since the scope
+ // is not used by an aliasing operation, such as a load or store, that is
+ // used to convert the alias scope metadata.
+ if (failed(scopeAttrs))
+ return success();
+ if (scopeAttrs->size() != 1)
+ return failure();
+ $_op = $_builder.create<LLVM::NoAliasScopeDeclOp>(
+ $_location, (*scopeAttrs)[0]);
+ }];
+ let assemblyFormat = "$scope attr-dict";
+}
+
//===----------------------------------------------------------------------===//
// Lifetime Markers
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
index be4f6e5717b11..e1a94d6b80cc9 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
@@ -135,6 +135,11 @@ class ModuleImport {
/// fails.
DILocalVariableAttr matchLocalVariableAttr(llvm::Value *value);
+ /// Converts `value` to an array of symbol references pointing to alias scope
+ /// operations, or returns failure if the conversion fails.
+ FailureOr<SmallVector<SymbolRefAttr>>
+ matchAliasScopeAttrs(llvm::Value *value);
+
/// Translates the debug location.
Location translateLoc(llvm::DILocation *loc);
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
index 67091257a3cf9..a04e285af580e 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
@@ -122,9 +122,14 @@ class ModuleTranslation {
void forgetMapping(Region ®ion);
/// Returns the LLVM metadata corresponding to a symbol reference to an mlir
- /// LLVM dialect alias scope operation
+ /// LLVM dialect alias scope operation.
llvm::MDNode *getAliasScope(Operation *op, SymbolRefAttr aliasScopeRef) const;
+ /// Returns the LLVM metadata corresponding to an array of symbol references
+ /// to mlir LLVM dialect alias scope operations.
+ llvm::MDNode *getAliasScopes(Operation *op,
+ ArrayRef<SymbolRefAttr> aliasScopeRefs) const;
+
// Sets LLVM metadata for memory operations that are in a parallel loop.
void setAccessGroupsMetadata(AccessGroupOpInterface op,
llvm::Instruction *inst);
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index a45768726bc43..d3ac7dcc17554 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1215,6 +1215,13 @@ DILocalVariableAttr ModuleImport::matchLocalVariableAttr(llvm::Value *value) {
return debugImporter->translate(node);
}
+FailureOr<SmallVector<SymbolRefAttr>>
+ModuleImport::matchAliasScopeAttrs(llvm::Value *value) {
+ auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
+ auto *node = cast<llvm::MDNode>(nodeAsVal->getMetadata());
+ return lookupAliasScopeAttrs(node);
+}
+
Location ModuleImport::translateLoc(llvm::DILocation *loc) {
return debugImporter->translateLoc(loc);
}
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index ca5fb7dda3841..7159aa49540ef 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1065,16 +1065,22 @@ ModuleTranslation::getAliasScope(Operation *op,
return aliasScopeMetadataMapping.lookup(aliasScopeOp);
}
+llvm::MDNode *ModuleTranslation::getAliasScopes(
+ Operation *op, ArrayRef<SymbolRefAttr> aliasScopeRefs) const {
+ SmallVector<llvm::Metadata *> nodes;
+ nodes.reserve(aliasScopeRefs.size());
+ for (SymbolRefAttr aliasScopeRef : aliasScopeRefs)
+ nodes.push_back(getAliasScope(op, aliasScopeRef));
+ return llvm::MDNode::get(getLLVMContext(), nodes);
+}
+
void ModuleTranslation::setAliasScopeMetadata(AliasAnalysisOpInterface op,
llvm::Instruction *inst) {
- auto populateScopeMetadata = [&](ArrayAttr scopeRefs, unsigned kind) {
- if (!scopeRefs || scopeRefs.empty())
+ auto populateScopeMetadata = [&](ArrayAttr aliasScopeRefs, unsigned kind) {
+ if (!aliasScopeRefs || aliasScopeRefs.empty())
return;
- llvm::Module *module = inst->getModule();
- SmallVector<llvm::Metadata *> scopeMDs;
- for (SymbolRefAttr scopeRef : scopeRefs.getAsRange<SymbolRefAttr>())
- scopeMDs.push_back(getAliasScope(op, scopeRef));
- llvm::MDNode *node = llvm::MDNode::get(module->getContext(), scopeMDs);
+ llvm::MDNode *node = getAliasScopes(
+ op, llvm::to_vector(aliasScopeRefs.getAsRange<SymbolRefAttr>()));
inst->setMetadata(kind, node);
};
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index c9db19b409e25..9147027c9d4b2 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -596,3 +596,15 @@ llvm.func @stackrestore_opaque_pointers(%arg0: !llvm.ptr) {
llvm.intr.stackrestore %arg0 : !llvm.ptr
llvm.return
}
+
+// CHECK-LABEL: @experimental_noalias_scope_decl
+llvm.func @experimental_noalias_scope_decl() {
+ // CHECK: llvm.intr.experimental.noalias.scope.decl @metadata::@scope
+ llvm.intr.experimental.noalias.scope.decl @metadata::@scope
+ llvm.return
+}
+
+llvm.metadata @metadata {
+ llvm.alias_scope_domain @domain {description = "The domain"}
+ llvm.alias_scope @scope {domain = @domain, description = "The first scope"}
+}
diff --git a/mlir/test/Target/LLVMIR/Import/import-failure.ll b/mlir/test/Target/LLVMIR/Import/import-failure.ll
index 16f2cf2b6283c..b330f654d3d51 100644
--- a/mlir/test/Target/LLVMIR/Import/import-failure.ll
+++ b/mlir/test/Target/LLVMIR/Import/import-failure.ll
@@ -322,3 +322,18 @@ bb2:
}
!0 = !{!"function_entry_count", i64 42}
+
+; // -----
+
+; CHECK: import-failure.ll
+; CHECK-SAME: warning: dropped instruction: call void @llvm.experimental.noalias.scope.decl(metadata !0)
+define void @unused_scope() {
+ call void @llvm.experimental.noalias.scope.decl(metadata !0)
+ ret void
+}
+
+declare void @llvm.experimental.noalias.scope.decl(metadata)
+
+!0 = !{!1}
+!1 = !{!1, !2}
+!2 = distinct !{!2, !"The domain"}
diff --git a/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll b/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll
index a9ed8e9ee556f..eb74b0ab880bb 100644
--- a/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll
+++ b/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll
@@ -62,27 +62,34 @@ define void @two_domains(ptr %arg1) {
; // -----
+; CHECK: llvm.metadata @__llvm_global_metadata {
+; CHECK: llvm.alias_scope_domain @[[DOMAIN:.*]] {description = "The domain"}
+; CHECK: llvm.alias_scope @[[$SCOPE:.*]] {domain = @[[DOMAIN]]}
+; CHECK: }
+
; CHECK-LABEL: llvm.func @supported_ops
define void @supported_ops(ptr %arg1, float %arg2, i32 %arg3, i32 %arg4) {
- ; CHECK: llvm.load {{.*}}alias_scopes =
- %1 = load i32, ptr %arg1, !alias.scope !3
- ; CHECK: llvm.store {{.*}}alias_scopes =
- store i32 %1, ptr %arg1, !alias.scope !3
- ; CHECK: llvm.atomicrmw {{.*}}alias_scopes =
- %2 = atomicrmw fmax ptr %arg1, float %arg2 acquire, !alias.scope !3
- ; CHECK: llvm.cmpxchg {{.*}}alias_scopes =
- %3 = cmpxchg ptr %arg1, i32 %arg3, i32 %arg4 monotonic seq_cst, !alias.scope !3
- ; CHECK: "llvm.intr.memcpy"{{.*}}alias_scopes =
- call void @llvm.memcpy.p0.p0.i32(ptr %arg1, ptr %arg1, i32 4, i1 false), !alias.scope !3
- ; CHECK: "llvm.intr.memset"{{.*}}alias_scopes =
- call void @llvm.memset.p0.i32(ptr %arg1, i8 42, i32 4, i1 false), !alias.scope !3
+ ; CHECK: llvm.intr.experimental.noalias.scope.decl @__llvm_global_metadata::@[[$SCOPE]]
+ call void @llvm.experimental.noalias.scope.decl(metadata !2)
+ ; CHECK: llvm.load {{.*}}alias_scopes = [@__llvm_global_metadata::@[[$SCOPE]]]
+ %1 = load i32, ptr %arg1, !alias.scope !2
+ ; CHECK: llvm.store {{.*}}alias_scopes = [@__llvm_global_metadata::@[[$SCOPE]]]
+ store i32 %1, ptr %arg1, !alias.scope !2
+ ; CHECK: llvm.atomicrmw {{.*}}alias_scopes = [@__llvm_global_metadata::@[[$SCOPE]]]
+ %2 = atomicrmw fmax ptr %arg1, float %arg2 acquire, !alias.scope !2
+ ; CHECK: llvm.cmpxchg {{.*}}alias_scopes = [@__llvm_global_metadata::@[[$SCOPE]]]
+ %3 = cmpxchg ptr %arg1, i32 %arg3, i32 %arg4 monotonic seq_cst, !alias.scope !2
+ ; CHECK: "llvm.intr.memcpy"{{.*}}alias_scopes = [@__llvm_global_metadata::@[[$SCOPE]]]
+ call void @llvm.memcpy.p0.p0.i32(ptr %arg1, ptr %arg1, i32 4, i1 false), !alias.scope !2
+ ; CHECK: "llvm.intr.memset"{{.*}}alias_scopes = [@__llvm_global_metadata::@[[$SCOPE]]]
+ call void @llvm.memset.p0.i32(ptr %arg1, i8 42, i32 4, i1 false), !alias.scope !2
ret void
}
+declare void @llvm.experimental.noalias.scope.decl(metadata)
declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg)
declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg)
!0 = distinct !{!0, !"The domain"}
-!1 = distinct !{!1}
-!2 = !{!2, !0}
-!3 = !{!2}
+!1 = !{!1, !0}
+!2 = !{!1}
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index ce65ff995709c..46120cb348296 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -2016,38 +2016,41 @@ llvm.func @switch_weights(%arg0: i32) -> i32 {
// -----
-module {
- llvm.func @aliasScope(%arg1 : !llvm.ptr) {
- %0 = llvm.mlir.constant(0 : i32) : i32
- llvm.store %0, %arg1 {alias_scopes = [@metadata::@scope1], noalias_scopes = [@metadata::@scope2, @metadata::@scope3]} : i32, !llvm.ptr
- %1 = llvm.load %arg1 {alias_scopes = [@metadata::@scope2], noalias_scopes = [@metadata::@scope1, @metadata::@scope3]} : !llvm.ptr -> i32
- %2 = llvm.atomicrmw add %arg1, %0 monotonic {alias_scopes = [@metadata::@scope3], noalias_scopes = [@metadata::@scope1, @metadata::@scope2]} : !llvm.ptr, i32
- %3 = llvm.cmpxchg %arg1, %1, %2 acq_rel monotonic {alias_scopes = [@metadata::@scope3]} : !llvm.ptr, i32
- %4 = llvm.mlir.constant(0 : i1) : i1
- %5 = llvm.mlir.constant(42 : i8) : i8
- "llvm.intr.memcpy"(%arg1, %arg1, %0, %4) {alias_scopes = [@metadata::@scope3]} : (!llvm.ptr, !llvm.ptr, i32, i1) -> ()
- "llvm.intr.memset"(%arg1, %5, %0, %4) {noalias_scopes = [@metadata::@scope3]} : (!llvm.ptr, i8, i32, i1) -> ()
- llvm.return
- }
-
- llvm.metadata @metadata {
- llvm.alias_scope_domain @domain {description = "The domain"}
- llvm.alias_scope @scope1 {domain = @domain, description = "The first scope"}
- llvm.alias_scope @scope2 {domain = @domain}
- llvm.alias_scope @scope3 {domain = @domain}
- }
-}
-
-// Function
// CHECK-LABEL: aliasScope
-// CHECK: store {{.*}}, !alias.scope ![[SCOPES1:[0-9]+]], !noalias ![[SCOPES23:[0-9]+]]
-// CHECK: load {{.*}}, !alias.scope ![[SCOPES2:[0-9]+]], !noalias ![[SCOPES13:[0-9]+]]
-// CHECK: atomicrmw {{.*}}, !alias.scope ![[SCOPES3:[0-9]+]], !noalias ![[SCOPES12:[0-9]+]]
-// CHECK: cmpxchg {{.*}}, !alias.scope ![[SCOPES3]]
-// CHECK: llvm.memcpy{{.*}}, !alias.scope ![[SCOPES3]]
-// CHECK: llvm.memset{{.*}}, !noalias ![[SCOPES3]]
-
-// Metadata
+llvm.func @aliasScope(%arg1 : !llvm.ptr) {
+ %0 = llvm.mlir.constant(0 : i32) : i32
+ // CHECK: call void @llvm.experimental.noalias.scope.decl(metadata ![[SCOPES1:[0-9]+]])
+ llvm.intr.experimental.noalias.scope.decl @metadata::@scope1
+ // CHECK: store {{.*}}, !alias.scope ![[SCOPES1]], !noalias ![[SCOPES23:[0-9]+]]
+ llvm.store %0, %arg1 {alias_scopes = [@metadata::@scope1], noalias_scopes = [@metadata::@scope2, @metadata::@scope3]} : i32, !llvm.ptr
+ // CHECK: load {{.*}}, !alias.scope ![[SCOPES2:[0-9]+]], !noalias ![[SCOPES13:[0-9]+]]
+ %1 = llvm.load %arg1 {alias_scopes = [@metadata::@scope2], noalias_scopes = [@metadata::@scope1, @metadata::@scope3]} : !llvm.ptr -> i32
+ // CHECK: atomicrmw {{.*}}, !alias.scope ![[SCOPES3:[0-9]+]], !noalias ![[SCOPES12:[0-9]+]]
+ %2 = llvm.atomicrmw add %arg1, %0 monotonic {alias_scopes = [@metadata::@scope3], noalias_scopes = [@metadata::@scope1, @metadata::@scope2]} : !llvm.ptr, i32
+ // CHECK: cmpxchg {{.*}}, !alias.scope ![[SCOPES3]]
+ %3 = llvm.cmpxchg %arg1, %1, %2 acq_rel monotonic {alias_scopes = [@metadata::@scope3]} : !llvm.ptr, i32
+ %4 = llvm.mlir.constant(0 : i1) : i1
+ %5 = llvm.mlir.constant(42 : i8) : i8
+ // CHECK: llvm.memcpy{{.*}}, !alias.scope ![[SCOPES3]]
+ "llvm.intr.memcpy"(%arg1, %arg1, %0, %4) {alias_scopes = [@metadata::@scope3]} : (!llvm.ptr, !llvm.ptr, i32, i1) -> ()
+ // CHECK: llvm.memset{{.*}}, !noalias ![[SCOPES3]]
+ "llvm.intr.memset"(%arg1, %5, %0, %4) {noalias_scopes = [@metadata::@scope3]} : (!llvm.ptr, i8, i32, i1) -> ()
+ llvm.return
+}
+
+llvm.metadata @metadata {
+ llvm.alias_scope_domain @domain {description = "The domain"}
+ llvm.alias_scope @scope1 {domain = @domain, description = "The first scope"}
+ llvm.alias_scope @scope2 {domain = @domain}
+ llvm.alias_scope @scope3 {domain = @domain}
+}
+
+// Check the intrinsic declarations.
+// CHECK-DAG: declare void @llvm.experimental.noalias.scope.decl(metadata)
+// CHECK-DAG: declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg)
+// CHECK-DAG: declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg)
+
+// Check the translated metadata.
// CHECK-DAG: ![[DOMAIN:[0-9]+]] = distinct !{![[DOMAIN]], !"The domain"}
// CHECK-DAG: ![[SCOPE1:[0-9]+]] = distinct !{![[SCOPE1]], ![[DOMAIN]], !"The first scope"}
// CHECK-DAG: ![[SCOPE2:[0-9]+]] = distinct !{![[SCOPE2]], ![[DOMAIN]]}
@@ -2059,7 +2062,6 @@ module {
// CHECK-DAG: ![[SCOPES13]] = !{![[SCOPE1]], ![[SCOPE3]]}
// CHECK-DAG: ![[SCOPES23]] = !{![[SCOPE2]], ![[SCOPE3]]}
-
// -----
// It is okay to have repeated successors if they have no arguments.
More information about the Mlir-commits
mailing list