Index: mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td =================================================================== --- mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -215,7 +215,7 @@ OptionalParameter<"LoopUnswitchAttr">:$unswitch, OptionalParameter<"BoolAttr">:$mustProgress, OptionalParameter<"BoolAttr">:$isVectorized, - OptionalArrayRefParameter<"SymbolRefAttr">:$parallelAccesses, + OptionalArrayRefParameter<"AccessGroupAttr">:$parallelAccesses, OptionalParameter<"FusedLoc">:$startLoc, OptionalParameter<"FusedLoc">:$endLoc ); @@ -650,4 +650,40 @@ let constBuilderCall = ?; } +//===----------------------------------------------------------------------===// +// AccessGroupAttr +//===----------------------------------------------------------------------===// + +def LLVM_AccessGroupAttr : LLVM_Attr<"AccessGroup", "access_group"> { + + let parameters = (ins "DistinctAttr":$id); + + let builders = [ + AttrBuilder<(ins), [{ + return $_get($_ctxt, DistinctAttr::create(UnitAttr::get($_ctxt))); + }]> + ]; + + let summary = "LLVM dialect access group metadata"; + + let description = [{ + Defines an access group metadata that can be attached to any instruction + that potentially accesses memory. The access group may be attached to a + memory accessing instruction via the `llvm.access.group` metadata and + a branch instruction in the loop latch block via the + `llvm.loop.parallel_accesses` metadata. + + See the following link for more details: + https://llvm.org/docs/LangRef.html#llvm-access-group-metadata + }]; + + let assemblyFormat = "`<` struct(params) `>`"; +} + +def LLVM_AccessGroupArrayAttr + : TypedArrayAttrBase { + let constBuilderCall = ?; +} + #endif // LLVMIR_ATTRDEFS Index: mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td =================================================================== --- mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td +++ mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td @@ -278,7 +278,7 @@ DeclareOpInterfaceMethods, DeclareOpInterfaceMethods], traits)>, LLVM_MemOpPatterns { - dag aliasAttrs = (ins OptionalAttr:$access_groups, + dag aliasAttrs = (ins OptionalAttr:$access_groups, OptionalAttr:$alias_scopes, OptionalAttr:$noalias_scopes, OptionalAttr:$tbaa); @@ -321,7 +321,7 @@ Results { dag aliasAttrs = !con( !if(!gt(requiresAccessGroup, 0), - (ins OptionalAttr:$access_groups), + (ins OptionalAttr:$access_groups), (ins )), !if(!gt(requiresAliasAnalysis, 0), (ins OptionalAttr:$alias_scopes, Index: mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td =================================================================== --- mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -845,7 +845,6 @@ }]>, LLVM_TerminatorPassthroughOpBuilder ]; - let hasVerifier = 1; } def LLVM_CondBrOp : LLVM_TerminatorOp<"cond_br", [AttrSizedOperandSegments, DeclareOpInterfaceMethods, @@ -880,7 +879,6 @@ build($_builder, $_state, condition, trueOperands, falseOperands, branchWeights, {}, trueDest, falseDest); }]>, LLVM_TerminatorPassthroughOpBuilder]; - let hasVerifier = 1; } //===----------------------------------------------------------------------===// @@ -1101,26 +1099,6 @@ let hasRegionVerifier = 1; } -def LLVM_AccessGroupMetadataOp : LLVM_Op<"access_group", [ - HasParent<"MetadataOp">, Symbol -]> { - let arguments = (ins - SymbolNameAttr:$sym_name - ); - let summary = "LLVM dialect access group metadata."; - let description = [{ - Defines an access group metadata that can be attached to any instruction - that potentially accesses memory. The access group may be attached to a - memory accessing instruction via the `llvm.access.group` metadata and - a branch instruction in the loop latch block via the - `llvm.loop.parallel_accesses` metadata. - - See the following link for more details: - https://llvm.org/docs/LangRef.html#llvm-access-group-metadata - }]; - let assemblyFormat = "$sym_name attr-dict"; -} - def LLVM_TBAARootMetadataOp : LLVM_Op<"tbaa_root", [ HasParent<"MetadataOp">, Symbol ]> { Index: mlir/include/mlir/Target/LLVMIR/ModuleImport.h =================================================================== --- mlir/include/mlir/Target/LLVMIR/ModuleImport.h +++ mlir/include/mlir/Target/LLVMIR/ModuleImport.h @@ -191,10 +191,10 @@ return tbaaMapping.lookup(node); } - /// Returns the symbol references pointing to the access group operations that - /// map to the access group nodes starting from the access group metadata - /// `node`. Returns failure, if any of the symbol references cannot be found. - FailureOr> + /// Returns the access group attributes that map to the access group nodes + /// starting from the access group metadata `node`. Returns failure, if any of + /// the attributes cannot be found. + FailureOr> lookupAccessGroupAttrs(const llvm::MDNode *node) const; /// Returns the loop annotation attribute that corresponds to the given LLVM Index: mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h =================================================================== --- mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h +++ mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h @@ -278,10 +278,6 @@ LogicalResult convertGlobals(); LogicalResult convertOneFunction(LLVMFuncOp func); - /// Process access_group LLVM Metadata operations and create LLVM - /// metadata nodes. - LogicalResult createAccessGroupMetadata(); - /// Process alias.scope LLVM Metadata operations and create LLVM /// metadata nodes for them and their domains. LogicalResult createAliasScopeMetadata(); Index: mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp =================================================================== --- mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -291,42 +291,11 @@ // LLVM::BrOp //===----------------------------------------------------------------------===// -/// Check if the `loopAttr` references correct symbols. -static LogicalResult verifyLoopAnnotationAttr(LoopAnnotationAttr loopAttr, - Operation *op) { - if (!loopAttr) - return success(); - // If the `llvm.loop` attribute is present, enforce the following structure, - // which the module translation can assume. - ArrayRef parallelAccesses = loopAttr.getParallelAccesses(); - if (parallelAccesses.empty()) - return success(); - for (SymbolRefAttr accessGroupRef : parallelAccesses) { - StringAttr metadataName = accessGroupRef.getRootReference(); - auto metadataOp = SymbolTable::lookupNearestSymbolFrom( - op->getParentOp(), metadataName); - if (!metadataOp) - return op->emitOpError() << "expected '" << accessGroupRef - << "' to reference a metadata op"; - StringAttr accessGroupName = accessGroupRef.getLeafReference(); - Operation *accessGroupOp = - SymbolTable::lookupNearestSymbolFrom(metadataOp, accessGroupName); - if (!accessGroupOp) - return op->emitOpError() << "expected '" << accessGroupRef - << "' to reference an access_group op"; - } - return success(); -} - SuccessorOperands BrOp::getSuccessorOperands(unsigned index) { assert(index == 0 && "invalid successor index"); return SuccessorOperands(getDestOperandsMutable()); } -LogicalResult BrOp::verify() { - return verifyLoopAnnotationAttr(getLoopAnnotationAttr(), *this); -} - //===----------------------------------------------------------------------===// // LLVM::CondBrOp //===----------------------------------------------------------------------===// @@ -337,10 +306,6 @@ : getFalseDestOperandsMutable()); } -LogicalResult CondBrOp::verify() { - return verifyLoopAnnotationAttr(getLoopAnnotationAttr(), *this); -} - void CondBrOp::build(OpBuilder &builder, OperationState &result, Value condition, Block *trueDest, ValueRange trueOperands, Block *falseDest, ValueRange falseOperands, @@ -3094,9 +3059,9 @@ AliasResult getAlias(Attribute attr, raw_ostream &os) const override { return TypeSwitch(attr) - .Case(op); - if (failed(verifySymbolRefsPointTo( - iface, "access groups", iface.getAccessGroupsOrNull()))) - return failure(); + ArrayAttr accessGroups = iface.getAccessGroupsOrNull(); + if (!accessGroups) + return success(); + for (Attribute iter : accessGroups) + if (!isa(iter)) + return op->emitOpError("expected op to return array of ") + << AccessGroupAttr::getMnemonic() << " attributes"; return success(); } Index: mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMIRToLLVMTranslation.cpp =================================================================== --- mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMIRToLLVMTranslation.cpp +++ mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMIRToLLVMTranslation.cpp @@ -158,7 +158,7 @@ static LogicalResult setAccessGroupsAttr(const llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport) { - FailureOr> accessGroups = + FailureOr> accessGroups = moduleImport.lookupAccessGroupAttrs(node); if (failed(accessGroups)) return failure(); @@ -168,8 +168,7 @@ return failure(); iface.setAccessGroups(ArrayAttr::get( - iface.getContext(), - SmallVector{accessGroups->begin(), accessGroups->end()})); + iface.getContext(), llvm::to_vector_of(*accessGroups))); return success(); } Index: mlir/lib/Target/LLVMIR/LoopAnnotationImporter.h =================================================================== --- mlir/lib/Target/LLVMIR/LoopAnnotationImporter.h +++ mlir/lib/Target/LLVMIR/LoopAnnotationImporter.h @@ -32,17 +32,15 @@ Location loc); /// Converts all LLVM access groups starting from node to MLIR access group - /// operations mested in the region of metadataOp. It stores a mapping from - /// every nested access group nod to the symbol pointing to the translated - /// operation. Returns success if all conversions succeed and failure - /// otherwise. - LogicalResult translateAccessGroup(const llvm::MDNode *node, Location loc, - MetadataOp metadataOp); + /// attributes. It stores a mapping from every nested access group node to the + /// translated attribute. Returns success if all conversions succeed and + /// failure otherwise. + LogicalResult translateAccessGroup(const llvm::MDNode *node, Location loc); - /// Returns the symbol references pointing to the access group operations that - /// map to the access group nodes starting from the access group metadata - /// node. Returns failure, if any of the symbol references cannot be found. - FailureOr> + /// Returns the access group attribute that map to the access group nodes + /// starting from the access group metadata node. Returns failure, if any of + /// the attributes cannot be found. + FailureOr> lookupAccessGroupAttrs(const llvm::MDNode *node) const; /// The ModuleImport owning this instance. @@ -63,9 +61,9 @@ OpBuilder &builder; DenseMap loopMetadataMapping; - /// Mapping between original LLVM access group metadata nodes and the symbol - /// references pointing to the imported MLIR access group operations. - DenseMap accessGroupMapping; + /// Mapping between original LLVM access group metadata nodes and the imported + /// MLIR access group attributes. + DenseMap accessGroupMapping; }; } // namespace detail Index: mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp =================================================================== --- mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp +++ mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp @@ -53,7 +53,7 @@ FailureOr convertPipelineAttr(); FailureOr convertPeeledAttr(); FailureOr convertUnswitchAttr(); - FailureOr> convertParallelAccesses(); + FailureOr> convertParallelAccesses(); FusedLoc convertStartLoc(); FailureOr convertEndLoc(); @@ -391,15 +391,15 @@ return createIfNonNull(ctx, partialDisable); } -FailureOr> +FailureOr> LoopMetadataConversion::convertParallelAccesses() { FailureOr> nodes = lookupMDNodes("llvm.loop.parallel_accesses"); if (failed(nodes)) return failure(); - SmallVector refs; + SmallVector refs; for (llvm::MDNode *node : *nodes) { - FailureOr> accessGroups = + FailureOr> accessGroups = loopAnnotationImporter.lookupAccessGroupAttrs(node); if (failed(accessGroups)) { emitWarning(loc) << "could not lookup access group"; @@ -445,7 +445,7 @@ FailureOr mustProgress = lookupUnitNode("llvm.loop.mustprogress"); FailureOr isVectorized = lookupIntNodeAsBoolAttr("llvm.loop.isvectorized"); - FailureOr> parallelAccesses = + FailureOr> parallelAccesses = convertParallelAccesses(); // Drop the metadata if there are parts that cannot be imported. @@ -483,8 +483,9 @@ return attr; } -LogicalResult LoopAnnotationImporter::translateAccessGroup( - const llvm::MDNode *node, Location loc, MetadataOp metadataOp) { +LogicalResult +LoopAnnotationImporter::translateAccessGroup(const llvm::MDNode *node, + Location loc) { SmallVector accessGroups; if (!node->getNumOperands()) accessGroups.push_back(node); @@ -504,24 +505,17 @@ return emitWarning(loc) << "expected an access group node to be empty and distinct"; - OpBuilder::InsertionGuard guard(builder); - builder.setInsertionPointToEnd(&metadataOp.getBody().back()); - auto groupOp = builder.create( - loc, llvm::formatv("group_{0}", accessGroupMapping.size()).str()); - // Add a mapping from the access group node to the symbol reference pointing - // to the newly created operation. - accessGroupMapping[accessGroup] = SymbolRefAttr::get( - builder.getContext(), metadataOp.getSymName(), - FlatSymbolRefAttr::get(builder.getContext(), groupOp.getSymName())); + // Add a mapping from the access group node to the newly created attribute. + accessGroupMapping[accessGroup] = builder.getAttr(); } return success(); } -FailureOr> +FailureOr> LoopAnnotationImporter::lookupAccessGroupAttrs(const llvm::MDNode *node) const { // An access group node is either a single access group or an access group // list. - SmallVector accessGroups; + SmallVector accessGroups; if (!node->getNumOperands()) accessGroups.push_back(accessGroupMapping.lookup(node)); for (const llvm::MDOperand &operand : node->operands()) { Index: mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.h =================================================================== --- mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.h +++ mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.h @@ -26,24 +26,18 @@ class LoopAnnotationTranslation { public: LoopAnnotationTranslation(ModuleTranslation &moduleTranslation, - Operation *mlirModule, llvm::Module &llvmModule) - : moduleTranslation(moduleTranslation), mlirModule(mlirModule), - llvmModule(llvmModule) {} + llvm::Module &llvmModule) + : moduleTranslation(moduleTranslation), llvmModule(llvmModule) {} llvm::MDNode *translateLoopAnnotation(LoopAnnotationAttr attr, Operation *op); - /// Traverses the global access group metadata operation in the `mlirModule` - /// and creates corresponding LLVM metadata nodes. - LogicalResult createAccessGroupMetadata(); + /// Returns the LLVM metadata corresponding to an mlir LLVM dialect access + /// group attribute. + llvm::MDNode *getAccessGroup(AccessGroupAttr accessGroupAttr); - /// Returns the LLVM metadata corresponding to a symbol reference to an mlir - /// LLVM dialect access group operation. - llvm::MDNode *getAccessGroup(Operation *op, - SymbolRefAttr accessGroupRef) const; - - /// Returns the LLVM metadata corresponding to the access group operations + /// Returns the LLVM metadata corresponding to the access group attribute /// referenced by the AccessGroupOpInterface or null if there are none. - llvm::MDNode *getAccessGroups(AccessGroupOpInterface op) const; + llvm::MDNode *getAccessGroups(AccessGroupOpInterface op); /// The ModuleTranslation owning this instance. ModuleTranslation &moduleTranslation; @@ -65,12 +59,11 @@ /// The metadata is attached to Latch block branches with this attribute. DenseMap loopMetadataMapping; - /// Mapping from an access group metadata operation to its LLVM metadata. + /// Mapping from an access group attribute to its LLVM metadata. /// This map is populated on module entry and is used to annotate loops (as /// identified via their branches) and contained memory accesses. - DenseMap accessGroupMetadataMapping; + DenseMap accessGroupMetadataMapping; - Operation *mlirModule; llvm::Module &llvmModule; }; Index: mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.cpp =================================================================== --- mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.cpp +++ mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.cpp @@ -240,14 +240,14 @@ if (auto options = attr.getUnswitch()) convertLoopOptions(options); - ArrayRef parallelAccessGroups = attr.getParallelAccesses(); + ArrayRef parallelAccessGroups = attr.getParallelAccesses(); if (!parallelAccessGroups.empty()) { SmallVector parallelAccess; parallelAccess.push_back( llvm::MDString::get(ctx, "llvm.loop.parallel_accesses")); - for (SymbolRefAttr accessGroupRef : parallelAccessGroups) + for (AccessGroupAttr accessGroupAttr : parallelAccessGroups) parallelAccess.push_back( - loopAnnotationTranslation.getAccessGroup(op, accessGroupRef)); + loopAnnotationTranslation.getAccessGroup(accessGroupAttr)); metadataNodes.push_back(llvm::MDNode::get(ctx, parallelAccess)); } @@ -277,38 +277,24 @@ return loopMD; } -LogicalResult LoopAnnotationTranslation::createAccessGroupMetadata() { - mlirModule->walk([&](LLVM::MetadataOp metadatas) { - metadatas.walk([&](LLVM::AccessGroupMetadataOp op) { - llvm::MDNode *accessGroup = - llvm::MDNode::getDistinct(llvmModule.getContext(), {}); - accessGroupMetadataMapping.insert({op, accessGroup}); - }); - }); - return success(); -} - llvm::MDNode * -LoopAnnotationTranslation::getAccessGroup(Operation *op, - SymbolRefAttr accessGroupRef) const { - auto metadataName = accessGroupRef.getRootReference(); - auto accessGroupName = accessGroupRef.getLeafReference(); - auto metadataOp = SymbolTable::lookupNearestSymbolFrom( - op->getParentOp(), metadataName); - auto *accessGroupOp = - SymbolTable::lookupNearestSymbolFrom(metadataOp, accessGroupName); - return accessGroupMetadataMapping.lookup(accessGroupOp); +LoopAnnotationTranslation::getAccessGroup(AccessGroupAttr accessGroupAttr) { + auto [result, inserted] = + accessGroupMetadataMapping.insert({accessGroupAttr, nullptr}); + if (inserted) + result->second = llvm::MDNode::getDistinct(llvmModule.getContext(), {}); + return result->second; } llvm::MDNode * -LoopAnnotationTranslation::getAccessGroups(AccessGroupOpInterface op) const { - ArrayAttr accessGroupRefs = op.getAccessGroupsOrNull(); - if (!accessGroupRefs || accessGroupRefs.empty()) +LoopAnnotationTranslation::getAccessGroups(AccessGroupOpInterface op) { + ArrayAttr accessGroups = op.getAccessGroupsOrNull(); + if (!accessGroups || accessGroups.empty()) return nullptr; SmallVector groupMDs; - for (SymbolRefAttr groupRef : accessGroupRefs.getAsRange()) - groupMDs.push_back(getAccessGroup(op, groupRef)); + for (AccessGroupAttr group : accessGroups.getAsRange()) + groupMDs.push_back(getAccessGroup(group)); if (groupMDs.size() == 1) return llvm::cast(groupMDs.front()); return llvm::MDNode::get(llvmModule.getContext(), groupMDs); Index: mlir/lib/Target/LLVMIR/ModuleImport.cpp =================================================================== --- mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -434,8 +434,7 @@ LogicalResult ModuleImport::processAccessGroupMetadata(const llvm::MDNode *node) { Location loc = mlirModule.getLoc(); - if (failed(loopAnnotationImporter->translateAccessGroup( - node, loc, getGlobalMetadataOp()))) + if (failed(loopAnnotationImporter->translateAccessGroup(node, loc))) return emitError(loc) << "unsupported access group node: " << diagMD(node, llvmModule.get()); return success(); @@ -1803,7 +1802,7 @@ return success(); } -FailureOr> +FailureOr> ModuleImport::lookupAccessGroupAttrs(const llvm::MDNode *node) const { return loopAnnotationImporter->lookupAccessGroupAttrs(node); } Index: mlir/lib/Target/LLVMIR/ModuleTranslation.cpp =================================================================== --- mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -462,7 +462,7 @@ debugTranslation( std::make_unique(module, *this->llvmModule)), loopAnnotationTranslation(std::make_unique( - *this, module, *this->llvmModule)), + *this, *this->llvmModule)), typeTranslator(this->llvmModule->getContext()), iface(module->getContext()) { assert(satisfiesLLVMModule(mlirModule) && @@ -1083,10 +1083,6 @@ return success(); } -LogicalResult ModuleTranslation::createAccessGroupMetadata() { - return loopAnnotationTranslation->createAccessGroupMetadata(); -} - void ModuleTranslation::setAccessGroupsMetadata(AccessGroupOpInterface op, llvm::Instruction *inst) { if (llvm::MDNode *node = loopAnnotationTranslation->getAccessGroups(op)) @@ -1419,8 +1415,6 @@ return nullptr; if (failed(translator.convertGlobals())) return nullptr; - if (failed(translator.createAccessGroupMetadata())) - return nullptr; if (failed(translator.createAliasScopeMetadata())) return nullptr; if (failed(translator.createTBAAMetadata())) Index: mlir/test/Dialect/LLVMIR/inlining.mlir =================================================================== --- mlir/test/Dialect/LLVMIR/inlining.mlir +++ mlir/test/Dialect/LLVMIR/inlining.mlir @@ -54,13 +54,10 @@ // ----- -llvm.metadata @metadata { - llvm.access_group @group - llvm.return -} +#group = #llvm.access_group> llvm.func @inlinee(%ptr : !llvm.ptr) -> i32 { - %0 = llvm.load %ptr { access_groups = [@metadata::@group] } : !llvm.ptr -> i32 + %0 = llvm.load %ptr { access_groups = [#group] } : !llvm.ptr -> i32 llvm.return %0 : i32 } @@ -73,16 +70,13 @@ // ----- -llvm.metadata @metadata { - llvm.access_group @group - llvm.return -} +#group = #llvm.access_group> func.func private @with_mem_attr(%ptr : !llvm.ptr) { %0 = llvm.mlir.constant(42 : i32) : i32 // Do not inline load/store operations that carry attributes requiring // handling while inlining, until this is supported by the inliner. - llvm.store %0, %ptr { access_groups = [@metadata::@group] }: i32, !llvm.ptr + llvm.store %0, %ptr { access_groups = [#group] }: i32, !llvm.ptr return } Index: mlir/test/Dialect/LLVMIR/invalid.mlir =================================================================== --- mlir/test/Dialect/LLVMIR/invalid.mlir +++ mlir/test/Dialect/LLVMIR/invalid.mlir @@ -911,36 +911,9 @@ // ----- -module { - llvm.func @loopOptions() { - // expected-error@below {{expected '@func1' to reference a metadata op}} - llvm.br ^bb4 {loop_annotation = #llvm.loop_annotation} - ^bb4: - llvm.return - } - llvm.func @func1() { - llvm.return - } -} - -// ----- - -module { - llvm.func @loopOptions() { - // expected-error@below {{expected '@metadata' to reference an access_group op}} - llvm.br ^bb4 {loop_annotation = #llvm.loop_annotation} - ^bb4: - llvm.return - } - llvm.metadata @metadata { - } -} - -// ----- - module { llvm.func @accessGroups(%arg0 : !llvm.ptr) { - // expected-error@below {{expected '@func1' to specify a fully qualified reference}} + // expected-error@below {{attribute 'access_groups' failed to satisfy constraint: LLVM dialect access group metadata array}} %0 = llvm.load %arg0 { "access_groups" = [@func1] } : !llvm.ptr -> i32 llvm.return } @@ -951,33 +924,9 @@ // ----- -module { - llvm.func @accessGroups(%arg0 : i32, %arg1 : !llvm.ptr) { - // expected-error@below {{expected '@accessGroups::@group1' to reference a metadata op}} - llvm.store %arg0, %arg1 { "access_groups" = [@accessGroups::@group1] } : i32, !llvm.ptr - llvm.return - } - llvm.metadata @metadata { - } -} - -// ----- - -module { - llvm.func @accessGroups(%arg0 : !llvm.ptr, %arg1 : f32) { - // expected-error@below {{expected '@metadata::@group1' to be a valid reference}} - %0 = llvm.atomicrmw fadd %arg0, %arg1 monotonic { "access_groups" = [@metadata::@group1] } : !llvm.ptr, f32 - llvm.return - } - llvm.metadata @metadata { - } -} - -// ----- - module { llvm.func @accessGroups(%arg0 : !llvm.ptr, %arg1 : i32, %arg2 : i32) { - // expected-error@below {{expected '@metadata::@scope' to resolve to a llvm.access_group}} + // expected-error@below {{attribute 'access_groups' failed to satisfy constraint: LLVM dialect access group metadata array}} %0 = llvm.cmpxchg %arg0, %arg1, %arg2 acq_rel monotonic { "access_groups" = [@metadata::@scope] } : !llvm.ptr, i32 llvm.return } Index: mlir/test/Dialect/LLVMIR/loop-metadata.mlir =================================================================== --- mlir/test/Dialect/LLVMIR/loop-metadata.mlir +++ mlir/test/Dialect/LLVMIR/loop-metadata.mlir @@ -42,6 +42,11 @@ // CHECK-DAG: #[[UNSWITCH:.*]] = #llvm.loop_unswitch #unswitch = #llvm.loop_unswitch +// CHECK-DAG: #[[GROUP1:.*]] = #llvm.access_group +// CHECK-DAG: #[[GROUP2:.*]] = #llvm.access_group +#group1 = #llvm.access_group> +#group2 = #llvm.access_group> + // CHECK: #[[LOOP_ANNOT:.*]] = #llvm.loop_annotation< // CHECK-DAG: disableNonforced = false // CHECK-DAG: mustProgress = true @@ -53,7 +58,7 @@ // CHECK-DAG: peeled = #[[PEELED]] // CHECK-DAG: unswitch = #[[UNSWITCH]] // CHECK-DAG: isVectorized = false -// CHECK-DAG: parallelAccesses = @metadata::@group1, @metadata::@group2> +// CHECK-DAG: parallelAccesses = #[[GROUP1]], #[[GROUP2]]> #loopMD = #llvm.loop_annotation + parallelAccesses = #group1, #group2> // CHECK: llvm.func @loop_annotation llvm.func @loop_annotation() { @@ -76,11 +81,6 @@ llvm.return } -llvm.metadata @metadata { - llvm.access_group @group1 - llvm.access_group @group2 -} - // ----- #di_file = #llvm.di_file<"metadata-loop.ll" in "/"> Index: mlir/test/Dialect/LLVMIR/tbaa-invalid.mlir =================================================================== --- mlir/test/Dialect/LLVMIR/tbaa-invalid.mlir +++ mlir/test/Dialect/LLVMIR/tbaa-invalid.mlir @@ -32,7 +32,7 @@ llvm.return } llvm.metadata @metadata { - llvm.access_group @group1 + llvm.func @group1() } } Index: mlir/test/Target/LLVMIR/Import/metadata-loop.ll =================================================================== --- mlir/test/Target/LLVMIR/Import/metadata-loop.ll +++ mlir/test/Target/LLVMIR/Import/metadata-loop.ll @@ -1,19 +1,17 @@ ; RUN: mlir-translate -import-llvm -split-input-file %s | FileCheck %s -; CHECK: llvm.metadata @__llvm_global_metadata { -; CHECK: llvm.access_group @[[$GROUP0:.*]] -; CHECK: llvm.access_group @[[$GROUP1:.*]] -; CHECK: llvm.access_group @[[$GROUP2:.*]] -; CHECK: llvm.access_group @[[$GROUP3:.*]] -; CHECK: } +; CHECK-DAG: #[[$GROUP0:.*]] = #llvm.access_group +; CHECK-DAG: #[[$GROUP1:.*]] = #llvm.access_group +; CHECK-DAG: #[[$GROUP2:.*]] = #llvm.access_group +; CHECK-DAG: #[[$GROUP3:.*]] = #llvm.access_group ; CHECK-LABEL: llvm.func @access_group define void @access_group(ptr %arg1) { - ; CHECK: access_groups = [@__llvm_global_metadata::@[[$GROUP0]], @__llvm_global_metadata::@[[$GROUP1]]] + ; CHECK: access_groups = [#[[$GROUP0]], #[[$GROUP1]]] %1 = load i32, ptr %arg1, !llvm.access.group !0 - ; CHECK: access_groups = [@__llvm_global_metadata::@[[$GROUP2]], @__llvm_global_metadata::@[[$GROUP0]]] + ; CHECK: access_groups = [#[[$GROUP2]], #[[$GROUP0]]] %2 = load i32, ptr %arg1, !llvm.access.group !1 - ; CHECK: access_groups = [@__llvm_global_metadata::@[[$GROUP3]]] + ; CHECK: access_groups = [#[[$GROUP3]]] %3 = load i32, ptr %arg1, !llvm.access.group !2 ret void } @@ -284,10 +282,8 @@ ; // ----- -; CHECK: #[[$ANNOT_ATTR:.*]] = #llvm.loop_annotation - -; CHECK: llvm.metadata @__llvm_global_metadata { -; CHECK: llvm.access_group @[[GROUP0]] +; CHECK: #[[GROUP0:.*]] = #llvm.access_group +; CHECK: #[[$ANNOT_ATTR:.*]] = #llvm.loop_annotation ; CHECK-LABEL: @parallel_accesses define void @parallel_accesses(ptr %arg) { @@ -305,11 +301,9 @@ ; // ----- -; CHECK: #[[$ANNOT_ATTR:.*]] = #llvm.loop_annotation - -; CHECK: llvm.metadata @__llvm_global_metadata { -; CHECK: llvm.access_group @[[GROUP0]] -; CHECK: llvm.access_group @[[GROUP1]] +; CHECK: #[[GROUP0:.*]] = #llvm.access_group +; CHECK: #[[GROUP1:.*]] = #llvm.access_group +; CHECK: #[[$ANNOT_ATTR:.*]] = #llvm.loop_annotation ; CHECK-LABEL: @multiple_parallel_accesses define void @multiple_parallel_accesses(ptr %arg) { @@ -330,8 +324,7 @@ ; // ----- ; Verify the unused access group is not imported. -; CHECK: llvm.metadata @__llvm_global_metadata { -; CHECK-COUNT1: llvm.access_group +; CHECK-COUNT1: #llvm.access_group ; CHECK-LABEL: @unused_parallel_access define void @unused_parallel_access(ptr %arg) { Index: mlir/test/Target/LLVMIR/loop-metadata.mlir =================================================================== --- mlir/test/Target/LLVMIR/loop-metadata.mlir +++ mlir/test/Target/LLVMIR/loop-metadata.mlir @@ -235,6 +235,9 @@ llvm.func @foo(%arg0: i32) +#group1 = #llvm.access_group> +#group2 = #llvm.access_group> + // CHECK-LABEL: @loopOptions llvm.func @loopOptions(%arg1 : i32, %arg2 : i32) { %0 = llvm.mlir.constant(0 : i32) : i32 @@ -247,40 +250,35 @@ licm = , interleave = , unroll = , pipeline = , - parallelAccesses = @metadata::@group1, @metadata::@group2>} + parallelAccesses = #group1, #group2>} ^bb4: %3 = llvm.add %1, %arg2 : i32 // CHECK: = load i32, ptr %{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE:[0-9]+]] - %5 = llvm.load %4 {access_groups = [@metadata::@group1, @metadata::@group2]} : !llvm.ptr -> i32 + %5 = llvm.load %4 {access_groups = [#group1, #group2]} : !llvm.ptr -> i32 // CHECK: store i32 %{{.*}}, ptr %{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] - llvm.store %5, %4 {access_groups = [@metadata::@group1, @metadata::@group2]} : i32, !llvm.ptr + llvm.store %5, %4 {access_groups = [#group1, #group2]} : i32, !llvm.ptr // CHECK: = atomicrmw add ptr %{{.*}}, i32 %{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] - %6 = llvm.atomicrmw add %4, %5 monotonic {access_groups = [@metadata::@group1, @metadata::@group2]} : !llvm.ptr, i32 + %6 = llvm.atomicrmw add %4, %5 monotonic {access_groups = [#group1, #group2]} : !llvm.ptr, i32 // CHECK: = cmpxchg ptr %{{.*}}, i32 %{{.*}}, i32 %{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] - %7 = llvm.cmpxchg %4, %5, %6 acq_rel monotonic {access_groups = [@metadata::@group1, @metadata::@group2]} : !llvm.ptr, i32 + %7 = llvm.cmpxchg %4, %5, %6 acq_rel monotonic {access_groups = [#group1, #group2]} : !llvm.ptr, i32 %9 = llvm.mlir.constant(42 : i8) : i8 // CHECK: llvm.memcpy{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] - "llvm.intr.memcpy"(%4, %4, %0) <{isVolatile = false}> {access_groups = [@metadata::@group1, @metadata::@group2]} : (!llvm.ptr, !llvm.ptr, i32) -> () + "llvm.intr.memcpy"(%4, %4, %0) <{isVolatile = false}> {access_groups = [#group1, #group2]} : (!llvm.ptr, !llvm.ptr, i32) -> () // CHECK: llvm.memset{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] - "llvm.intr.memset"(%4, %9, %0) <{isVolatile = false}> {access_groups = [@metadata::@group1, @metadata::@group2]} : (!llvm.ptr, i8, i32) -> () + "llvm.intr.memset"(%4, %9, %0) <{isVolatile = false}> {access_groups = [#group1, #group2]} : (!llvm.ptr, i8, i32) -> () // CHECK: call void @foo({{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]] - llvm.call @foo(%arg1) {access_groups = [@metadata::@group1, @metadata::@group2]} : (i32) -> () + llvm.call @foo(%arg1) {access_groups = [#group1, #group2]} : (i32) -> () // CHECK: br label {{.*}} !llvm.loop ![[LOOP_NODE]] llvm.br ^bb3(%3 : i32) {loop_annotation = #llvm.loop_annotation< licm = , interleave = , unroll = , pipeline = , - parallelAccesses = @metadata::@group1, @metadata::@group2>} + parallelAccesses = #group1, #group2>} ^bb5: llvm.return } -llvm.metadata @metadata { - llvm.access_group @group1 - llvm.access_group @group2 -} - // CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} // CHECK-DAG: ![[PA_NODE:[0-9]+]] = !{!"llvm.loop.parallel_accesses", ![[GROUP_NODE1:[0-9]+]], ![[GROUP_NODE2:[0-9]+]]} // CHECK-DAG: ![[GROUP_NODE1:[0-9]+]] = distinct !{}