Skip to content

Commit

Permalink
[mlir][llvm] Add AliasAnalysis and AccessGroup interfaces to intrinsics.
Browse files Browse the repository at this point in the history
This revision updates the memcpy, memove, and memset intrinsics to
implement the AliasAnalysis and AccessGroup interfaces. The changes
will enable the import and export of alias scope, tbaa, and
access group metadata attached to these intrinsics. It also
renames the requiresAliasScope flag to requiresAliasAnalysis since
the intrinsics also support tbaa and not only access scope metadata.

The revision still maintains the string based attribute lookup
in the translation from MLIR to LLVMIR. Using the interfaces
instead of the string based lookup is left to a followup revision.

Depends on D144851

Reviewed By: Dinistro

Differential Revision: https://reviews.llvm.org/D144965
  • Loading branch information
gysit committed Mar 2, 2023
1 parent 8ece85a commit b30422e
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 56 deletions.
4 changes: 2 additions & 2 deletions mlir/include/mlir/Dialect/ArmNeon/ArmNeon.td
Expand Up @@ -40,7 +40,7 @@ def ArmNeon_Dialect : Dialect {
class ArmNeon_IntrOp<string mnemonic, list<int> overloadedResults,
list<int> overloadedOperands, int numResults,
list<Trait> traits = [], bit requiresAccessGroup = 0,
bit requiresAliasScope = 0>
bit requiresAliasAnalysis = 0>
: LLVM_IntrOpBase</*dialect=*/ArmNeon_Dialect,
/*opName=*/"intr." # mnemonic,
/*enumName=*/"aarch64_neon_" # !subst(".", "_", mnemonic),
Expand All @@ -49,7 +49,7 @@ class ArmNeon_IntrOp<string mnemonic, list<int> overloadedResults,
/*traits=*/traits,
/*numResults=*/numResults,
/*requiresAccessGroup=*/requiresAccessGroup,
/*requiresAliasScope=*/requiresAliasScope>;
/*requiresAliasAnalysis=*/requiresAliasAnalysis>;

// ArmNeon dialect op that corresponds to an LLVM IR intrinsic with one
// overloaded result.
Expand Down
56 changes: 36 additions & 20 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
Expand Up @@ -4,7 +4,6 @@
include "mlir/IR/OpBase.td"
include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td"
include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td"
include "mlir/Interfaces/InferTypeOpInterface.td"

// Operations that correspond to LLVM intrinsics. With MLIR operation set being
Expand Down Expand Up @@ -130,25 +129,42 @@ def LLVM_SMinOp : LLVM_BinarySameArgsIntrOpI<"smin">;
def LLVM_UMaxOp : LLVM_BinarySameArgsIntrOpI<"umax">;
def LLVM_UMinOp : LLVM_BinarySameArgsIntrOpI<"umin">;

def LLVM_MemcpyOp : LLVM_ZeroResultIntrOp<"memcpy", [0, 1, 2]> {
let arguments = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
Arg<LLVM_AnyPointer,"",[MemRead]>:$src,
AnySignlessInteger:$len, I1:$isVolatile);
}
def LLVM_MemcpyInlineOp : LLVM_ZeroResultIntrOp<"memcpy.inline", [0, 1, 2]> {
let arguments = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
Arg<LLVM_AnyPointer,"",[MemRead]>:$src,
AnySignlessInteger:$len, I1:$isVolatile);
}
def LLVM_MemmoveOp : LLVM_ZeroResultIntrOp<"memmove", [0, 1, 2]> {
let arguments = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
Arg<LLVM_AnyPointer,"",[MemRead]>:$src,
AnySignlessInteger:$len, I1:$isVolatile);
}

def LLVM_MemsetOp : LLVM_ZeroResultIntrOp<"memset", [0, 2]> {
let arguments = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
I8:$val, AnySignlessInteger:$len, I1:$isVolatile);
class LLVM_MemcpyIntrOpBase<string name> :
LLVM_ZeroResultIntrOp<name, [0, 1, 2], [], /*requiresAccessGroup=*/1,
/*requiresAliasAnalysis=*/1> {
dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
Arg<LLVM_AnyPointer,"",[MemRead]>:$src,
AnySignlessInteger:$len, I1:$isVolatile);
// Append the alias attributes defined by LLVM_IntrOpBase.
let arguments = !con(args, aliasAttrs);
let builders = [
OpBuilder<(ins "Value":$dst, "Value":$src, "Value":$len,
"Value":$isVolatile), [{
build($_builder, $_state, dst, src, len, isVolatile,
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
}]
>];
}

def LLVM_MemcpyOp : LLVM_MemcpyIntrOpBase<"memcpy">;
def LLVM_MemcpyInlineOp : LLVM_MemcpyIntrOpBase<"memcpy.inline">;
def LLVM_MemmoveOp : LLVM_MemcpyIntrOpBase<"memmove">;

def LLVM_MemsetOp : LLVM_ZeroResultIntrOp<"memset", [0, 2], [],
/*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1> {
dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
I8:$val, AnySignlessInteger:$len, I1:$isVolatile);
// Append the alias attributes defined by LLVM_IntrOpBase.
let arguments = !con(args, aliasAttrs);
let builders = [
OpBuilder<(ins "Value":$dst, "Value":$val, "Value":$len,
"Value":$isVolatile), [{
build($_builder, $_state, dst, val, len, isVolatile,
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
}]
>];
}

//===----------------------------------------------------------------------===//
Expand Down
53 changes: 36 additions & 17 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
Expand Up @@ -426,18 +426,36 @@ 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.
// 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.
class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
list<int> overloadedResults, list<int> overloadedOperands,
list<Trait> traits, int numResults,
bit requiresAccessGroup = 0, bit requiresAliasScope = 0,
bit requiresAccessGroup = 0, bit requiresAliasAnalysis = 0,
bit requiresFastmath = 0>
: LLVM_OpBase<dialect, opName, !listconcat(
!if(!gt(requiresAccessGroup, 0),
[DeclareOpInterfaceMethods<AccessGroupOpInterface>], []),
!if(!gt(requiresAliasAnalysis, 0),
[DeclareOpInterfaceMethods<AliasAnalysisOpInterface>], []),
!if(!gt(requiresFastmath, 0),
[DeclareOpInterfaceMethods<FastmathFlagsInterface>],
[]),
[DeclareOpInterfaceMethods<FastmathFlagsInterface>], []),
traits)>,
LLVM_MemOpPatterns,
Results<!if(!gt(numResults, 0), (outs LLVM_Type:$res), (outs))> {
dag aliasAttrs = !con(
!if(!gt(requiresAccessGroup, 0),
(ins OptionalAttr<SymbolRefArrayAttr>:$access_groups),
(ins )),
!if(!gt(requiresAccessGroup, 0),
(ins OptionalAttr<SymbolRefArrayAttr>:$alias_scopes,
OptionalAttr<SymbolRefArrayAttr>:$noalias_scopes,
OptionalAttr<SymbolRefArrayAttr>:$tbaa),
(ins )));
string resultPattern = !if(!gt(numResults, 1),
LLVM_IntrPatterns.structResult,
LLVM_IntrPatterns.result);
Expand All @@ -453,14 +471,12 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
overloadedOperands>.lst), ", ") # [{
});
auto operands = moduleTranslation.lookupValues(opInst.getOperands());
}] # [{auto *inst = builder.CreateCall(fn, operands);
}] # !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;", "");
}] # [{
auto *inst = builder.CreateCall(fn, operands);
(void) inst;
}] # !if(!gt(requiresAccessGroup, 0), setAccessGroupsMetadataCode, "")
# !if(!gt(requiresAliasAnalysis, 0), setAliasAnalysisMetadataCode, "")
# !if(!gt(numResults, 0), "$res = inst;", "");

string mlirBuilder = [{
FailureOr<SmallVector<Value>> mlirOperands =
Expand All @@ -481,10 +497,10 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
class LLVM_IntrOp<string mnem, list<int> overloadedResults,
list<int> overloadedOperands, list<Trait> traits,
int numResults, bit requiresAccessGroup = 0,
bit requiresAliasScope = 0, bit requiresFastmath = 0>
bit requiresAliasAnalysis = 0, bit requiresFastmath = 0>
: LLVM_IntrOpBase<LLVM_Dialect, "intr." # mnem, !subst(".", "_", mnem),
overloadedResults, overloadedOperands, traits,
numResults, requiresAccessGroup, requiresAliasScope,
numResults, requiresAccessGroup, requiresAliasAnalysis,
requiresFastmath>;

// Base class for LLVM intrinsic operations returning no results. Places the
Expand All @@ -502,8 +518,11 @@ class LLVM_IntrOp<string mnem, list<int> overloadedResults,
// one (as indicated by `[0]`) is necessary to resolve the overloaded intrinsic.
// The Op has no results.
class LLVM_ZeroResultIntrOp<string mnem, list<int> overloadedOperands = [],
list<Trait> traits = []>
: LLVM_IntrOp<mnem, [], overloadedOperands, traits, 0>;
list<Trait> traits = [],
bit requiresAccessGroup = 0,
bit requiresAliasAnalysis = 0>
: LLVM_IntrOp<mnem, [], overloadedOperands, traits, /*numResults=*/0,
requiresAccessGroup, requiresAliasAnalysis>;

// Base class for LLVM intrinsic operations returning one result. Places the
// intrinsic into the LLVM dialect and prefixes its name with "intr.". This is
Expand All @@ -516,7 +535,7 @@ class LLVM_OneResultIntrOp<string mnem, list<int> overloadedResults = [],
list<Trait> traits = [],
bit requiresFastmath = 0>
: LLVM_IntrOp<mnem, overloadedResults, overloadedOperands, traits, 1,
/*requiresAccessGroup=*/0, /*requiresAliasScope=*/0,
/*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
requiresFastmath>;

def LLVM_OneResultOpBuilder :
Expand Down
7 changes: 7 additions & 0 deletions mlir/test/Target/LLVMIR/Import/metadata-alias-scopes.ll
Expand Up @@ -72,9 +72,16 @@ define void @supported_ops(ptr %arg1, float %arg2, i32 %arg3, i32 %arg4) {
%2 = atomicrmw fmax ptr %arg1, float %arg2 acquire, !alias.scope !3
; CHECK: llvm.cmpxchg {{.*}}alias_scopes =
%3 = cmpxchg ptr %arg1, i32 %arg3, i32 %arg4 monotonic seq_cst, !alias.scope !3
; CHECK: "llvm.intr.memcpy"{{.*}}alias_scopes =
call void @llvm.memcpy.p0.p0.i32(ptr %arg1, ptr %arg1, i32 4, i1 false), !alias.scope !3
; CHECK: "llvm.intr.memset"{{.*}}alias_scopes =
call void @llvm.memset.p0.i32(ptr %arg1, i8 42, i32 4, i1 false), !alias.scope !3
ret void
}

declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg)
declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg)

!0 = distinct !{!0, !"The domain"}
!1 = distinct !{!1}
!2 = !{!2, !0}
Expand Down
7 changes: 7 additions & 0 deletions mlir/test/Target/LLVMIR/Import/metadata-loop.ll
Expand Up @@ -37,9 +37,16 @@ define void @supported_ops(ptr %arg1, float %arg2, i32 %arg3, i32 %arg4) {
%2 = atomicrmw fmax ptr %arg1, float %arg2 acquire, !llvm.access.group !0
; CHECK: llvm.cmpxchg {{.*}}access_groups =
%3 = cmpxchg ptr %arg1, i32 %arg3, i32 %arg4 monotonic seq_cst, !llvm.access.group !0
; CHECK: "llvm.intr.memcpy"{{.*}}access_groups =
call void @llvm.memcpy.p0.p0.i32(ptr %arg1, ptr %arg1, i32 4, i1 false), !llvm.access.group !0
; CHECK: "llvm.intr.memset"{{.*}}access_groups =
call void @llvm.memset.p0.i32(ptr %arg1, i8 42, i32 4, i1 false), !llvm.access.group !0
ret void
}

declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg)
declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg)

!0 = !{!1, !2}
!1 = distinct !{}
!2 = distinct !{}
Expand Down
7 changes: 7 additions & 0 deletions mlir/test/Target/LLVMIR/Import/metadata-tbaa.ll
Expand Up @@ -81,9 +81,16 @@ define void @supported_ops(ptr %arg1, float %arg2, i32 %arg3, i32 %arg4) {
%2 = atomicrmw fmax ptr %arg1, float %arg2 acquire, !tbaa !0
; CHECK: llvm.cmpxchg {{.*}}tbaa =
%3 = cmpxchg ptr %arg1, i32 %arg3, i32 %arg4 monotonic seq_cst, !tbaa !0
; CHECK: "llvm.intr.memcpy"{{.*}}tbaa =
call void @llvm.memcpy.p0.p0.i32(ptr %arg1, ptr %arg1, i32 4, i1 false), !tbaa !0
; CHECK: "llvm.intr.memset"{{.*}}tbaa =
call void @llvm.memset.p0.i32(ptr %arg1, i8 42, i32 4, i1 false), !tbaa !0
ret void
}

declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg)
declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg)

!0 = !{!1, !1, i64 0}
!1 = !{!"scalar type", !2, i64 0}
!2 = !{!"Simple C/C++ TBAA"}
6 changes: 6 additions & 0 deletions mlir/test/Target/LLVMIR/llvmir.mlir
Expand Up @@ -1981,6 +1981,10 @@ module {
%1 = llvm.load %arg1 {alias_scopes = [@metadata::@scope2], noalias_scopes = [@metadata::@scope1, @metadata::@scope3]} : !llvm.ptr -> i32
%2 = llvm.atomicrmw add %arg1, %0 monotonic {alias_scopes = [@metadata::@scope3], noalias_scopes = [@metadata::@scope1, @metadata::@scope2]} : !llvm.ptr, i32
%3 = llvm.cmpxchg %arg1, %1, %2 acq_rel monotonic {alias_scopes = [@metadata::@scope3]} : !llvm.ptr, i32
%4 = llvm.mlir.constant(0 : i1) : i1
%5 = llvm.mlir.constant(42 : i8) : i8
"llvm.intr.memcpy"(%arg1, %arg1, %0, %4) {alias_scopes = [@metadata::@scope3]} : (!llvm.ptr, !llvm.ptr, i32, i1) -> ()
"llvm.intr.memset"(%arg1, %5, %0, %4) {noalias_scopes = [@metadata::@scope3]} : (!llvm.ptr, i8, i32, i1) -> ()
llvm.return
}

Expand All @@ -1998,6 +2002,8 @@ module {
// CHECK: load {{.*}}, !alias.scope ![[SCOPES2:[0-9]+]], !noalias ![[SCOPES13:[0-9]+]]
// CHECK: atomicrmw {{.*}}, !alias.scope ![[SCOPES3:[0-9]+]], !noalias ![[SCOPES12:[0-9]+]]
// CHECK: cmpxchg {{.*}}, !alias.scope ![[SCOPES3]]
// CHECK: llvm.memcpy{{.*}}, !alias.scope ![[SCOPES3]]
// CHECK: llvm.memset{{.*}}, !noalias ![[SCOPES3]]

// Metadata
// CHECK-DAG: ![[DOMAIN:[0-9]+]] = distinct !{![[DOMAIN]], !"The domain"}
Expand Down
6 changes: 6 additions & 0 deletions mlir/test/Target/LLVMIR/loop-metadata.mlir
Expand Up @@ -256,6 +256,12 @@ llvm.func @loopOptions(%arg1 : i32, %arg2 : i32) {
%6 = llvm.atomicrmw add %4, %5 monotonic {access_groups = [@metadata::@group1, @metadata::@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
%8 = llvm.mlir.constant(0 : i1) : i1
%9 = llvm.mlir.constant(42 : i8) : i8
// CHECK: llvm.memcpy{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]]
"llvm.intr.memcpy"(%4, %4, %0, %8) {access_groups = [@metadata::@group1, @metadata::@group2]} : (!llvm.ptr, !llvm.ptr, i32, i1) -> ()
// CHECK: llvm.memset{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]]
"llvm.intr.memset"(%4, %9, %0, %8) {access_groups = [@metadata::@group1, @metadata::@group2]} : (!llvm.ptr, i8, i32, i1) -> ()
// CHECK: br label {{.*}} !llvm.loop ![[LOOP_NODE]]
llvm.br ^bb3(%3 : i32) {loop_annotation = #llvm.loop_annotation<
licm = <disable = true>,
Expand Down
6 changes: 6 additions & 0 deletions mlir/test/Target/LLVMIR/tbaa.mlir
Expand Up @@ -69,6 +69,12 @@ module {
%6 = llvm.atomicrmw add %5, %4 monotonic {tbaa = [@__tbaa::@tbaa_tag_7]} : !llvm.ptr, i32
// CHECK: cmpxchg ptr %{{.*}}, i32 %{{.*}}, i32 %{{.*}} !tbaa ![[STAG]]
%7 = llvm.cmpxchg %5, %6, %4 acq_rel monotonic {tbaa = [@__tbaa::@tbaa_tag_7]} : !llvm.ptr, i32
%8 = llvm.mlir.constant(0 : i1) : i1
%9 = llvm.mlir.constant(42 : i8) : i8
// CHECK: llvm.memcpy{{.*}} !tbaa ![[STAG]]
"llvm.intr.memcpy"(%arg1, %arg1, %0, %8) {tbaa = [@__tbaa::@tbaa_tag_7]} : (!llvm.ptr, !llvm.ptr, i32, i1) -> ()
// CHECK: llvm.memset{{.*}} !tbaa ![[STAG]]
"llvm.intr.memset"(%arg1, %9, %0, %8) {tbaa = [@__tbaa::@tbaa_tag_7]} : (!llvm.ptr, i8, i32, i1) -> ()
llvm.return
}
}
Expand Down
19 changes: 10 additions & 9 deletions mlir/test/mlir-tblgen/llvm-intrinsics.td
Expand Up @@ -24,9 +24,9 @@
// CHECK: [NoMemoryEffect]
// It has a result.
// CHECK: 1,
// It does not require an access group.
// It does not implement the access group interface.
// CHECK: 0,
// It does not require alias scopes.
// It does not implement the alias analysis interface.
// CHECK: 0>
// CHECK: Arguments<(ins LLVM_Type, LLVM_Type

Expand All @@ -45,20 +45,20 @@
// GROUPS: [NoMemoryEffect]
// It has a result.
// GROUPS: 1,
// It requires generation of an access group LLVM metadata.
// It implements the access group interface.
// GROUPS: 1,
// It does not require alias scopes.
// It does not implement the alias analysis interface.
// GROUPS: 0>
// It has an access group attribute.
// GROUPS: OptionalAttr<SymbolRefArrayAttr>:$access_groups

//---------------------------------------------------------------------------//

// This checks that we can define an op that takes in alias scopes metadata.
// This checks that we can define an op that takes in alias analysis 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: | mlir-tblgen -gen-llvmir-intrinsics -I %S/../../../llvm/include/ --llvmir-intrinsics-filter=ptrmask --llvmir-intrinsics-alias-analysis-regexp=ptrmask \
// RUN: | FileCheck --check-prefix=ALIAS %s

// ALIAS-LABEL: def LLVM_ptrmask
Expand All @@ -67,13 +67,14 @@
// ALIAS: [NoMemoryEffect]
// It has a result.
// ALIAS: 1,
// It does not require an access group.
// It does not implement the access group interface.
// ALIAS: 0,
// It requires generation of alias scopes LLVM metadata.
// It implements the alias analysis interface.
// ALIAS: 1>
// It has alias scopes and noalias.
// It has alias scopes, noalias, and tbaa.
// ALIAS: OptionalAttr<SymbolRefArrayAttr>:$alias_scopes
// ALIAS: OptionalAttr<SymbolRefArrayAttr>:$noalias_scopes
// ALIAS: OptionalAttr<SymbolRefArrayAttr>:$tbaa

//---------------------------------------------------------------------------//

Expand Down
17 changes: 9 additions & 8 deletions mlir/tools/mlir-tblgen/LLVMIRIntrinsicGen.cpp
Expand Up @@ -44,10 +44,10 @@ static llvm::cl::opt<std::string> accessGroupRegexp(
"regexp as taking an access group metadata"),
llvm::cl::cat(intrinsicGenCat));

static llvm::cl::opt<std::string> aliasScopesRegexp(
"llvmir-intrinsics-alias-scopes-regexp",
static llvm::cl::opt<std::string> aliasAnalysisRegexp(
"llvmir-intrinsics-alias-analysis-regexp",
llvm::cl::desc("Mark intrinsics that match the specified "
"regexp as taking alias.scopes and noalias metadata"),
"regexp as taking alias.scopes, noalias, and tbaa metadata"),
llvm::cl::cat(intrinsicGenCat));

// Used to represent the indices of overloadable operands/results.
Expand Down Expand Up @@ -202,9 +202,9 @@ static bool emitIntrinsic(const llvm::Record &record, llvm::raw_ostream &os) {
bool requiresAccessGroup =
!accessGroupRegexp.empty() && accessGroupMatcher.match(record.getName());

llvm::Regex aliasScopesMatcher(aliasScopesRegexp);
bool requiresAliasScopes =
!aliasScopesRegexp.empty() && aliasScopesMatcher.match(record.getName());
llvm::Regex aliasAnalysisMatcher(aliasAnalysisRegexp);
bool requiresAliasAnalysis = !aliasAnalysisRegexp.empty() &&
aliasAnalysisMatcher.match(record.getName());

// Prepare strings for traits, if any.
llvm::SmallVector<llvm::StringRef, 2> traits;
Expand All @@ -218,9 +218,10 @@ static bool emitIntrinsic(const llvm::Record &record, llvm::raw_ostream &os) {
"LLVM_Type");
if (requiresAccessGroup)
operands.push_back("OptionalAttr<SymbolRefArrayAttr>:$access_groups");
if (requiresAliasScopes) {
if (requiresAliasAnalysis) {
operands.push_back("OptionalAttr<SymbolRefArrayAttr>:$alias_scopes");
operands.push_back("OptionalAttr<SymbolRefArrayAttr>:$noalias_scopes");
operands.push_back("OptionalAttr<SymbolRefArrayAttr>:$tbaa");
}

// Emit the definition.
Expand All @@ -233,7 +234,7 @@ static bool emitIntrinsic(const llvm::Record &record, llvm::raw_ostream &os) {
printBracketedRange(traits, os);
os << ", " << intr.getNumResults() << ", "
<< (requiresAccessGroup ? "1" : "0") << ", "
<< (requiresAliasScopes ? "1" : "0") << ">, Arguments<(ins"
<< (requiresAliasAnalysis ? "1" : "0") << ">, Arguments<(ins"
<< (operands.empty() ? "" : " ");
llvm::interleaveComma(operands, os);
os << ")>;\n\n";
Expand Down

0 comments on commit b30422e

Please sign in to comment.