diff --git a/mlir/include/mlir/Dialect/ArmNeon/ArmNeon.td b/mlir/include/mlir/Dialect/ArmNeon/ArmNeon.td --- a/mlir/include/mlir/Dialect/ArmNeon/ArmNeon.td +++ b/mlir/include/mlir/Dialect/ArmNeon/ArmNeon.td @@ -38,7 +38,8 @@ // intrinsic. class ArmNeon_IntrOp overloadedResults, list overloadedOperands, int numResults, - list traits = [], bit requiresAccessGroup = 0> + list traits = [], bit requiresAccessGroup = 0, + bit requiresAliasScope = 0> : LLVM_IntrOpBase; + /*requiresAccessGroup=*/requiresAccessGroup, + /*requiresAliasScope=*/requiresAliasScope>; // ArmNeon dialect op that corresponds to an LLVM IR intrinsic with one // overloaded result. diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td @@ -255,7 +255,7 @@ class LLVM_IntrOpBase overloadedResults, list overloadedOperands, list traits, int numResults, - bit requiresAccessGroup = 0> + bit requiresAccessGroup = 0, bit requiresAliasScope = 0> : LLVM_OpBase, Results { string resultPattern = !if(!gt(numResults, 1), @@ -276,6 +276,9 @@ }] # !if(!gt(requiresAccessGroup, 0), "moduleTranslation.setAccessGroupsMetadata(op, inst);", "(void) inst;") + # !if(!gt(requiresAliasScope, 0), + "moduleTranslation.setAliasScopeMetadata(op, inst);", + "(void) inst;") # !if(!gt(numResults, 0), "$res = inst;", ""); } @@ -283,10 +286,11 @@ // the intrinsic into the LLVM dialect and prefixes its name with "intr.". class LLVM_IntrOp overloadedResults, list overloadedOperands, list traits, - int numResults, bit requiresAccessGroup = 0> + int numResults, bit requiresAccessGroup = 0, + bit requiresAliasScope = 0> : LLVM_IntrOpBase; + numResults, requiresAccessGroup, requiresAliasScope>; // Base class for LLVM intrinsic operations returning no results. Places the // intrinsic into the LLVM dialect and prefixes its name with "intr.". diff --git a/mlir/test/mlir-tblgen/llvm-intrinsics.td b/mlir/test/mlir-tblgen/llvm-intrinsics.td --- a/mlir/test/mlir-tblgen/llvm-intrinsics.td +++ b/mlir/test/mlir-tblgen/llvm-intrinsics.td @@ -25,6 +25,8 @@ // It has a result. // CHECK: 1, // It does not require an access group. +// CHECK: 0, +// It does not require alias scopes. // CHECK: 0> // CHECK: Arguments<(ins LLVM_Type, LLVM_Type @@ -44,12 +46,37 @@ // It has a result. // GROUPS: 1, // It requires generation of an access group LLVM metadata. -// GROUPS: 1> +// GROUPS: 1, +// It does not require alias scopes. +// GROUPS: 0> // It has an access group attribute. // GROUPS: OptionalAttr:$access_groups //---------------------------------------------------------------------------// +// This checks that we can define an op that takes in alias scopes metadata. +// +// RUN: cat %S/../../../llvm/include/llvm/IR/Intrinsics.td \ +// RUN: | grep -v "llvm/IR/Intrinsics" \ +// RUN: | mlir-tblgen -gen-llvmir-intrinsics -I %S/../../../llvm/include/ --llvmir-intrinsics-filter=ptrmask --llvmir-intrinsics-alias-scopes-regexp=ptrmask \ +// RUN: | FileCheck --check-prefix=ALIAS %s + +// ALIAS-LABEL: def LLVM_ptrmask +// ALIAS: LLVM_IntrOp<"ptrmask +// It has no side effects. +// ALIAS: [NoSideEffect] +// It has a result. +// ALIAS: 1, +// It does not require an access group. +// ALIAS: 0, +// It requires generation of alias scopes LLVM metadata. +// ALIAS: 1> +// It has alias scopes and noalias. +// ALIAS: OptionalAttr:$alias_scopes +// ALIAS: OptionalAttr:$noalias_scopes + +//---------------------------------------------------------------------------// + // This checks that the ODS we produce can be consumed by MLIR tablegen. We only // make sure the entire process does not fail and produces some C++. The shape // of this C++ code is tested by ODS tests. diff --git a/mlir/tools/mlir-tblgen/LLVMIRIntrinsicGen.cpp b/mlir/tools/mlir-tblgen/LLVMIRIntrinsicGen.cpp --- a/mlir/tools/mlir-tblgen/LLVMIRIntrinsicGen.cpp +++ b/mlir/tools/mlir-tblgen/LLVMIRIntrinsicGen.cpp @@ -44,6 +44,12 @@ "regexp as taking an access group metadata"), llvm::cl::cat(IntrinsicGenCat)); +static llvm::cl::opt aliasScopesRegexp( + "llvmir-intrinsics-alias-scopes-regexp", + llvm::cl::desc("Mark intrinsics that match the specified " + "regexp as taking alias.scopes and noalias metadata"), + llvm::cl::cat(IntrinsicGenCat)); + // Used to represent the indices of overloadable operands/results. using IndicesTy = llvm::SmallBitVector; @@ -196,6 +202,10 @@ bool requiresAccessGroup = !accessGroupRegexp.empty() && accessGroupMatcher.match(record.getName()); + llvm::Regex aliasScopesMatcher(aliasScopesRegexp); + bool requiresAliasScopes = + !aliasScopesRegexp.empty() && aliasScopesMatcher.match(record.getName()); + // Prepare strings for traits, if any. llvm::SmallVector traits; if (intr.isCommutative()) @@ -208,6 +218,10 @@ "LLVM_Type"); if (requiresAccessGroup) operands.push_back("OptionalAttr:$access_groups"); + if (requiresAliasScopes) { + operands.push_back("OptionalAttr:$alias_scopes"); + operands.push_back("OptionalAttr:$noalias_scopes"); + } // Emit the definition. os << "def LLVM_" << intr.getProperRecordName() << " : " << opBaseClass @@ -218,7 +232,8 @@ os << ", "; printBracketedRange(traits, os); os << ", " << intr.getNumResults() << ", " - << (requiresAccessGroup ? "1" : "0") << ">, Arguments<(ins" + << (requiresAccessGroup ? "1" : "0") << ", " + << (requiresAliasScopes ? "1" : "0") << ">, Arguments<(ins" << (operands.empty() ? "" : " "); llvm::interleaveComma(operands, os); os << ")>;\n\n";