Author: Mehdi Amini Date: 2025-07-30T13:49:23+02:00 New Revision: d7c231a37864a5d41317e6d2b1dee1dd1103d9cf
URL: https://github.com/llvm/llvm-project/commit/d7c231a37864a5d41317e6d2b1dee1dd1103d9cf DIFF: https://github.com/llvm/llvm-project/commit/d7c231a37864a5d41317e6d2b1dee1dd1103d9cf.diff LOG: Revert "Reland "[mlir][llvm] Add intrinsic arg and result attribute support (…" This reverts commit b7bfbc0c4c7b20d6623a5b0b4a7fea8ae08a62da. Added: Modified: mlir/include/mlir/Dialect/ArmSME/IR/ArmSMEIntrinsicOps.td mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td mlir/include/mlir/Interfaces/CallInterfaces.td mlir/include/mlir/Target/LLVMIR/ModuleImport.h mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp mlir/lib/Target/LLVMIR/LLVMImportInterface.cpp mlir/lib/Target/LLVMIR/ModuleImport.cpp mlir/lib/Target/LLVMIR/ModuleTranslation.cpp mlir/test/Target/LLVMIR/Import/intrinsic.ll mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir utils/bazel/llvm-project-overlay/mlir/test/mlir-tblgen/BUILD.bazel Removed: ################################################################################ diff --git a/mlir/include/mlir/Dialect/ArmSME/IR/ArmSMEIntrinsicOps.td b/mlir/include/mlir/Dialect/ArmSME/IR/ArmSMEIntrinsicOps.td index 06fb8511774e8..e81db32bcaad0 100644 --- a/mlir/include/mlir/Dialect/ArmSME/IR/ArmSMEIntrinsicOps.td +++ b/mlir/include/mlir/Dialect/ArmSME/IR/ArmSMEIntrinsicOps.td @@ -71,7 +71,6 @@ class ArmSME_IntrOp<string mnemonic, /*bit requiresAccessGroup=*/0, /*bit requiresAliasAnalysis=*/0, /*bit requiresFastmath=*/0, - /*bit requiresArgAndResultAttrs=*/0, /*bit requiresOpBundles=*/0, /*list<int> immArgPositions=*/immArgPositions, /*list<string> immArgAttrNames=*/immArgAttrNames>; diff --git a/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td b/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td index d055bb4da09f8..8988df680b8f9 100644 --- a/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td +++ b/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td @@ -92,7 +92,6 @@ class ArmSVE_IntrOp<string mnemonic, /*bit requiresAccessGroup=*/0, /*bit requiresAliasAnalysis=*/0, /*bit requiresFastmath=*/0, - /*bit requiresArgAndResultAttrs=*/0, /*bit requiresOpBundles=*/0, /*list<int> immArgPositions=*/immArgPositions, /*list<string> immArgAttrNames=*/immArgAttrNames>; diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td index d38298fcb2a38..8c6f1eecdd759 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td @@ -140,8 +140,8 @@ def LLVM_Log2Op : LLVM_UnaryIntrOpF<"log2">; def LLVM_LogOp : LLVM_UnaryIntrOpF<"log">; def LLVM_Prefetch : LLVM_ZeroResultIntrOp<"prefetch", [0], /*traits=*/[], /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0, - /*requiresArgAndResultAttrs=*/0, /*requiresOpBundles=*/0, - /*immArgPositions=*/[1, 2, 3], /*immArgAttrNames=*/["rw", "hint", "cache"] + /*requiresOpBundles=*/0, /*immArgPositions=*/[1, 2, 3], + /*immArgAttrNames=*/["rw", "hint", "cache"] > { let arguments = (ins LLVM_AnyPointer:$addr, I32Attr:$rw, I32Attr:$hint, I32Attr:$cache); } @@ -200,13 +200,13 @@ class LLVM_MemcpyIntrOpBase<string name> : DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>, DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>], /*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1, - /*requiresArgAndResultAttrs=*/1, /*requiresOpBundles=*/0, - /*immArgPositions=*/[3], /*immArgAttrNames=*/["isVolatile"]> { + /*requiresOpBundles=*/0, /*immArgPositions=*/[3], + /*immArgAttrNames=*/["isVolatile"]> { dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst, Arg<LLVM_AnyPointer,"",[MemRead]>:$src, AnySignlessInteger:$len, I1Attr:$isVolatile); - // Append the arguments defined by LLVM_IntrOpBase. - let arguments = !con(args, baseArgs); + // Append the alias attributes defined by LLVM_IntrOpBase. + let arguments = !con(args, aliasAttrs); let builders = [ OpBuilder<(ins "Value":$dst, "Value":$src, "Value":$len, "bool":$isVolatile), [{ @@ -217,8 +217,7 @@ class LLVM_MemcpyIntrOpBase<string name> : "IntegerAttr":$isVolatile), [{ build($_builder, $_state, dst, src, len, isVolatile, /*access_groups=*/nullptr, /*alias_scopes=*/nullptr, - /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr, - /*arg_attrs=*/nullptr, /*res_attrs=*/nullptr); + /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr); }]> ]; } @@ -232,13 +231,13 @@ def LLVM_MemcpyInlineOp : DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>, DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>], /*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1, - /*requiresArgAndResultAttrs=*/1, /*requiresOpBundles=*/0, - /*immArgPositions=*/[2, 3], /*immArgAttrNames=*/["len", "isVolatile"]> { + /*requiresOpBundles=*/0, /*immArgPositions=*/[2, 3], + /*immArgAttrNames=*/["len", "isVolatile"]> { dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst, Arg<LLVM_AnyPointer,"",[MemRead]>:$src, APIntAttr:$len, I1Attr:$isVolatile); - // Append the arguments defined by LLVM_IntrOpBase. - let arguments = !con(args, baseArgs); + // Append the alias attributes defined by LLVM_IntrOpBase. + let arguments = !con(args, aliasAttrs); let builders = [ OpBuilder<(ins "Value":$dst, "Value":$src, "IntegerAttr":$len, "bool":$isVolatile), [{ @@ -249,8 +248,7 @@ def LLVM_MemcpyInlineOp : "IntegerAttr":$isVolatile), [{ build($_builder, $_state, dst, src, len, isVolatile, /*access_groups=*/nullptr, /*alias_scopes=*/nullptr, - /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr, - /*arg_attrs=*/nullptr, /*res_attrs=*/nullptr); + /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr); }]> ]; } @@ -260,12 +258,12 @@ def LLVM_MemsetOp : LLVM_ZeroResultIntrOp<"memset", [0, 2], DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>, DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>], /*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1, - /*requiresArgAndResultAttrs=*/1, /*requiresOpBundles=*/0, - /*immArgPositions=*/[3], /*immArgAttrNames=*/["isVolatile"]> { + /*requiresOpBundles=*/0, /*immArgPositions=*/[3], + /*immArgAttrNames=*/["isVolatile"]> { dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst, I8:$val, AnySignlessInteger:$len, I1Attr:$isVolatile); - // Append the arguments defined by LLVM_IntrOpBase. - let arguments = !con(args, baseArgs); + // Append the alias attributes defined by LLVM_IntrOpBase. + let arguments = !con(args, aliasAttrs); let builders = [ OpBuilder<(ins "Value":$dst, "Value":$val, "Value":$len, "bool":$isVolatile), [{ @@ -276,8 +274,7 @@ def LLVM_MemsetOp : LLVM_ZeroResultIntrOp<"memset", [0, 2], "IntegerAttr":$isVolatile), [{ build($_builder, $_state, dst, val, len, isVolatile, /*access_groups=*/nullptr, /*alias_scopes=*/nullptr, - /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr, - /*arg_attrs=*/nullptr, /*res_attrs=*/nullptr); + /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr); }]> ]; } @@ -287,12 +284,12 @@ def LLVM_MemsetInlineOp : LLVM_ZeroResultIntrOp<"memset.inline", [0, 2], DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>, DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>], /*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1, - /*requiresArgAndResultAttrs=*/1, /*requiresOpBundles=*/0, - /*immArgPositions=*/[2, 3], /*immArgAttrNames=*/["len", "isVolatile"]> { + /*requiresOpBundles=*/0, /*immArgPositions=*/[2, 3], + /*immArgAttrNames=*/["len", "isVolatile"]> { dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst, I8:$val, APIntAttr:$len, I1Attr:$isVolatile); - // Append the arguments defined by LLVM_IntrOpBase. - let arguments = !con(args, baseArgs); + // Append the alias attributes defined by LLVM_IntrOpBase. + let arguments = !con(args, aliasAttrs); let builders = [ OpBuilder<(ins "Value":$dst, "Value":$val, "IntegerAttr":$len, "bool":$isVolatile), [{ @@ -303,8 +300,7 @@ def LLVM_MemsetInlineOp : LLVM_ZeroResultIntrOp<"memset.inline", [0, 2], "IntegerAttr":$isVolatile), [{ build($_builder, $_state, dst, val, len, isVolatile, /*access_groups=*/nullptr, /*alias_scopes=*/nullptr, - /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr, - /*arg_attrs=*/nullptr, /*res_attrs=*/nullptr); + /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr); }]> ]; } @@ -353,8 +349,8 @@ def LLVM_PtrMaskOp class LLVM_LifetimeBaseOp<string opName> : LLVM_ZeroResultIntrOp<opName, [1], [DeclareOpInterfaceMethods<PromotableOpInterface>], /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0, - /*requiresArgAndResultAttrs=*/0, /*requiresOpBundles=*/0, - /*immArgPositions=*/[0], /*immArgAttrNames=*/["size"]> { + /*requiresOpBundles=*/0, /*immArgPositions=*/[0], + /*immArgAttrNames=*/["size"]> { let arguments = (ins I64Attr:$size, LLVM_AnyPointer:$ptr); let assemblyFormat = "$size `,` $ptr attr-dict `:` qualified(type($ptr))"; } @@ -374,8 +370,8 @@ def LLVM_InvariantStartOp : LLVM_OneResultIntrOp<"invariant.start", [], [1], def LLVM_InvariantEndOp : LLVM_ZeroResultIntrOp<"invariant.end", [2], [DeclareOpInterfaceMethods<PromotableOpInterface>], /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0, - /*requiresArgAndResultAttrs=*/0, /*requiresOpBundles=*/0, - /*immArgPositions=*/[1], /*immArgAttrNames=*/["size"]> { + /*requiresOpBundles=*/0, /*immArgPositions=*/[1], + /*immArgAttrNames=*/["size"]> { let arguments = (ins LLVM_DefaultPointer:$start, I64Attr:$size, LLVM_AnyPointer:$ptr); @@ -546,10 +542,9 @@ def LLVM_AssumeOp : LLVM_ZeroResultIntrOp<"assume", /*overloadedOperands=*/[], /*traits=*/[], /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0, - /*requiresArgAndResultAttrs=*/0, /*requiresOpBundles=*/1> { dag args = (ins I1:$cond); - let arguments = !con(args, baseArgs); + let arguments = !con(args, opBundleArgs); let assemblyFormat = [{ $cond @@ -1131,8 +1126,8 @@ def LLVM_DebugTrap : LLVM_ZeroResultIntrOp<"debugtrap">; def LLVM_UBSanTrap : LLVM_ZeroResultIntrOp<"ubsantrap", /*overloadedOperands=*/[], /*traits=*/[], /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0, - /*requiresArgAndResultAttrs=*/0, /*requiresOpBundles=*/0, - /*immArgPositions=*/[0], /*immArgAttrNames=*/["failureKind"]> { + /*requiresOpBundles=*/0, /*immArgPositions=*/[0], + /*immArgAttrNames=*/["failureKind"]> { let arguments = (ins I8Attr:$failureKind); } diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td index a8d7cf2069547..e845ea9f1e604 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td @@ -18,7 +18,6 @@ include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td" include "mlir/Dialect/LLVMIR/LLVMInterfaces.td" include "mlir/IR/OpBase.td" include "mlir/Interfaces/SideEffectInterfaces.td" -include "mlir/Interfaces/CallInterfaces.td" //===----------------------------------------------------------------------===// // LLVM dialect type constraints. @@ -287,26 +286,22 @@ class LLVM_MemAccessOpBase<string mnemonic, list<Trait> traits = []> : // intrinsic and "enumName" contains the name of the intrinsic as appears in // `llvm::Intrinsic` enum; one usually wants these to be related. Additionally, // the base class also defines the "mlirBuilder" field to support the inverse -// translation starting from an LLVM IR intrinsic. -// -// The flags "requiresAccessGroup", "requiresAliasAnalysis", -// "requiresFastmath", and "requiresArgAndResultAttrs" indicate which -// interfaces the intrinsic implements. When a flag is set, the "baseArgs" -// list includes the arguments required by the corresponding interface. -// Derived intrinsics must append "baseArgs" to their argument list if they -// enable any of these flags. -// -// LLVM `immargs` can be represented as MLIR attributes by providing both -// the `immArgPositions` and `immArgAttrNames` lists. These two lists should -// have equal length, with `immArgPositions` containing the argument -// positions on the LLVM IR attribute that are `immargs`, and -// `immArgAttrNames` mapping these to corresponding MLIR attributes. +// translation starting from an LLVM IR intrinsic. The "requiresAccessGroup", +// "requiresAliasAnalysis", and "requiresFastmath" flags specify which +// interfaces the intrinsic implements. If the corresponding flags are set, the +// "aliasAttrs" list contains the arguments required by the access group and +// alias analysis interfaces. Derived intrinsics should append the "aliasAttrs" +// to their argument list if they set one of the flags. LLVM `immargs` can be +// represented as MLIR attributes by providing both the `immArgPositions` and +// `immArgAttrNames` lists. These two lists should have equal length, with +// `immArgPositions` containing the argument positions on the LLVM IR attribute +// that are `immargs`, and `immArgAttrNames` mapping these to corresponding +// MLIR attributes. class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName, list<int> overloadedResults, list<int> overloadedOperands, list<Trait> traits, int numResults, bit requiresAccessGroup = 0, bit requiresAliasAnalysis = 0, - bit requiresFastmath = 0, bit requiresArgAndResultAttrs = 0, - bit requiresOpBundles = 0, + bit requiresFastmath = 0, bit requiresOpBundles = 0, list<int> immArgPositions = [], list<string> immArgAttrNames = []> : LLVM_OpBase<dialect, opName, !listconcat( @@ -316,12 +311,10 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName, [DeclareOpInterfaceMethods<AliasAnalysisOpInterface>], []), !if(!gt(requiresFastmath, 0), [DeclareOpInterfaceMethods<FastmathFlagsInterface>], []), - !if(!gt(requiresArgAndResultAttrs, 0), - [DeclareOpInterfaceMethods<ArgAndResultAttrsOpInterface>], []), traits)>, LLVM_MemOpPatterns, Results<!if(!gt(numResults, 0), (outs LLVM_Type:$res), (outs))> { - dag baseArgs = !con( + dag aliasAttrs = !con( !if(!gt(requiresAccessGroup, 0), (ins OptionalAttr<LLVM_AccessGroupArrayAttr>:$access_groups), (ins )), @@ -329,17 +322,13 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName, (ins OptionalAttr<LLVM_AliasScopeArrayAttr>:$alias_scopes, OptionalAttr<LLVM_AliasScopeArrayAttr>:$noalias_scopes, OptionalAttr<LLVM_TBAATagArrayAttr>:$tbaa), - (ins )), - !if(!gt(requiresArgAndResultAttrs, 0), - (ins OptionalAttr<DictArrayAttr>:$arg_attrs, - OptionalAttr<DictArrayAttr>:$res_attrs), - (ins )), - !if(!gt(requiresOpBundles, 0), - (ins VariadicOfVariadic<LLVM_Type, - "op_bundle_sizes">:$op_bundle_operands, - DenseI32ArrayAttr:$op_bundle_sizes, - OptionalAttr<ArrayAttr>:$op_bundle_tags), (ins ))); + dag opBundleArgs = !if(!gt(requiresOpBundles, 0), + (ins VariadicOfVariadic<LLVM_Type, + "op_bundle_sizes">:$op_bundle_operands, + DenseI32ArrayAttr:$op_bundle_sizes, + OptionalAttr<ArrayAttr>:$op_bundle_tags), + (ins )); string llvmEnumName = enumName; string overloadedResultsCpp = "{" # !interleave(overloadedResults, ", ") # "}"; string overloadedOperandsCpp = "{" # !interleave(overloadedOperands, ", ") # "}"; @@ -353,35 +342,23 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName, immArgPositionsCpp, immArgAttrNamesCpp], ",") # [{); (void) inst; }]; - string baseLlvmBuilderArgAndResultAttrs = [{ - if (failed(moduleTranslation.convertArgAndResultAttrs( - op, - inst, - }] # immArgPositionsCpp # [{))) { - return failure(); - } - }]; string baseLlvmBuilderCoda = !if(!gt(numResults, 0), "$res = inst;", ""); - let llvmBuilder = baseLlvmBuilder - # !if(!gt(requiresAccessGroup, 0), - setAccessGroupsMetadataCode, "") - # !if(!gt(requiresAliasAnalysis, 0), - setAliasAnalysisMetadataCode, "") - # !if(!gt(requiresArgAndResultAttrs, 0), - baseLlvmBuilderArgAndResultAttrs, "") - # baseLlvmBuilderCoda; + let llvmBuilder = baseLlvmBuilder # !if(!gt(requiresAccessGroup, 0), setAccessGroupsMetadataCode, "") + # !if(!gt(requiresAliasAnalysis, 0), setAliasAnalysisMetadataCode, "") + # baseLlvmBuilderCoda; string baseMlirBuilder = [{ SmallVector<Value> mlirOperands; SmallVector<NamedAttribute> mlirAttrs; if (failed(moduleImport.convertIntrinsicArguments( - llvmOperands, - llvmOpBundles, - }] # !if(!gt(requiresOpBundles, 0), "true", "false") # [{, - }] # immArgPositionsCpp # [{, - }] # immArgAttrNamesCpp # [{, - mlirOperands, - mlirAttrs))) { + llvmOperands, + llvmOpBundles, + }] # !if(!gt(requiresOpBundles, 0), "true", "false") # [{, + }] # immArgPositionsCpp # [{, + }] # immArgAttrNamesCpp # [{, + mlirOperands, + mlirAttrs)) + ) { return failure(); } SmallVector<Type> resultTypes = @@ -389,16 +366,9 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName, auto op = $_qualCppClassName::create($_builder, $_location, resultTypes, mlirOperands, mlirAttrs); }]; - string baseMlirBuilderArgAndResultAttrs = [{ - moduleImport.convertArgAndResultAttrs( - inst, op, }] # immArgPositionsCpp # [{); - }]; string baseMlirBuilderCoda = !if(!gt(numResults, 0), "$res = op;", "$_op = op;"); - let mlirBuilder = baseMlirBuilder - # !if(!gt(requiresFastmath, 0), + let mlirBuilder = baseMlirBuilder # !if(!gt(requiresFastmath, 0), "moduleImport.setFastmathFlagsAttr(inst, op);", "") - # !if(!gt(requiresArgAndResultAttrs, 0), - baseMlirBuilderArgAndResultAttrs, "") # baseMlirBuilderCoda; // Code for handling a `range` attribute that holds the constant range of the @@ -429,14 +399,14 @@ class LLVM_IntrOp<string mnem, list<int> overloadedResults, list<int> overloadedOperands, list<Trait> traits, int numResults, bit requiresAccessGroup = 0, bit requiresAliasAnalysis = 0, bit requiresFastmath = 0, - bit requiresArgAndResultAttrs = 0, bit requiresOpBundles = 0, + bit requiresOpBundles = 0, list<int> immArgPositions = [], list<string> immArgAttrNames = []> : LLVM_IntrOpBase<LLVM_Dialect, "intr." # mnem, !subst(".", "_", mnem), overloadedResults, overloadedOperands, traits, numResults, requiresAccessGroup, requiresAliasAnalysis, - requiresFastmath, requiresArgAndResultAttrs, - requiresOpBundles, immArgPositions, immArgAttrNames>; + requiresFastmath, requiresOpBundles, immArgPositions, + immArgAttrNames>; // Base class for LLVM intrinsic operations returning no results. Places the // intrinsic into the LLVM dialect and prefixes its name with "intr.". @@ -456,14 +426,13 @@ class LLVM_ZeroResultIntrOp<string mnem, list<int> overloadedOperands = [], list<Trait> traits = [], bit requiresAccessGroup = 0, bit requiresAliasAnalysis = 0, - bit requiresArgAndResultAttrs = 0, bit requiresOpBundles = 0, list<int> immArgPositions = [], list<string> immArgAttrNames = []> : LLVM_IntrOp<mnem, [], overloadedOperands, traits, /*numResults=*/0, requiresAccessGroup, requiresAliasAnalysis, - /*requiresFastMath=*/0, requiresArgAndResultAttrs, - requiresOpBundles, immArgPositions, immArgAttrNames>; + /*requiresFastMath=*/0, requiresOpBundles, immArgPositions, + immArgAttrNames>; // Base class for LLVM intrinsic operations returning one result. Places the // intrinsic into the LLVM dialect and prefixes its name with "intr.". This is @@ -479,8 +448,7 @@ class LLVM_OneResultIntrOp<string mnem, list<int> overloadedResults = [], list<string> immArgAttrNames = []> : LLVM_IntrOp<mnem, overloadedResults, overloadedOperands, traits, 1, /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0, - requiresFastmath, /*requiresArgAndResultAttrs=*/0, - /*requiresOpBundles=*/0, immArgPositions, + requiresFastmath, /*requiresOpBundles=*/0, immArgPositions, immArgAttrNames>; // Base class for LLVM intrinsic operations returning two results. Places the @@ -497,8 +465,7 @@ class LLVM_TwoResultIntrOp<string mnem, list<int> overloadedResults = [], list<string> immArgAttrNames = []> : LLVM_IntrOp<mnem, overloadedResults, overloadedOperands, traits, 2, /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0, - requiresFastmath, /*requiresArgAndResultAttrs=*/0, - /*requiresOpBundles=*/0, immArgPositions, + requiresFastmath, /*requiresOpBundles=*/0, immArgPositions, immArgAttrNames>; def LLVM_OneResultOpBuilder : diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td index 3f27f6d9ae8b7..51004f592eca4 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -2405,8 +2405,7 @@ def LLVM_InlineAsmOp : LLVM_Op<"inline_asm", [DeclareOpInterfaceMethods<MemoryEf def LLVM_CallIntrinsicOp : LLVM_Op<"call_intrinsic", - [ArgAndResultAttrsOpInterface, - AttrSizedOperandSegments, + [AttrSizedOperandSegments, DeclareOpInterfaceMethods<FastmathFlagsInterface>]> { let summary = "Call to an LLVM intrinsic function."; let description = [{ diff --git a/mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td b/mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td index a2354e22e2745..04a0b58a85211 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td @@ -98,7 +98,7 @@ class ROCDL_IntrOp<string mnemonic, list<int> overloadedResults, LLVM_IntrOpBase<ROCDL_Dialect, mnemonic, "amdgcn_" # !subst(".", "_", mnemonic), overloadedResults, overloadedOperands, traits, numResults, requiresAccessGroup, - requiresAliasAnalysis, 0, 0, 0, immArgPositions, immArgAttrNames>; + requiresAliasAnalysis, 0, 0, immArgPositions, immArgAttrNames>; // Subclass to save typing and ease readibility when there aren't overloaded // operands or memory accesses. @@ -482,7 +482,7 @@ def ROCDLBufferLDS : LLVM_PointerInAddressSpace<3>; class ROCDL_LDS_Read_Tr_IntrOp<string mnemonic> : ROCDL_IntrOp<mnemonic, [1], [], [], 1, 0, 1> { dag args = (ins Arg<ROCDLBufferLDS, "", [MemRead]>:$ptr); - let arguments = !con(args, baseArgs); + let arguments = !con(args, aliasAttrs); let assemblyFormat = "$ptr attr-dict `:` type($ptr) `->` type($res)"; let extraClassDefinition = [{ ::llvm::SmallVector<::mlir::Value> $cppClass::getAccessedOperands() { @@ -507,7 +507,7 @@ def ROCDL_LoadToLDSOp : I32Attr:$size, I32Attr:$offset, I32Attr:$aux); - let arguments = !con(args, baseArgs); + let arguments = !con(args, aliasAttrs); let assemblyFormat = [{ $globalPtr `,` $ldsPtr `,` $size `,` $offset `,` $aux attr-dict `:` type($globalPtr) @@ -526,7 +526,7 @@ def ROCDL_GlobalLoadLDSOp : I32Attr:$size, I32Attr:$offset, I32Attr:$aux); - let arguments = !con(args, baseArgs); + let arguments = !con(args, aliasAttrs); let assemblyFormat = [{ $globalPtr `,` $ldsPtr `,` $size `,` $offset `,` $aux attr-dict @@ -561,7 +561,7 @@ def ROCDL_RawPtrBufferLoadOp : I32:$offset, I32:$soffset, I32:$aux); - let arguments = !con(args, baseArgs); + let arguments = !con(args, aliasAttrs); let assemblyFormat = "operands attr-dict `:` type($res)"; let extraClassDefinition = [{ ::llvm::SmallVector<::mlir::Value> $cppClass::getAccessedOperands() { @@ -579,7 +579,7 @@ def ROCDL_RawPtrBufferLoadLdsOp : I32:$soffset, I32:$offset, I32:$aux); - let arguments = !con(args, baseArgs); + let arguments = !con(args, aliasAttrs); let assemblyFormat = "operands attr-dict"; let extraClassDefinition = [{ ::llvm::SmallVector<::mlir::Value> $cppClass::getAccessedOperands() { @@ -595,7 +595,7 @@ def ROCDL_RawPtrBufferStoreOp : I32:$offset, I32:$soffset, I32:$aux); - let arguments = !con(args, baseArgs); + let arguments = !con(args, aliasAttrs); let assemblyFormat = "operands attr-dict `:` type($vdata)"; let extraClassDefinition = [{ ::llvm::SmallVector<::mlir::Value> $cppClass::getAccessedOperands() { @@ -614,7 +614,7 @@ def ROCDL_RawPtrBufferAtomicCmpSwap : I32:$offset, I32:$soffset, I32:$aux); - let arguments = !con(args, baseArgs); + let arguments = !con(args, aliasAttrs); let assemblyFormat = "operands attr-dict `:` type($res)"; let extraClassDefinition = [{ ::llvm::SmallVector<::mlir::Value> $cppClass::getAccessedOperands() { @@ -630,7 +630,7 @@ class ROCDL_RawPtrBufferAtomicNoRet<string op> : I32:$offset, I32:$soffset, I32:$aux); - let arguments = !con(args, baseArgs); + let arguments = !con(args, aliasAttrs); let assemblyFormat = "operands attr-dict `:` type($vdata)"; let extraClassDefinition = [{ ::llvm::SmallVector<::mlir::Value> $cppClass::getAccessedOperands() { diff --git a/mlir/include/mlir/Interfaces/CallInterfaces.td b/mlir/include/mlir/Interfaces/CallInterfaces.td index b0aa1be4aee80..e3c2aec401741 100644 --- a/mlir/include/mlir/Interfaces/CallInterfaces.td +++ b/mlir/include/mlir/Interfaces/CallInterfaces.td @@ -18,16 +18,10 @@ include "mlir/IR/OpBase.td" -/// Interface for operations with result and argument attributes. -def ArgAndResultAttrsOpInterface : OpInterface<"ArgAndResultAttrsOpInterface"> { - let description = [{ - An operation that has argument and result attributes. This interface - provides functions to access and modify the argument and result - attributes of the operation. - }]; - let cppNamespace = "::mlir"; - - let methods = [ +/// Interface for operations with arguments attributes (both call-like +/// and callable operations). +def ArgumentAttributesMethods { + list<InterfaceMethod> methods = [ InterfaceMethod<[{ Get the array of argument attribute dictionaries. The method should return an array attribute containing only dictionary attributes equal in @@ -70,8 +64,7 @@ def ArgAndResultAttrsOpInterface : OpInterface<"ArgAndResultAttrsOpInterface"> { // a call-like operation. This represents the destination of the call. /// Interface for call-like operations. -def CallOpInterface : OpInterface<"CallOpInterface", - [ArgAndResultAttrsOpInterface]> { +def CallOpInterface : OpInterface<"CallOpInterface"> { let description = [{ A call-like operation is one that transfers control from one sub-routine to another. These operations may be traditional direct calls `call @foo`, or @@ -130,12 +123,11 @@ def CallOpInterface : OpInterface<"CallOpInterface", return ::mlir::call_interface_impl::resolveCallable($_op); }] > - ]; + ] # ArgumentAttributesMethods.methods; } /// Interface for callable operations. -def CallableOpInterface : OpInterface<"CallableOpInterface", - [ArgAndResultAttrsOpInterface]> { +def CallableOpInterface : OpInterface<"CallableOpInterface"> { let description = [{ A callable operation is one who represents a potential sub-routine, and may be a target for a call-like operation (those providing the CallOpInterface @@ -148,11 +140,11 @@ def CallableOpInterface : OpInterface<"CallableOpInterface", let methods = [ InterfaceMethod<[{ - Returns the region on the current operation that is callable. This may - return null in the case of an external callable object, e.g. an external - function. - }], - "::mlir::Region *", "getCallableRegion">, + Returns the region on the current operation that is callable. This may + return null in the case of an external callable object, e.g. an external + function. + }], + "::mlir::Region *", "getCallableRegion">, InterfaceMethod<[{ Returns the callable's argument types based exclusively on the type (to allow for this method may be called on function declarations). @@ -163,7 +155,7 @@ def CallableOpInterface : OpInterface<"CallableOpInterface", allow for this method may be called on function declarations). }], "::llvm::ArrayRef<::mlir::Type>", "getResultTypes">, - ]; + ] # ArgumentAttributesMethods.methods; } #endif // MLIR_INTERFACES_CALLINTERFACES diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h index b22ed60bc7d1b..17ef8e44afd2d 100644 --- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h +++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h @@ -291,12 +291,10 @@ class ModuleImport { SmallVectorImpl<Value> &valuesOut, SmallVectorImpl<NamedAttribute> &attrsOut); - /// Converts the argument and result attributes attached to `call` and adds - /// them to `attrsOp`. For intrinsic calls, filters out attributes - /// corresponding to immediate arguments specified by `immArgPositions`. - void convertArgAndResultAttrs(llvm::CallBase *call, - ArgAndResultAttrsOpInterface attrsOp, - ArrayRef<unsigned> immArgPositions = {}); + /// Converts the parameter and result attributes in `argsAttr` and `resAttr` + /// and add them to the `callOp`. + void convertParameterAttributes(llvm::CallBase *call, ArrayAttr &argsAttr, + ArrayAttr &resAttr, OpBuilder &builder); /// Whether the importer should try to convert all intrinsics to /// llvm.call_intrinsic instead of dialect supported operations. @@ -380,12 +378,19 @@ class ModuleImport { bool &isIncompatibleCall); /// Returns the callee name, or an empty symbol if the call is not direct. FlatSymbolRefAttr convertCalleeName(llvm::CallBase *callInst); - /// Converts the argument and result attributes attached to `func` and adds + /// Converts the parameter and result attributes attached to `func` and adds /// them to the `funcOp`. - void convertArgAndResultAttrs(llvm::Function *func, LLVMFuncOp funcOp); - /// Converts the argument or result attributes in `llvmAttrSet` to a - /// corresponding MLIR LLVM dialect attribute dictionary. - DictionaryAttr convertArgOrResultAttrSet(llvm::AttributeSet llvmAttrSet); + void convertParameterAttributes(llvm::Function *func, LLVMFuncOp funcOp, + OpBuilder &builder); + /// Converts the AttributeSet of one parameter in LLVM IR to a corresponding + /// DictionaryAttr for the LLVM dialect. + DictionaryAttr convertParameterAttribute(llvm::AttributeSet llvmParamAttrs, + OpBuilder &builder); + /// Converts the parameter and result attributes attached to `call` and adds + /// them to the `callOp`. Implemented in terms of the the public definition of + /// convertParameterAttributes. + void convertParameterAttributes(llvm::CallBase *call, CallOpInterface callOp, + OpBuilder &builder); /// Converts the attributes attached to `inst` and adds them to the `op`. LogicalResult convertCallAttributes(llvm::CallInst *inst, CallOp op); /// Converts the attributes attached to `inst` and adds them to the `op`. diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h index b262704511072..f0bd5245a7d41 100644 --- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h +++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h @@ -307,16 +307,10 @@ class ModuleTranslation { /*recordInsertions=*/false); } - /// Converts argument and result attributes from `attrsOp` to LLVM IR - /// attributes on the `call` instruction. Returns failure if conversion fails. - /// The `immArgPositions` parameter is only relevant for intrinsics. It - /// specifies the positions of immediate arguments, which do not have - /// associated argument attributes in MLIR and should be skipped during - /// attribute mapping. - LogicalResult - convertArgAndResultAttrs(ArgAndResultAttrsOpInterface attrsOp, - llvm::CallBase *call, - ArrayRef<unsigned> immArgPositions = {}); + /// Translates parameter attributes of a call and adds them to the returned + /// AttrBuilder. Returns failure if any of the translations failed. + FailureOr<llvm::AttrBuilder> convertParameterAttrs(mlir::Location loc, + DictionaryAttr paramAttrs); /// Gets the named metadata in the LLVM IR module being constructed, creating /// it if it does not exist. @@ -396,11 +390,6 @@ class ModuleTranslation { convertDialectAttributes(Operation *op, ArrayRef<llvm::Instruction *> instructions); - /// Translates parameter attributes of a call and adds them to the returned - /// AttrBuilder. Returns failure if any of the translations failed. - FailureOr<llvm::AttrBuilder> convertParameterAttrs(mlir::Location loc, - DictionaryAttr paramAttrs); - /// Translates parameter attributes of a function and adds them to the /// returned AttrBuilder. Returns failure if any of the translations failed. FailureOr<llvm::AttrBuilder> diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp index 0f675a0a5df5d..ff34a0825215c 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp @@ -13,7 +13,6 @@ #include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/IR/Operation.h" -#include "mlir/Interfaces/CallInterfaces.h" #include "mlir/Support/LLVM.h" #include "mlir/Target/LLVMIR/ModuleTranslation.h" @@ -137,6 +136,46 @@ convertOperandBundles(OperandRangeRange bundleOperands, return convertOperandBundles(bundleOperands, *bundleTags, moduleTranslation); } +static LogicalResult +convertParameterAndResultAttrs(mlir::Location loc, ArrayAttr argAttrsArray, + ArrayAttr resAttrsArray, llvm::CallBase *call, + LLVM::ModuleTranslation &moduleTranslation) { + if (argAttrsArray) { + for (auto [argIdx, argAttrsAttr] : llvm::enumerate(argAttrsArray)) { + if (auto argAttrs = cast<DictionaryAttr>(argAttrsAttr); + !argAttrs.empty()) { + FailureOr<llvm::AttrBuilder> attrBuilder = + moduleTranslation.convertParameterAttrs(loc, argAttrs); + if (failed(attrBuilder)) + return failure(); + call->addParamAttrs(argIdx, *attrBuilder); + } + } + } + + if (resAttrsArray && resAttrsArray.size() > 0) { + if (resAttrsArray.size() != 1) + return mlir::emitError(loc, "llvm.func cannot have multiple results"); + if (auto resAttrs = cast<DictionaryAttr>(resAttrsArray[0]); + !resAttrs.empty()) { + FailureOr<llvm::AttrBuilder> attrBuilder = + moduleTranslation.convertParameterAttrs(loc, resAttrs); + if (failed(attrBuilder)) + return failure(); + call->addRetAttrs(*attrBuilder); + } + } + return success(); +} + +static LogicalResult +convertParameterAndResultAttrs(CallOpInterface callOp, llvm::CallBase *call, + LLVM::ModuleTranslation &moduleTranslation) { + return convertParameterAndResultAttrs( + callOp.getLoc(), callOp.getArgAttrsAttr(), callOp.getResAttrsAttr(), call, + moduleTranslation); +} + /// Builder for LLVM_CallIntrinsicOp static LogicalResult convertCallLLVMIntrinsicOp(CallIntrinsicOp op, llvm::IRBuilderBase &builder, @@ -204,7 +243,9 @@ convertCallLLVMIntrinsicOp(CallIntrinsicOp op, llvm::IRBuilderBase &builder, convertOperandBundles(op.getOpBundleOperands(), op.getOpBundleTags(), moduleTranslation)); - if (failed(moduleTranslation.convertArgAndResultAttrs(op, inst))) + if (failed(convertParameterAndResultAttrs(op.getLoc(), op.getArgAttrsAttr(), + op.getResAttrsAttr(), inst, + moduleTranslation))) return failure(); if (op.getNumResults() == 1) @@ -414,7 +455,7 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder, if (callOp.getInlineHintAttr()) call->addFnAttr(llvm::Attribute::InlineHint); - if (failed(moduleTranslation.convertArgAndResultAttrs(callOp, call))) + if (failed(convertParameterAndResultAttrs(callOp, call, moduleTranslation))) return failure(); if (MemoryEffectsAttr memAttr = callOp.getMemoryEffectsAttr()) { @@ -528,7 +569,8 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder, operandsRef.drop_front(), opBundles); } result->setCallingConv(convertCConvToLLVM(invOp.getCConv())); - if (failed(moduleTranslation.convertArgAndResultAttrs(invOp, result))) + if (failed( + convertParameterAndResultAttrs(invOp, result, moduleTranslation))) return failure(); moduleTranslation.mapBranch(invOp, result); // InvokeOp can only have 0 or 1 result diff --git a/mlir/lib/Target/LLVMIR/LLVMImportInterface.cpp b/mlir/lib/Target/LLVMIR/LLVMImportInterface.cpp index cb1f234aca50b..580afdddd7078 100644 --- a/mlir/lib/Target/LLVMIR/LLVMImportInterface.cpp +++ b/mlir/lib/Target/LLVMIR/LLVMImportInterface.cpp @@ -33,9 +33,7 @@ LogicalResult mlir::LLVMImportInterface::convertUnregisteredIntrinsic( SmallVector<Value> mlirOperands; SmallVector<NamedAttribute> mlirAttrs; if (failed(moduleImport.convertIntrinsicArguments( - llvmOperands, llvmOpBundles, /*requiresOpBundles=*/false, - /*immArgPositions=*/{}, /*immArgAttrNames=*/{}, mlirOperands, - mlirAttrs))) + llvmOperands, llvmOpBundles, false, {}, {}, mlirOperands, mlirAttrs))) return failure(); Type resultType = moduleImport.convertType(inst->getType()); @@ -46,7 +44,11 @@ LogicalResult mlir::LLVMImportInterface::convertUnregisteredIntrinsic( ValueRange{mlirOperands}, FastmathFlagsAttr{}); moduleImport.setFastmathFlagsAttr(inst, op); - moduleImport.convertArgAndResultAttrs(inst, op); + + ArrayAttr argsAttr, resAttr; + moduleImport.convertParameterAttributes(inst, argsAttr, resAttr, builder); + op.setArgAttrsAttr(argsAttr); + op.setResAttrsAttr(resAttr); // Update importer tracking of results. unsigned numRes = op.getNumResults(); diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index a207cceef88b5..58e3c44ec0049 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -2267,7 +2267,7 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) { // Handle parameter and result attributes unless it's an incompatible // call. if (!isIncompatibleCall) - convertArgAndResultAttrs(callInst, callOp); + convertParameterAttributes(callInst, callOp, builder); return callOp.getOperation(); }(); @@ -2364,7 +2364,7 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) { // Handle parameter and result attributes unless it's an incompatible // invoke. if (!isIncompatibleInvoke) - convertArgAndResultAttrs(invokeInst, invokeOp); + convertParameterAttributes(invokeInst, invokeOp, builder); if (!invokeInst->getType()->isVoidTy()) mapValue(inst, invokeOp.getResults().front()); @@ -2730,10 +2730,11 @@ void ModuleImport::processFunctionAttributes(llvm::Function *func, } DictionaryAttr -ModuleImport::convertArgOrResultAttrSet(llvm::AttributeSet llvmAttrSet) { +ModuleImport::convertParameterAttribute(llvm::AttributeSet llvmParamAttrs, + OpBuilder &builder) { SmallVector<NamedAttribute> paramAttrs; for (auto [llvmKind, mlirName] : getAttrKindToNameMapping()) { - auto llvmAttr = llvmAttrSet.getAttribute(llvmKind); + auto llvmAttr = llvmParamAttrs.getAttribute(llvmKind); // Skip attributes that are not attached. if (!llvmAttr.isValid()) continue; @@ -2768,12 +2769,13 @@ ModuleImport::convertArgOrResultAttrSet(llvm::AttributeSet llvmAttrSet) { return builder.getDictionaryAttr(paramAttrs); } -void ModuleImport::convertArgAndResultAttrs(llvm::Function *func, - LLVMFuncOp funcOp) { +void ModuleImport::convertParameterAttributes(llvm::Function *func, + LLVMFuncOp funcOp, + OpBuilder &builder) { auto llvmAttrs = func->getAttributes(); for (size_t i = 0, e = funcOp.getNumArguments(); i < e; ++i) { llvm::AttributeSet llvmArgAttrs = llvmAttrs.getParamAttrs(i); - funcOp.setArgAttrs(i, convertArgOrResultAttrSet(llvmArgAttrs)); + funcOp.setArgAttrs(i, convertParameterAttribute(llvmArgAttrs, builder)); } // Convert the result attributes and attach them wrapped in an ArrayAttribute // to the funcOp. @@ -2781,23 +2783,17 @@ void ModuleImport::convertArgAndResultAttrs(llvm::Function *func, if (!llvmResAttr.hasAttributes()) return; funcOp.setResAttrsAttr( - builder.getArrayAttr({convertArgOrResultAttrSet(llvmResAttr)})); + builder.getArrayAttr(convertParameterAttribute(llvmResAttr, builder))); } -void ModuleImport::convertArgAndResultAttrs( - llvm::CallBase *call, ArgAndResultAttrsOpInterface attrsOp, - ArrayRef<unsigned> immArgPositions) { - // Compute the set of immediate argument positions. - llvm::SmallDenseSet<unsigned> immArgPositionsSet(immArgPositions.begin(), - immArgPositions.end()); - // Convert the argument attributes and filter out immediate arguments. +void ModuleImport::convertParameterAttributes(llvm::CallBase *call, + ArrayAttr &argsAttr, + ArrayAttr &resAttr, + OpBuilder &builder) { llvm::AttributeList llvmAttrs = call->getAttributes(); SmallVector<llvm::AttributeSet> llvmArgAttrsSet; bool anyArgAttrs = false; for (size_t i = 0, e = call->arg_size(); i < e; ++i) { - // Skip immediate arguments. - if (immArgPositionsSet.contains(i)) - continue; llvmArgAttrsSet.emplace_back(llvmAttrs.getParamAttrs(i)); if (llvmArgAttrsSet.back().hasAttributes()) anyArgAttrs = true; @@ -2811,16 +2807,24 @@ void ModuleImport::convertArgAndResultAttrs( if (anyArgAttrs) { SmallVector<DictionaryAttr> argAttrs; for (auto &llvmArgAttrs : llvmArgAttrsSet) - argAttrs.emplace_back(convertArgOrResultAttrSet(llvmArgAttrs)); - attrsOp.setArgAttrsAttr(getArrayAttr(argAttrs)); + argAttrs.emplace_back(convertParameterAttribute(llvmArgAttrs, builder)); + argsAttr = getArrayAttr(argAttrs); } - // Convert the result attributes. llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs(); if (!llvmResAttr.hasAttributes()) return; - DictionaryAttr resAttrs = convertArgOrResultAttrSet(llvmResAttr); - attrsOp.setResAttrsAttr(getArrayAttr({resAttrs})); + DictionaryAttr resAttrs = convertParameterAttribute(llvmResAttr, builder); + resAttr = getArrayAttr({resAttrs}); +} + +void ModuleImport::convertParameterAttributes(llvm::CallBase *call, + CallOpInterface callOp, + OpBuilder &builder) { + ArrayAttr argsAttr, resAttr; + convertParameterAttributes(call, argsAttr, resAttr, builder); + callOp.setArgAttrsAttr(argsAttr); + callOp.setResAttrsAttr(resAttr); } template <typename Op> @@ -2888,7 +2892,7 @@ LogicalResult ModuleImport::processFunction(llvm::Function *func) { builder, loc, func->getName(), functionType, convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv); - convertArgAndResultAttrs(func, funcOp); + convertParameterAttributes(func, funcOp, builder); if (FlatSymbolRefAttr personality = getPersonalityAsAttr(func)) funcOp.setPersonalityAttr(personality); diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 2685b5c91426e..b997e559885e2 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -1758,48 +1758,6 @@ ModuleTranslation::convertParameterAttrs(LLVMFuncOp func, int argIdx, return attrBuilder; } -LogicalResult ModuleTranslation::convertArgAndResultAttrs( - ArgAndResultAttrsOpInterface attrsOp, llvm::CallBase *call, - ArrayRef<unsigned> immArgPositions) { - // Convert the argument attributes. - if (ArrayAttr argAttrsArray = attrsOp.getArgAttrsAttr()) { - unsigned argAttrIdx = 0; - llvm::SmallDenseSet<unsigned> immArgPositionsSet(immArgPositions.begin(), - immArgPositions.end()); - for (unsigned argIdx : llvm::seq<unsigned>(call->arg_size())) { - if (argAttrIdx >= argAttrsArray.size()) - break; - // Skip immediate arguments (they have no entries in argAttrsArray). - if (immArgPositionsSet.contains(argIdx)) - continue; - // Skip empty argument attributes. - auto argAttrs = cast<DictionaryAttr>(argAttrsArray[argAttrIdx++]); - if (argAttrs.empty()) - continue; - // Convert and add attributes to the call instruction. - FailureOr<llvm::AttrBuilder> attrBuilder = - convertParameterAttrs(attrsOp->getLoc(), argAttrs); - if (failed(attrBuilder)) - return failure(); - call->addParamAttrs(argIdx, *attrBuilder); - } - } - - // Convert the result attributes. - if (ArrayAttr resAttrsArray = attrsOp.getResAttrsAttr()) { - if (!resAttrsArray.empty()) { - auto resAttrs = cast<DictionaryAttr>(resAttrsArray[0]); - FailureOr<llvm::AttrBuilder> attrBuilder = - convertParameterAttrs(attrsOp->getLoc(), resAttrs); - if (failed(attrBuilder)) - return failure(); - call->addRetAttrs(*attrBuilder); - } - } - - return success(); -} - FailureOr<llvm::AttrBuilder> ModuleTranslation::convertParameterAttrs(Location loc, DictionaryAttr paramAttrs) { diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic.ll b/mlir/test/Target/LLVMIR/Import/intrinsic.ll index a419d75be24a6..24380b575753e 100644 --- a/mlir/test/Target/LLVMIR/Import/intrinsic.ll +++ b/mlir/test/Target/LLVMIR/Import/intrinsic.ll @@ -570,10 +570,10 @@ define void @trap_intrinsics() { ; CHECK-LABEL: llvm.func @memcpy_test define void @memcpy_test(i32 %0, ptr %1, ptr %2) { - ; CHECK: "llvm.intr.memcpy"(%{{.*}}, %{{.*}}, %{{.*}}) <{arg_attrs = [{llvm.align = 4 : i64}, {llvm.align = 8 : i64}, {}], isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () - call void @llvm.memcpy.p0.p0.i32(ptr align 4 %1, ptr align 8 %2, i32 %0, i1 false) - ; CHECK: "llvm.intr.memcpy.inline"(%{{.*}}, %{{.*}}) <{arg_attrs = [{}, {llvm.align = 4 : i64}], isVolatile = false, len = 10 : i64}> : (!llvm.ptr, !llvm.ptr) -> () - call void @llvm.memcpy.inline.p0.p0.i64(ptr %1, ptr align 4 %2, i64 10, i1 false) + ; CHECK: "llvm.intr.memcpy"(%{{.*}}, %{{.*}}, %{{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () + call void @llvm.memcpy.p0.p0.i32(ptr %1, ptr %2, i32 %0, i1 false) + ; CHECK: "llvm.intr.memcpy.inline"(%{{.*}}, %{{.*}}) <{isVolatile = false, len = 10 : i64}> : (!llvm.ptr, !llvm.ptr) -> () + call void @llvm.memcpy.inline.p0.p0.i64(ptr %1, ptr %2, i64 10, i1 false) ; CHECK: "llvm.intr.memcpy.inline"(%{{.*}}, %{{.*}}) <{isVolatile = false, len = 10 : i32}> : (!llvm.ptr, !llvm.ptr) -> () call void @llvm.memcpy.inline.p0.p0.i32(ptr %1, ptr %2, i32 10, i1 false) ret void @@ -581,17 +581,17 @@ define void @memcpy_test(i32 %0, ptr %1, ptr %2) { ; CHECK-LABEL: llvm.func @memmove_test define void @memmove_test(i32 %0, ptr %1, ptr %2) { - ; CHECK: "llvm.intr.memmove"(%{{.*}}, %{{.*}}, %{{.*}}) <{arg_attrs = [{llvm.align = 16 : i64}, {}, {}], isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () - call void @llvm.memmove.p0.p0.i32(ptr align 16 %1, ptr %2, i32 %0, i1 false) + ; CHECK: "llvm.intr.memmove"(%{{.*}}, %{{.*}}, %{{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () + call void @llvm.memmove.p0.p0.i32(ptr %1, ptr %2, i32 %0, i1 false) ret void } ; CHECK-LABEL: llvm.func @memset_test define void @memset_test(i32 %0, ptr %1, i8 %2) { - ; CHECK: "llvm.intr.memset"(%{{.*}}, %{{.*}}, %{{.*}}) <{arg_attrs = [{llvm.align = 2 : i64}, {}, {}], isVolatile = false}> : (!llvm.ptr, i8, i32) -> () - call void @llvm.memset.p0.i32(ptr align 2 %1, i8 %2, i32 %0, i1 false) - ; CHECK: "llvm.intr.memset.inline"(%{{.*}}, %{{.*}}) <{arg_attrs = [{llvm.align = 4 : i64}, {}], isVolatile = false, len = 10 : i64}> : (!llvm.ptr, i8) -> () - call void @llvm.memset.inline.p0.i64(ptr align 4 %1, i8 %2, i64 10, i1 false) + ; CHECK: "llvm.intr.memset"(%{{.*}}, %{{.*}}, %{{.*}}) <{isVolatile = false}> : (!llvm.ptr, i8, i32) -> () + call void @llvm.memset.p0.i32(ptr %1, i8 %2, i32 %0, i1 false) + ; CHECK: "llvm.intr.memset.inline"(%{{.*}}, %{{.*}}) <{isVolatile = false, len = 10 : i64}> : (!llvm.ptr, i8) -> () + call void @llvm.memset.inline.p0.i64(ptr %1, i8 %2, i64 10, i1 false) ; CHECK: "llvm.intr.memset.inline"(%{{.*}}, %{{.*}}) <{isVolatile = false, len = 10 : i32}> : (!llvm.ptr, i8) -> () call void @llvm.memset.inline.p0.i32(ptr %1, i8 %2, i32 10, i1 false) ret void diff --git a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir index eb3510ca7317d..44074ce0577e2 100644 --- a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir @@ -601,33 +601,29 @@ llvm.func @trap_intrinsics() { // CHECK-LABEL: @memcpy_test llvm.func @memcpy_test(%arg0: i32, %arg2: !llvm.ptr, %arg3: !llvm.ptr) { - // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %{{.*}}, ptr align 8 %{{.*}}, i32 %{{.*}}, i1 false - "llvm.intr.memcpy"(%arg2, %arg3, %arg0) <{arg_attrs = [{llvm.align = 4 : i64}, {llvm.align = 8 : i64}, {}], isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () - // CHECK: call void @llvm.memcpy.inline.p0.p0.i32(ptr align 4 %{{.*}}, ptr %{{.*}}, i32 10, i1 true - "llvm.intr.memcpy.inline"(%arg2, %arg3) <{arg_attrs = [{llvm.align = 4 : i64}, {}], isVolatile = true, len = 10 : i32}> : (!llvm.ptr, !llvm.ptr) -> () + // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr %{{.*}}, ptr %{{.*}}, i32 %{{.*}}, i1 false + "llvm.intr.memcpy"(%arg2, %arg3, %arg0) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () + // CHECK: call void @llvm.memcpy.inline.p0.p0.i32(ptr %{{.*}}, ptr %{{.*}}, i32 10, i1 true + "llvm.intr.memcpy.inline"(%arg2, %arg3) <{isVolatile = true, len = 10 : i32}> : (!llvm.ptr, !llvm.ptr) -> () // CHECK: call void @llvm.memcpy.inline.p0.p0.i64(ptr %{{.*}}, ptr %{{.*}}, i64 10, i1 true "llvm.intr.memcpy.inline"(%arg2, %arg3) <{isVolatile = true, len = 10 : i64}> : (!llvm.ptr, !llvm.ptr) -> () - - // Verify that trailing empty argument attribute dictionaries can be omitted. - // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %{{.*}}, ptr align 8 %{{.*}}, i32 %{{.*}}, i1 false - "llvm.intr.memcpy"(%arg2, %arg3, %arg0) <{arg_attrs = [{llvm.align = 4 : i64}, {llvm.align = 8 : i64}], isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () llvm.return } // CHECK-LABEL: @memmove_test llvm.func @memmove_test(%arg0: i32, %arg2: !llvm.ptr, %arg3: !llvm.ptr) { - // CHECK: call void @llvm.memmove.p0.p0.i32(ptr align 4 %{{.*}}, ptr align 8 %{{.*}}, i32 %{{.*}}, i1 false - "llvm.intr.memmove"(%arg2, %arg3, %arg0) <{arg_attrs = [{llvm.align = 4 : i64}, {llvm.align = 8 : i64}, {}], isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () + // CHECK: call void @llvm.memmove.p0.p0.i32(ptr %{{.*}}, ptr %{{.*}}, i32 %{{.*}}, i1 false + "llvm.intr.memmove"(%arg2, %arg3, %arg0) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () llvm.return } // CHECK-LABEL: @memset_test llvm.func @memset_test(%arg0: i32, %arg2: !llvm.ptr, %arg3: i8) { %i1 = llvm.mlir.constant(false) : i1 - // CHECK: call void @llvm.memset.p0.i32(ptr align 8 %{{.*}}, i8 %{{.*}}, i32 %{{.*}}, i1 false - "llvm.intr.memset"(%arg2, %arg3, %arg0) <{arg_attrs = [{llvm.align = 8 : i64}, {}, {}], isVolatile = false}> : (!llvm.ptr, i8, i32) -> () - // CHECK: call void @llvm.memset.inline.p0.i32(ptr align 8 %{{.*}}, i8 %{{.*}}, i32 10, i1 true - "llvm.intr.memset.inline"(%arg2, %arg3) <{arg_attrs = [{llvm.align = 8 : i64}, {}], isVolatile = true, len = 10 : i32}> : (!llvm.ptr, i8) -> () + // CHECK: call void @llvm.memset.p0.i32(ptr %{{.*}}, i8 %{{.*}}, i32 %{{.*}}, i1 false + "llvm.intr.memset"(%arg2, %arg3, %arg0) <{isVolatile = false}> : (!llvm.ptr, i8, i32) -> () + // CHECK: call void @llvm.memset.inline.p0.i32(ptr %{{.*}}, i8 %{{.*}}, i32 10, i1 true + "llvm.intr.memset.inline"(%arg2, %arg3) <{isVolatile = true, len = 10 : i32}> : (!llvm.ptr, i8) -> () // CHECK: call void @llvm.memset.inline.p0.i64(ptr %{{.*}}, i8 %{{.*}}, i64 10, i1 true "llvm.intr.memset.inline"(%arg2, %arg3) <{isVolatile = true, len = 10 : i64}> : (!llvm.ptr, i8) -> () llvm.return diff --git a/utils/bazel/llvm-project-overlay/mlir/test/mlir-tblgen/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/test/mlir-tblgen/BUILD.bazel index 5ebdc33dfdd1d..1dd418c75984e 100644 --- a/utils/bazel/llvm-project-overlay/mlir/test/mlir-tblgen/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/test/mlir-tblgen/BUILD.bazel @@ -32,7 +32,6 @@ package(default_visibility = ["//visibility:public"]) "//mlir:include/mlir/IR/BuiltinDialectBytecode.td", "//mlir:include/mlir/IR/BytecodeBase.td", "//mlir:include/mlir/IR/OpBase.td", - "//mlir:include/mlir/Interfaces/CallInterfaces.td", "//mlir:include/mlir/Interfaces/InferTypeOpInterface.td", "//mlir:include/mlir/Interfaces/SideEffectInterfaces.td", "//mlir:include/mlir/Pass/PassBase.td", _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits