From 023dbbaa3eeddd537e2376aa7355e3bcef618908 Mon Sep 17 00:00:00 2001 From: "William S. Moses" Date: Tue, 7 Jan 2025 14:44:19 -0500 Subject: [PATCH 1/5] [MLIR] Enable import of non self referential alias scopes --- .../mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 6 ++- mlir/lib/Target/LLVMIR/ModuleImport.cpp | 32 +++++++++--- mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 21 ++++++-- mlir/test/Dialect/LLVMIR/roundtrip.mlir | 10 ++++ .../LLVMIR/Import/metadata-alias-scopes.ll | 35 +++++++++++++ .../Target/LLVMIR/attribute-alias-scopes.mlir | 51 +++++++++++++++++++ 6 files changed, 143 insertions(+), 12 deletions(-) diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td index e8eeafd09a9cb..68df6f64e51ea 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -825,7 +825,7 @@ def LLVM_MemoryEffectsAttr : LLVM_Attr<"MemoryEffects", "memory_effects"> { def LLVM_AliasScopeDomainAttr : LLVM_Attr<"AliasScopeDomain", "alias_scope_domain"> { let parameters = (ins - "DistinctAttr":$id, + "Attribute":$id, OptionalParameter<"StringAttr">:$description ); @@ -853,7 +853,7 @@ def LLVM_AliasScopeDomainAttr : LLVM_Attr<"AliasScopeDomain", def LLVM_AliasScopeAttr : LLVM_Attr<"AliasScope", "alias_scope"> { let parameters = (ins - "DistinctAttr":$id, + "Attribute":$id, "AliasScopeDomainAttr":$domain, OptionalParameter<"StringAttr">:$description ); @@ -891,6 +891,8 @@ def LLVM_AliasScopeAttr : LLVM_Attr<"AliasScope", "alias_scope"> { } ``` + The first attribute can either be a DistinctAttribute or a StringAttribute. + See the following link for more details: https://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata }]; diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index 95fb673fc72e3..e7e5825fd5b45 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -427,6 +427,11 @@ ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) { return node->getNumOperands() != 0 && node == dyn_cast(node->getOperand(0)); }; + auto verifySelfRefOrString = [](const llvm::MDNode *node) { + return node->getNumOperands() != 0 && + (node == dyn_cast(node->getOperand(0)) || + isa(node->getOperand(0))); + }; // Helper that verifies the given operand is a string or does not exist. auto verifyDescription = [](const llvm::MDNode *node, unsigned idx) { return idx >= node->getNumOperands() || @@ -438,8 +443,14 @@ ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) { if (aliasDomain->getNumOperands() >= 2) if (auto *operand = dyn_cast(aliasDomain->getOperand(1))) description = builder.getStringAttr(operand->getString()); - return builder.getAttr( - DistinctAttr::create(builder.getUnitAttr()), description); + Attribute idAttr; + if (verifySelfRef(aliasDomain)) { + idAttr = DistinctAttr::create(builder.getUnitAttr()); + } else { + auto name = cast(aliasDomain->getOperand(0)); + idAttr = builder.getStringAttr(name->getString()); + } + return builder.getAttr(idAttr, description); }; // Collect the alias scopes and domains to translate them. @@ -452,10 +463,11 @@ ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) { // verifying its domain. Perform the verification before looking it up in // the alias scope mapping since it could have been inserted as a domain // node before. - if (!verifySelfRef(scope) || !domain || !verifyDescription(scope, 2)) + if (!verifySelfRefOrString(scope) || !domain || + !verifyDescription(scope, 2)) return emitError(loc) << "unsupported alias scope node: " << diagMD(scope, llvmModule.get()); - if (!verifySelfRef(domain) || !verifyDescription(domain, 1)) + if (!verifySelfRefOrString(domain) || !verifyDescription(domain, 1)) return emitError(loc) << "unsupported alias domain node: " << diagMD(domain, llvmModule.get()); @@ -473,9 +485,17 @@ ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) { StringAttr description = nullptr; if (!aliasScope.getName().empty()) description = builder.getStringAttr(aliasScope.getName()); + Attribute idAttr; + if (verifySelfRef(scope)) { + idAttr = DistinctAttr::create(builder.getUnitAttr()); + } else { + auto Name = cast(scope->getOperand(0)); + idAttr = builder.getStringAttr(Name->getString()); + } + auto aliasScopeOp = builder.getAttr( - DistinctAttr::create(builder.getUnitAttr()), - cast(it->second), description); + idAttr, cast(it->second), description); + aliasScopeMapping.try_emplace(aliasScope.getNode(), aliasScopeOp); } } diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index ad62ae0cef57b..88d26a4f778a3 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -1724,25 +1724,38 @@ ModuleTranslation::getOrCreateAliasScope(AliasScopeAttr aliasScopeAttr) { aliasScopeAttr.getDomain(), nullptr); if (insertedDomain) { llvm::SmallVector operands; - // Placeholder for self-reference. + // Placeholder for potential self-reference. operands.push_back(dummy.get()); if (StringAttr description = aliasScopeAttr.getDomain().getDescription()) operands.push_back(llvm::MDString::get(ctx, description)); domainIt->second = llvm::MDNode::get(ctx, operands); // Self-reference for uniqueness. - domainIt->second->replaceOperandWith(0, domainIt->second); + llvm::Metadata *replacement; + if (auto stringAttr = + dyn_cast(aliasScopeAttr.getDomain().getId())) { + replacement = llvm::MDString::get(ctx, stringAttr.getValue()); + } else { + replacement = domainIt->second; + } + domainIt->second->replaceOperandWith(0, replacement); } // Convert the scope metadata node. assert(domainIt->second && "Scope's domain should already be valid"); llvm::SmallVector operands; - // Placeholder for self-reference. + // Placeholder for potential self-reference. operands.push_back(dummy.get()); operands.push_back(domainIt->second); if (StringAttr description = aliasScopeAttr.getDescription()) operands.push_back(llvm::MDString::get(ctx, description)); scopeIt->second = llvm::MDNode::get(ctx, operands); // Self-reference for uniqueness. - scopeIt->second->replaceOperandWith(0, scopeIt->second); + llvm::Metadata *replacement; + if (auto stringAttr = dyn_cast(aliasScopeAttr.getId())) { + replacement = llvm::MDString::get(ctx, stringAttr.getValue()); + } else { + replacement = scopeIt->second; + } + scopeIt->second->replaceOperandWith(0, replacement); return scopeIt->second; } diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir index aebfd7492093c..d254601932475 100644 --- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir +++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir @@ -750,6 +750,16 @@ llvm.func @experimental_noalias_scope_decl() { llvm.return } +#alias_scope_domain2 = #llvm.alias_scope_domain +#alias_scope2 = #llvm.alias_scope + +// CHECK-LABEL: @experimental_noalias_scope_decl +llvm.func @experimental_noalias_scope_decl2() { + // CHECK: llvm.intr.experimental.noalias.scope.decl #{{.*}} + llvm.intr.experimental.noalias.scope.decl #alias_scope2 + llvm.return +} + // CHECK-LABEL: @experimental_constrained_fptrunc llvm.func @experimental_constrained_fptrunc(%in: f64) { // CHECK: llvm.intr.experimental.constrained.fptrunc %{{.*}} towardzero ignore : f64 to f32 diff --git a/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll b/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll index f5128ff76bc5f..bf4c85786216f 100644 --- a/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll +++ b/mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll @@ -92,3 +92,38 @@ declare void @foo(ptr %arg1) !0 = distinct !{!0, !"The domain"} !1 = !{!1, !0} !2 = !{!1} + +; // ----- + +; CHECK: #[[DOMAIN:.*]] = #llvm.alias_scope_domain +; CHECK: #[[$SCOPE0:.*]] = #llvm.alias_scope +; CHECK: #[[$SCOPE1:.*]] = #llvm.alias_scope +; CHECK: #[[$SCOPE2:.*]] = #llvm.alias_scope + +; CHECK-LABEL: llvm.func @alias_scope +define void @alias_scope(ptr %arg1) { + ; CHECK: llvm.load + ; CHECK-SAME: alias_scopes = [#[[$SCOPE0]]] + ; CHECK-SAME: noalias_scopes = [#[[$SCOPE1]], #[[$SCOPE2]]] + %1 = load i32, ptr %arg1, !alias.scope !4, !noalias !7 + ; CHECK: llvm.load + ; CHECK-SAME: alias_scopes = [#[[$SCOPE1]]] + ; CHECK-SAME: noalias_scopes = [#[[$SCOPE0]], #[[$SCOPE2]]] + %2 = load i32, ptr %arg1, !alias.scope !5, !noalias !8 + ; CHECK: llvm.load + ; CHECK-SAME: alias_scopes = [#[[$SCOPE2]]] + ; CHECK-SAME: noalias_scopes = [#[[$SCOPE0]], #[[$SCOPE1]]] + %3 = load i32, ptr %arg1, !alias.scope !6, !noalias !9 + ret void +} + +!0 = !{!"domain1"} +!1 = !{!"scopeid1", !0, !"The first scope"} +!2 = !{!"scopeid2", !0} +!3 = !{!"scopeid3", !0} +!4 = !{!1} +!5 = !{!2} +!6 = !{!3} +!7 = !{!2, !3} +!8 = !{!1, !3} +!9 = !{!1, !2} diff --git a/mlir/test/Target/LLVMIR/attribute-alias-scopes.mlir b/mlir/test/Target/LLVMIR/attribute-alias-scopes.mlir index fa3395533af22..fb71a51512aee 100644 --- a/mlir/test/Target/LLVMIR/attribute-alias-scopes.mlir +++ b/mlir/test/Target/LLVMIR/attribute-alias-scopes.mlir @@ -104,3 +104,54 @@ llvm.func @self_reference() { // CHECK-DAG: ![[SCOPES]] = !{![[SCOPE]]} // CHECK-DAG: = !DISubroutineType(types: ![[TYPES:[0-9]+]]) // CHECK-DAG: ![[TYPES]] = !{null} + +// ----- + +llvm.func @foo(%arg0: !llvm.ptr) + +#alias_scope_domain = #llvm.alias_scope_domain +#alias_scope1 = #llvm.alias_scope +#alias_scope2 = #llvm.alias_scope +#alias_scope3 = #llvm.alias_scope + +// CHECK-LABEL: @alias_scopes +llvm.func @alias_scopes(%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 #alias_scope1 + // CHECK: store {{.*}}, !alias.scope ![[SCOPES1]], !noalias ![[SCOPES23:[0-9]+]] + llvm.store %0, %arg1 {alias_scopes = [#alias_scope1], noalias_scopes = [#alias_scope2, #alias_scope3]} : i32, !llvm.ptr + // CHECK: load {{.*}}, !alias.scope ![[SCOPES2:[0-9]+]], !noalias ![[SCOPES13:[0-9]+]] + %1 = llvm.load %arg1 {alias_scopes = [#alias_scope2], noalias_scopes = [#alias_scope1, #alias_scope3]} : !llvm.ptr -> i32 + // CHECK: atomicrmw {{.*}}, !alias.scope ![[SCOPES3:[0-9]+]], !noalias ![[SCOPES12:[0-9]+]] + %2 = llvm.atomicrmw add %arg1, %0 monotonic {alias_scopes = [#alias_scope3], noalias_scopes = [#alias_scope1, #alias_scope2]} : !llvm.ptr, i32 + // CHECK: cmpxchg {{.*}}, !alias.scope ![[SCOPES3]] + %3 = llvm.cmpxchg %arg1, %1, %2 acq_rel monotonic {alias_scopes = [#alias_scope3]} : !llvm.ptr, i32 + %5 = llvm.mlir.constant(42 : i8) : i8 + // CHECK: llvm.memcpy{{.*}}, !alias.scope ![[SCOPES3]] + "llvm.intr.memcpy"(%arg1, %arg1, %0) <{isVolatile = false}> {alias_scopes = [#alias_scope3]} : (!llvm.ptr, !llvm.ptr, i32) -> () + // CHECK: llvm.memset{{.*}}, !noalias ![[SCOPES3]] + "llvm.intr.memset"(%arg1, %5, %0) <{isVolatile = false}> {noalias_scopes = [#alias_scope3]} : (!llvm.ptr, i8, i32) -> () + // CHECK: call void @foo({{.*}} !alias.scope ![[SCOPES3]] + llvm.call @foo(%arg1) {alias_scopes = [#alias_scope3]} : (!llvm.ptr) -> () + // CHECK: call void @foo({{.*}} !noalias ![[SCOPES3]] + llvm.call @foo(%arg1) {noalias_scopes = [#alias_scope3]} : (!llvm.ptr) -> () + llvm.return +} + +// 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]+]] = !{!"domain1", !"The domain"} +// CHECK-DAG: ![[SCOPE1:[0-9]+]] = !{!"scope1", ![[DOMAIN]], !"The first scope"} +// CHECK-DAG: ![[SCOPE2:[0-9]+]] = !{!"scope2", ![[DOMAIN]]} +// CHECK-DAG: ![[SCOPE3:[0-9]+]] = !{!"scope3", ![[DOMAIN]]} +// CHECK-DAG: ![[SCOPES1]] = !{![[SCOPE1]]} +// CHECK-DAG: ![[SCOPES2]] = !{![[SCOPE2]]} +// CHECK-DAG: ![[SCOPES3]] = !{![[SCOPE3]]} +// CHECK-DAG: ![[SCOPES12]] = !{![[SCOPE1]], ![[SCOPE2]]} +// CHECK-DAG: ![[SCOPES13]] = !{![[SCOPE1]], ![[SCOPE3]]} +// CHECK-DAG: ![[SCOPES23]] = !{![[SCOPE2]], ![[SCOPE3]]} From a2f845aec29a861ff801a362f9dcfcd187387089 Mon Sep 17 00:00:00 2001 From: William Moses Date: Tue, 7 Jan 2025 18:49:27 -0500 Subject: [PATCH 2/5] Update mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td Co-authored-by: Oleksandr "Alex" Zinenko --- mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td index 68df6f64e51ea..e746062ad88d9 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -891,7 +891,7 @@ def LLVM_AliasScopeAttr : LLVM_Attr<"AliasScope", "alias_scope"> { } ``` - The first attribute can either be a DistinctAttribute or a StringAttribute. + The first attribute can either be a DistinctAttr or a StringAttr. See the following link for more details: https://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata From efe67bedb54284ba18724199ca87161a8e350ecb Mon Sep 17 00:00:00 2001 From: "Oleksandr \"Alex\" Zinenko" Date: Wed, 8 Jan 2025 10:21:38 +0100 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: Christian Ulmann --- mlir/lib/Target/LLVMIR/ModuleImport.cpp | 4 ++-- mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index e7e5825fd5b45..094cbf8e6912e 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -489,8 +489,8 @@ ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) { if (verifySelfRef(scope)) { idAttr = DistinctAttr::create(builder.getUnitAttr()); } else { - auto Name = cast(scope->getOperand(0)); - idAttr = builder.getStringAttr(Name->getString()); + auto name = cast(scope->getOperand(0)); + idAttr = builder.getStringAttr(name->getString()); } auto aliasScopeOp = builder.getAttr( diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 88d26a4f778a3..4367100e3aca6 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -1732,11 +1732,10 @@ ModuleTranslation::getOrCreateAliasScope(AliasScopeAttr aliasScopeAttr) { // Self-reference for uniqueness. llvm::Metadata *replacement; if (auto stringAttr = - dyn_cast(aliasScopeAttr.getDomain().getId())) { + dyn_cast(aliasScopeAttr.getDomain().getId())) replacement = llvm::MDString::get(ctx, stringAttr.getValue()); - } else { + else replacement = domainIt->second; - } domainIt->second->replaceOperandWith(0, replacement); } // Convert the scope metadata node. @@ -1750,11 +1749,10 @@ ModuleTranslation::getOrCreateAliasScope(AliasScopeAttr aliasScopeAttr) { scopeIt->second = llvm::MDNode::get(ctx, operands); // Self-reference for uniqueness. llvm::Metadata *replacement; - if (auto stringAttr = dyn_cast(aliasScopeAttr.getId())) { + if (auto stringAttr = dyn_cast(aliasScopeAttr.getId())) replacement = llvm::MDString::get(ctx, stringAttr.getValue()); - } else { + else replacement = scopeIt->second; - } scopeIt->second->replaceOperandWith(0, replacement); return scopeIt->second; } From bd0bb3c739eaa6d30931f967e04150ed84403d7c Mon Sep 17 00:00:00 2001 From: Alex Zinenko Date: Wed, 8 Jan 2025 11:33:41 +0100 Subject: [PATCH 4/5] extract lambda --- mlir/lib/Target/LLVMIR/ModuleImport.cpp | 26 +++++++++++-------------- mlir/test/Dialect/LLVMIR/roundtrip.mlir | 4 ++-- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index 094cbf8e6912e..2d8d7745eca9b 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -437,19 +437,22 @@ ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) { return idx >= node->getNumOperands() || isa(node->getOperand(idx)); }; + + auto getIdAttr = [&](const llvm::MDNode *node) -> Attribute { + if (verifySelfRef(node)) + return DistinctAttr::create(builder.getUnitAttr()); + + auto name = cast(node->getOperand(0)); + return builder.getStringAttr(name->getString()); + }; + // Helper that creates an alias scope domain attribute. auto createAliasScopeDomainOp = [&](const llvm::MDNode *aliasDomain) { StringAttr description = nullptr; if (aliasDomain->getNumOperands() >= 2) if (auto *operand = dyn_cast(aliasDomain->getOperand(1))) description = builder.getStringAttr(operand->getString()); - Attribute idAttr; - if (verifySelfRef(aliasDomain)) { - idAttr = DistinctAttr::create(builder.getUnitAttr()); - } else { - auto name = cast(aliasDomain->getOperand(0)); - idAttr = builder.getStringAttr(name->getString()); - } + Attribute idAttr = getIdAttr(aliasDomain); return builder.getAttr(idAttr, description); }; @@ -485,14 +488,7 @@ ModuleImport::processAliasScopeMetadata(const llvm::MDNode *node) { StringAttr description = nullptr; if (!aliasScope.getName().empty()) description = builder.getStringAttr(aliasScope.getName()); - Attribute idAttr; - if (verifySelfRef(scope)) { - idAttr = DistinctAttr::create(builder.getUnitAttr()); - } else { - auto name = cast(scope->getOperand(0)); - idAttr = builder.getStringAttr(name->getString()); - } - + Attribute idAttr = getIdAttr(scope); auto aliasScopeOp = builder.getAttr( idAttr, cast(it->second), description); diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir index d254601932475..88660ce598f3c 100644 --- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir +++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir @@ -753,8 +753,8 @@ llvm.func @experimental_noalias_scope_decl() { #alias_scope_domain2 = #llvm.alias_scope_domain #alias_scope2 = #llvm.alias_scope -// CHECK-LABEL: @experimental_noalias_scope_decl -llvm.func @experimental_noalias_scope_decl2() { +// CHECK-LABEL: @experimental_noalias_scope_with_string_id +llvm.func @experimental_noalias_scope_with_string_id() { // CHECK: llvm.intr.experimental.noalias.scope.decl #{{.*}} llvm.intr.experimental.noalias.scope.decl #alias_scope2 llvm.return From b91ba3457e1f1c3e884947b71a2f3fcece69a98b Mon Sep 17 00:00:00 2001 From: Alex Zinenko Date: Wed, 8 Jan 2025 13:06:37 +0100 Subject: [PATCH 5/5] add verifier --- .../include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 2 ++ mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td index e746062ad88d9..267389774bd5a 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -900,6 +900,8 @@ def LLVM_AliasScopeAttr : LLVM_Attr<"AliasScope", "alias_scope"> { let summary = "LLVM dialect alias scope"; let assemblyFormat = "`<` struct(params) `>`"; + + let genVerifyDecl = 1; } def LLVM_AliasScopeArrayAttr diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp index 7490e8735f5fd..ff1636bc121b6 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp @@ -52,6 +52,23 @@ void LLVMDialect::registerAttributes() { >(); } +//===----------------------------------------------------------------------===// +// AliasScopeAttr +//===----------------------------------------------------------------------===// + +LogicalResult +AliasScopeAttr::verify(function_ref emitError, + Attribute id, AliasScopeDomainAttr domain, + StringAttr description) { + (void)domain; + (void)description; + if (!llvm::isa(id)) + return emitError() + << "id of an alias scope must be a StringAttr or a DistrinctAttr"; + + return success(); +} + //===----------------------------------------------------------------------===// // DINodeAttr //===----------------------------------------------------------------------===//