[Mlir-commits] [mlir] [mlir][LLVMIR] Add operand bundle support for llvm.intr.assume (PR #112143)
Sirui Mu
llvmlistbot at llvm.org
Sun Oct 13 08:34:00 PDT 2024
https://github.com/Lancern created https://github.com/llvm/llvm-project/pull/112143
This PR adds operand bundle support for `llvm.intr.assume`.
This PR actually contains two parts:
- `llvm.intr.assume` now accepts operand bundle related attributes and operands. `llvm.intr.assume` does not take constraint on the operand bundles, but obviously only a few set of operand bundles are meaningful. I plan to add some of those (e.g. `aligned` and `separate_storage` are what interest me but other people may be interested in other operand bundles as well) in future patches.
- The definitions of `llvm.call`, `llvm.invoke`, and `llvm.call_intrinsic` actually define `op_bundle_tags` as an operation property. It turns out this approach would introduce some unnecessary burden if applied equally to the intrinsic operations, so this PR changes it from a property to an array attribute.
>From 6e2a807f4d5a757fdb96bd0f0531ba56d89b3c7e Mon Sep 17 00:00:00 2001
From: Sirui Mu <msrlancern at gmail.com>
Date: Sun, 13 Oct 2024 23:03:50 +0800
Subject: [PATCH] [mlir][LLVMIR] Add operand bundle support for
llvm.intr.assume
---
.../mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td | 30 +++++-
.../include/mlir/Dialect/LLVMIR/LLVMOpBase.td | 26 +++--
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 18 +---
.../include/mlir/Target/LLVMIR/ModuleImport.h | 3 +
.../mlir/Target/LLVMIR/ModuleTranslation.h | 4 +-
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 97 ++++++++++++-------
.../LLVMIR/LLVMIRToLLVMTranslation.cpp | 6 ++
.../LLVMIR/LLVMToLLVMIRTranslation.cpp | 16 ++-
.../Dialect/NVVM/LLVMIRToNVVMTranslation.cpp | 6 ++
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 37 ++++++-
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 41 +++++++-
.../expand-then-convert-to-llvm.mlir | 2 +-
.../MemRefToLLVM/memref-to-llvm.mlir | 4 +-
mlir/test/Dialect/LLVMIR/inlining.mlir | 4 +-
mlir/test/Dialect/LLVMIR/roundtrip.mlir | 27 ++++++
mlir/test/Target/LLVMIR/Import/intrinsic.ll | 2 +-
mlir/test/Target/LLVMIR/llvmir-invalid.mlir | 2 +-
17 files changed, 250 insertions(+), 75 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index 448a171cf3e412..c56065af07b10e 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -365,8 +365,8 @@ class LLVM_ConstrainedIntr<string mnem, int numArgs,
SmallVector<Value> mlirOperands;
SmallVector<NamedAttribute> mlirAttrs;
if (failed(moduleImport.convertIntrinsicArguments(
- llvmOperands.take_front( }] # numArgs # [{),
- {}, {}, mlirOperands, mlirAttrs))) {
+ llvmOperands.take_front( }] # numArgs # [{), {}, {}, {},
+ StringLiteral(""), StringLiteral(""), mlirOperands, mlirAttrs))) {
return failure();
}
@@ -426,7 +426,31 @@ def LLVM_USHLSat : LLVM_BinarySameArgsIntrOpI<"ushl.sat">;
//
def LLVM_AssumeOp
- : LLVM_ZeroResultIntrOp<"assume", []>, Arguments<(ins I1:$cond)>;
+ : LLVM_ZeroResultIntrOp<"assume", /*overloadedOperands=*/[], /*traits=*/[],
+ /*requiresAccessGroup=*/0,
+ /*requiresAliasAnalysis=*/0,
+ /*immArgPositions=*/[], /*immArgAttrNames=*/[],
+ /*opBundleSizesAttrName=*/"op_bundle_sizes",
+ /*opBundleTagsAttrName=*/"op_bundle_tags"> {
+ let arguments = (ins I1:$cond,
+ VariadicOfVariadic<LLVM_Type,
+ "op_bundle_sizes">:$op_bundle_operands,
+ DenseI32ArrayAttr:$op_bundle_sizes,
+ OptionalAttr<ArrayAttr>:$op_bundle_tags);
+
+ let assemblyFormat = [{
+ $cond
+ ( custom<OpBundles>($op_bundle_operands, type($op_bundle_operands),
+ $op_bundle_tags)^ )?
+ `:` `(` type($cond) `)` `->` `(` `)` attr-dict
+ }];
+
+ let builders = [
+ OpBuilder<(ins "Value":$cond)>
+ ];
+
+ let hasVerifier = 1;
+}
def LLVM_SSACopyOp : LLVM_OneResultIntrOp<"ssa.copy", [], [0],
[Pure, SameOperandsAndResultType]> {
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
index c3d352d8d0dd48..dc59baed67472a 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
@@ -293,7 +293,9 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
bit requiresAccessGroup = 0, bit requiresAliasAnalysis = 0,
bit requiresFastmath = 0,
list<int> immArgPositions = [],
- list<string> immArgAttrNames = []>
+ list<string> immArgAttrNames = [],
+ string opBundleSizesAttrName = "",
+ string opBundleTagsAttrName = "">
: LLVM_OpBase<dialect, opName, !listconcat(
!if(!gt(requiresAccessGroup, 0),
[DeclareOpInterfaceMethods<AccessGroupOpInterface>], []),
@@ -319,11 +321,14 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
string immArgPositionsCpp = "{" # !interleave(immArgPositions, ", ") # "}";
string immArgAttrNamesCpp = "{" # !interleave(!foreach(name, immArgAttrNames,
"StringLiteral(\"" # name # "\")"), ", ") # "}";
+ string opBundleSizesAttrNameCpp = "StringLiteral(\"" # opBundleSizesAttrName # "\")";
+ string opBundleTagsAttrNameCpp = "StringLiteral(\"" # opBundleTagsAttrName # "\")";
string baseLlvmBuilder = [{
auto *inst = LLVM::detail::createIntrinsicCall(
builder, moduleTranslation, &opInst, llvm::Intrinsic::}] # !interleave([
enumName, "" # numResults, overloadedResultsCpp, overloadedOperandsCpp,
- immArgPositionsCpp, immArgAttrNamesCpp], ",") # [{);
+ immArgPositionsCpp, immArgAttrNamesCpp, opBundleSizesAttrNameCpp], ",")
+ # ", " # opBundleTagsAttrNameCpp # [{);
(void) inst;
}];
string baseLlvmBuilderCoda = !if(!gt(numResults, 0), "$res = inst;", "");
@@ -336,8 +341,11 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
SmallVector<NamedAttribute> mlirAttrs;
if (failed(moduleImport.convertIntrinsicArguments(
llvmOperands,
+ opBundles,
}] # immArgPositionsCpp # [{,
}] # immArgAttrNamesCpp # [{,
+ }] # opBundleSizesAttrNameCpp # [{,
+ }] # opBundleTagsAttrNameCpp # [{,
mlirOperands,
mlirAttrs))
) {
@@ -382,11 +390,14 @@ class LLVM_IntrOp<string mnem, list<int> overloadedResults,
int numResults, bit requiresAccessGroup = 0,
bit requiresAliasAnalysis = 0, bit requiresFastmath = 0,
list<int> immArgPositions = [],
- list<string> immArgAttrNames = []>
+ list<string> immArgAttrNames = [],
+ string opBundleSizesAttrName = "",
+ string opBundleTagsAttrName = "">
: LLVM_IntrOpBase<LLVM_Dialect, "intr." # mnem, !subst(".", "_", mnem),
overloadedResults, overloadedOperands, traits,
numResults, requiresAccessGroup, requiresAliasAnalysis,
- requiresFastmath, immArgPositions, immArgAttrNames>;
+ requiresFastmath, immArgPositions, immArgAttrNames,
+ opBundleSizesAttrName, opBundleTagsAttrName>;
// Base class for LLVM intrinsic operations returning no results. Places the
// intrinsic into the LLVM dialect and prefixes its name with "intr.".
@@ -407,10 +418,13 @@ class LLVM_ZeroResultIntrOp<string mnem, list<int> overloadedOperands = [],
bit requiresAccessGroup = 0,
bit requiresAliasAnalysis = 0,
list<int> immArgPositions = [],
- list<string> immArgAttrNames = []>
+ list<string> immArgAttrNames = [],
+ string opBundleSizesAttrName = "",
+ string opBundleTagsAttrName = "">
: LLVM_IntrOp<mnem, [], overloadedOperands, traits, /*numResults=*/0,
requiresAccessGroup, requiresAliasAnalysis,
- /*requiresFastMath=*/0, immArgPositions, immArgAttrNames>;
+ /*requiresFastMath=*/0, immArgPositions, immArgAttrNames,
+ opBundleSizesAttrName, opBundleTagsAttrName>;
// Base class for LLVM intrinsic operations returning one result. Places the
// intrinsic into the LLVM dialect and prefixes its name with "intr.". This is
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 000d92f9ea3bcb..d388de3960f2b2 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -559,11 +559,7 @@ def LLVM_InvokeOp : LLVM_Op<"invoke", [
VariadicOfVariadic<LLVM_Type,
"op_bundle_sizes">:$op_bundle_operands,
DenseI32ArrayAttr:$op_bundle_sizes,
- DefaultValuedProperty<
- ArrayProperty<StringProperty, "operand bundle tags">,
- "ArrayRef<std::string>{}",
- "SmallVector<std::string>{}"
- >:$op_bundle_tags);
+ OptionalAttr<ArrayAttr>:$op_bundle_tags);
let results = (outs Optional<LLVM_Type>:$result);
let successors = (successor AnySuccessor:$normalDest,
AnySuccessor:$unwindDest);
@@ -678,11 +674,7 @@ def LLVM_CallOp : LLVM_MemAccessOpBase<"call",
VariadicOfVariadic<LLVM_Type,
"op_bundle_sizes">:$op_bundle_operands,
DenseI32ArrayAttr:$op_bundle_sizes,
- DefaultValuedProperty<
- ArrayProperty<StringProperty, "operand bundle tags">,
- "ArrayRef<std::string>{}",
- "SmallVector<std::string>{}"
- >:$op_bundle_tags);
+ OptionalAttr<ArrayAttr>:$op_bundle_tags);
// Append the aliasing related attributes defined in LLVM_MemAccessOpBase.
let arguments = !con(args, aliasAttrs);
let results = (outs Optional<LLVM_Type>:$result);
@@ -1930,11 +1922,7 @@ def LLVM_CallIntrinsicOp
VariadicOfVariadic<LLVM_Type,
"op_bundle_sizes">:$op_bundle_operands,
DenseI32ArrayAttr:$op_bundle_sizes,
- DefaultValuedProperty<
- ArrayProperty<StringProperty, "operand bundle tags">,
- "ArrayRef<std::string>{}",
- "SmallVector<std::string>{}"
- >:$op_bundle_tags);
+ OptionalAttr<ArrayAttr>:$op_bundle_tags);
let results = (outs Optional<LLVM_Type>:$results);
let llvmBuilder = [{
return convertCallLLVMIntrinsicOp(op, builder, moduleTranslation);
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
index 436675793062eb..a2cf065bb9eb76 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
@@ -239,8 +239,11 @@ class ModuleImport {
/// corresponding MLIR attribute names.
LogicalResult
convertIntrinsicArguments(ArrayRef<llvm::Value *> values,
+ ArrayRef<llvm::OperandBundleUse> opBundles,
ArrayRef<unsigned> immArgPositions,
ArrayRef<StringLiteral> immArgAttrNames,
+ StringLiteral opBundleSizesAttrName,
+ StringLiteral opBundleTagsAttrName,
SmallVectorImpl<Value> &valuesOut,
SmallVectorImpl<NamedAttribute> &attrsOut);
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
index 3c85338bc642f6..4a8503ceb4cd9c 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
@@ -431,8 +431,8 @@ llvm::CallInst *createIntrinsicCall(
llvm::IRBuilderBase &builder, ModuleTranslation &moduleTranslation,
Operation *intrOp, llvm::Intrinsic::ID intrinsic, unsigned numResults,
ArrayRef<unsigned> overloadedResults, ArrayRef<unsigned> overloadedOperands,
- ArrayRef<unsigned> immArgPositions,
- ArrayRef<StringLiteral> immArgAttrNames);
+ ArrayRef<unsigned> immArgPositions, ArrayRef<StringLiteral> immArgAttrNames,
+ StringLiteral opBundleSizesAttrName, StringLiteral opBundleTagsAttrName);
} // namespace detail
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 006d412936a337..967aafd1dbc86e 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -241,13 +241,18 @@ static void printOneOpBundle(OpAsmPrinter &p, OperandRange operands,
static void printOpBundles(OpAsmPrinter &p, Operation *op,
OperandRangeRange opBundleOperands,
TypeRangeRange opBundleOperandTypes,
- ArrayRef<std::string> opBundleTags) {
+ std::optional<ArrayAttr> opBundleTags) {
+ if (opBundleOperands.empty())
+ return;
+ assert(opBundleTags && "expect operand bundle tags");
+
p << "[";
llvm::interleaveComma(
- llvm::zip(opBundleOperands, opBundleOperandTypes, opBundleTags), p,
+ llvm::zip(opBundleOperands, opBundleOperandTypes, *opBundleTags), p,
[&p](auto bundle) {
+ auto bundleTag = llvm::cast<StringAttr>(std::get<2>(bundle)).getValue();
printOneOpBundle(p, std::get<0>(bundle), std::get<1>(bundle),
- std::get<2>(bundle));
+ bundleTag);
});
p << "]";
}
@@ -256,7 +261,7 @@ static ParseResult parseOneOpBundle(
OpAsmParser &p,
SmallVector<SmallVector<OpAsmParser::UnresolvedOperand>> &opBundleOperands,
SmallVector<SmallVector<Type>> &opBundleOperandTypes,
- SmallVector<std::string> &opBundleTags) {
+ SmallVector<Attribute> &opBundleTags) {
SMLoc currentParserLoc = p.getCurrentLocation();
SmallVector<OpAsmParser::UnresolvedOperand> operands;
SmallVector<Type> types;
@@ -276,7 +281,7 @@ static ParseResult parseOneOpBundle(
opBundleOperands.push_back(std::move(operands));
opBundleOperandTypes.push_back(std::move(types));
- opBundleTags.push_back(std::move(tag));
+ opBundleTags.push_back(StringAttr::get(p.getContext(), tag));
return success();
}
@@ -285,16 +290,17 @@ static std::optional<ParseResult> parseOpBundles(
OpAsmParser &p,
SmallVector<SmallVector<OpAsmParser::UnresolvedOperand>> &opBundleOperands,
SmallVector<SmallVector<Type>> &opBundleOperandTypes,
- SmallVector<std::string> &opBundleTags) {
+ ArrayAttr &opBundleTags) {
if (p.parseOptionalLSquare())
return std::nullopt;
if (succeeded(p.parseOptionalRSquare()))
return success();
+ SmallVector<Attribute> opBundleTagAttrs;
auto bundleParser = [&] {
return parseOneOpBundle(p, opBundleOperands, opBundleOperandTypes,
- opBundleTags);
+ opBundleTagAttrs);
};
if (p.parseCommaSeparatedList(bundleParser))
return failure();
@@ -302,6 +308,8 @@ static std::optional<ParseResult> parseOpBundles(
if (p.parseRSquare())
return failure();
+ opBundleTags = ArrayAttr::get(p.getContext(), opBundleTagAttrs);
+
return success();
}
@@ -1039,7 +1047,7 @@ void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
/*CConv=*/nullptr, /*TailCallKind=*/nullptr,
/*memory_effects=*/nullptr,
/*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr,
- /*op_bundle_operands=*/{}, /*op_bundle_tags=*/std::nullopt,
+ /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{},
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
}
@@ -1066,7 +1074,7 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
/*TailCallKind=*/nullptr, /*memory_effects=*/nullptr,
/*convergent=*/nullptr,
/*no_unwind=*/nullptr, /*will_return=*/nullptr,
- /*op_bundle_operands=*/{}, /*op_bundle_tags=*/std::nullopt,
+ /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{},
/*access_groups=*/nullptr,
/*alias_scopes=*/nullptr, /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
}
@@ -1079,7 +1087,7 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
/*fastmathFlags=*/nullptr, /*branch_weights=*/nullptr,
/*CConv=*/nullptr, /*TailCallKind=*/nullptr, /*memory_effects=*/nullptr,
/*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr,
- /*op_bundle_operands=*/{}, /*op_bundle_tags=*/std::nullopt,
+ /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{},
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
}
@@ -1092,7 +1100,7 @@ void CallOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
/*fastmathFlags=*/nullptr, /*branch_weights=*/nullptr,
/*CConv=*/nullptr, /*TailCallKind=*/nullptr, /*memory_effects=*/nullptr,
/*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr,
- /*op_bundle_operands=*/{}, /*op_bundle_tags=*/std::nullopt,
+ /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{},
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
}
@@ -1192,12 +1200,21 @@ LogicalResult verifyCallOpVarCalleeType(OpTy callOp) {
template <typename OpType>
static LogicalResult verifyOperandBundles(OpType &op) {
OperandRangeRange opBundleOperands = op.getOpBundleOperands();
- ArrayRef<std::string> opBundleTags = op.getOpBundleTags();
+ std::optional<ArrayAttr> opBundleTags = op.getOpBundleTags();
- if (opBundleTags.size() != opBundleOperands.size())
+ if (opBundleTags) {
+ for (Attribute tagAttr : *opBundleTags) {
+ if (!llvm::isa<StringAttr>(tagAttr))
+ return op.emitError("operand bundle tag must be a StringAttr");
+ }
+ }
+
+ size_t numOpBundles = opBundleOperands.size();
+ size_t numOpBundleTags = opBundleTags ? opBundleTags->size() : 0;
+ if (numOpBundles != numOpBundleTags)
return op.emitError("expected ")
- << opBundleOperands.size()
- << " operand bundle tags, but actually got " << opBundleTags.size();
+ << numOpBundles << " operand bundle tags, but actually got "
+ << numOpBundleTags;
return success();
}
@@ -1329,7 +1346,8 @@ void CallOp::print(OpAsmPrinter &p) {
{getCalleeAttrName(), getTailCallKindAttrName(),
getVarCalleeTypeAttrName(), getCConvAttrName(),
getOperandSegmentSizesAttrName(),
- getOpBundleSizesAttrName()});
+ getOpBundleSizesAttrName(),
+ getOpBundleTagsAttrName()});
p << " : ";
if (!isDirect)
@@ -1437,7 +1455,7 @@ ParseResult CallOp::parse(OpAsmParser &parser, OperationState &result) {
SmallVector<OpAsmParser::UnresolvedOperand> operands;
SmallVector<SmallVector<OpAsmParser::UnresolvedOperand>> opBundleOperands;
SmallVector<SmallVector<Type>> opBundleOperandTypes;
- SmallVector<std::string> opBundleTags;
+ ArrayAttr opBundleTags;
// Default to C Calling Convention if no keyword is provided.
result.addAttribute(
@@ -1483,9 +1501,9 @@ ParseResult CallOp::parse(OpAsmParser &parser, OperationState &result) {
parser, opBundleOperands, opBundleOperandTypes, opBundleTags);
result && failed(*result))
return failure();
- if (!opBundleTags.empty())
- result.getOrAddProperties<CallOp::Properties>().op_bundle_tags =
- std::move(opBundleTags);
+ if (opBundleTags && !opBundleTags.empty())
+ result.addAttribute(CallOp::getOpBundleTagsAttrName(result.name).getValue(),
+ opBundleTags);
if (parser.parseOptionalAttrDict(result.attributes))
return failure();
@@ -1525,8 +1543,7 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
auto calleeType = func.getFunctionType();
build(builder, state, getCallOpResultTypes(calleeType),
getCallOpVarCalleeType(calleeType), SymbolRefAttr::get(func), ops,
- normalOps, unwindOps, nullptr, nullptr, {}, std::nullopt, normal,
- unwind);
+ normalOps, unwindOps, nullptr, nullptr, {}, {}, normal, unwind);
}
void InvokeOp::build(OpBuilder &builder, OperationState &state, TypeRange tys,
@@ -1535,7 +1552,7 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state, TypeRange tys,
ValueRange unwindOps) {
build(builder, state, tys,
/*var_callee_type=*/nullptr, callee, ops, normalOps, unwindOps, nullptr,
- nullptr, {}, std::nullopt, normal, unwind);
+ nullptr, {}, {}, normal, unwind);
}
void InvokeOp::build(OpBuilder &builder, OperationState &state,
@@ -1544,7 +1561,7 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state,
Block *unwind, ValueRange unwindOps) {
build(builder, state, getCallOpResultTypes(calleeType),
getCallOpVarCalleeType(calleeType), callee, ops, normalOps, unwindOps,
- nullptr, nullptr, {}, std::nullopt, normal, unwind);
+ nullptr, nullptr, {}, {}, normal, unwind);
}
SuccessorOperands InvokeOp::getSuccessorOperands(unsigned index) {
@@ -1634,7 +1651,8 @@ void InvokeOp::print(OpAsmPrinter &p) {
p.printOptionalAttrDict((*this)->getAttrs(),
{getCalleeAttrName(), getOperandSegmentSizeAttr(),
getCConvAttrName(), getVarCalleeTypeAttrName(),
- getOpBundleSizesAttrName()});
+ getOpBundleSizesAttrName(),
+ getOpBundleTagsAttrName()});
p << " : ";
if (!isDirect)
@@ -1657,7 +1675,7 @@ ParseResult InvokeOp::parse(OpAsmParser &parser, OperationState &result) {
TypeAttr varCalleeType;
SmallVector<SmallVector<OpAsmParser::UnresolvedOperand>> opBundleOperands;
SmallVector<SmallVector<Type>> opBundleOperandTypes;
- SmallVector<std::string> opBundleTags;
+ ArrayAttr opBundleTags;
Block *normalDest, *unwindDest;
SmallVector<Value, 4> normalOperands, unwindOperands;
Builder &builder = parser.getBuilder();
@@ -1703,9 +1721,10 @@ ParseResult InvokeOp::parse(OpAsmParser &parser, OperationState &result) {
parser, opBundleOperands, opBundleOperandTypes, opBundleTags);
result && failed(*result))
return failure();
- if (!opBundleTags.empty())
- result.getOrAddProperties<InvokeOp::Properties>().op_bundle_tags =
- std::move(opBundleTags);
+ if (opBundleTags && !opBundleTags.empty())
+ result.addAttribute(
+ InvokeOp::getOpBundleTagsAttrName(result.name).getValue(),
+ opBundleTags);
if (parser.parseOptionalAttrDict(result.attributes))
return failure();
@@ -3332,7 +3351,7 @@ void CallIntrinsicOp::build(OpBuilder &builder, OperationState &state,
mlir::StringAttr intrin, mlir::ValueRange args) {
build(builder, state, /*resultTypes=*/TypeRange{}, intrin, args,
FastmathFlagsAttr{},
- /*op_bundle_operands=*/{});
+ /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{});
}
void CallIntrinsicOp::build(OpBuilder &builder, OperationState &state,
@@ -3340,14 +3359,14 @@ void CallIntrinsicOp::build(OpBuilder &builder, OperationState &state,
mlir::LLVM::FastmathFlagsAttr fastMathFlags) {
build(builder, state, /*resultTypes=*/TypeRange{}, intrin, args,
fastMathFlags,
- /*op_bundle_operands=*/{});
+ /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{});
}
void CallIntrinsicOp::build(OpBuilder &builder, OperationState &state,
mlir::Type resultType, mlir::StringAttr intrin,
mlir::ValueRange args) {
build(builder, state, {resultType}, intrin, args, FastmathFlagsAttr{},
- /*op_bundle_operands=*/{});
+ /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{});
}
void CallIntrinsicOp::build(OpBuilder &builder, OperationState &state,
@@ -3355,7 +3374,7 @@ void CallIntrinsicOp::build(OpBuilder &builder, OperationState &state,
mlir::StringAttr intrin, mlir::ValueRange args,
mlir::LLVM::FastmathFlagsAttr fastMathFlags) {
build(builder, state, resultTypes, intrin, args, fastMathFlags,
- /*op_bundle_operands=*/{});
+ /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{});
}
//===----------------------------------------------------------------------===//
@@ -3412,6 +3431,18 @@ void InlineAsmOp::getEffects(
}
}
+//===----------------------------------------------------------------------===//
+// AssumeOp (intrinsic)
+//===----------------------------------------------------------------------===//
+
+void LLVM::AssumeOp::build(OpBuilder &builder, OperationState &state,
+ mlir::Value cond) {
+ return build(builder, state, cond, /*op_bundle_operands=*/{},
+ /*op_bundle_tags=*/{});
+}
+
+LogicalResult LLVM::AssumeOp::verify() { return verifyOperandBundles(*this); }
+
//===----------------------------------------------------------------------===//
// masked_gather (intrinsic)
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMIRToLLVMTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMIRToLLVMTranslation.cpp
index d034e576dfc579..afb1252e547276 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMIRToLLVMTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMIRToLLVMTranslation.cpp
@@ -68,6 +68,12 @@ static LogicalResult convertIntrinsicImpl(OpBuilder &odsBuilder,
if (isConvertibleIntrinsic(intrinsicID)) {
SmallVector<llvm::Value *> args(inst->args());
ArrayRef<llvm::Value *> llvmOperands(args);
+
+ SmallVector<llvm::OperandBundleUse> opBundles;
+ opBundles.reserve(inst->getNumOperandBundles());
+ for (unsigned i = 0; i < inst->getNumOperandBundles(); ++i)
+ opBundles.push_back(inst->getOperandBundleAt(i));
+
#include "mlir/Dialect/LLVMIR/LLVMIntrinsicFromLLVMIRConversions.inc"
}
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index a8595d14ccf2e5..c351e09c3d66ac 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -114,17 +114,27 @@ convertOperandBundle(OperandRange bundleOperands, StringRef bundleTag,
}
static SmallVector<llvm::OperandBundleDef>
-convertOperandBundles(OperandRangeRange bundleOperands,
- ArrayRef<std::string> bundleTags,
+convertOperandBundles(OperandRangeRange bundleOperands, ArrayAttr bundleTags,
LLVM::ModuleTranslation &moduleTranslation) {
SmallVector<llvm::OperandBundleDef> bundles;
bundles.reserve(bundleOperands.size());
- for (auto [operands, tag] : llvm::zip_equal(bundleOperands, bundleTags))
+ for (auto [operands, tagAttr] : llvm::zip_equal(bundleOperands, bundleTags)) {
+ StringRef tag = llvm::cast<StringAttr>(tagAttr).getValue();
bundles.push_back(convertOperandBundle(operands, tag, moduleTranslation));
+ }
return bundles;
}
+static SmallVector<llvm::OperandBundleDef>
+convertOperandBundles(OperandRangeRange bundleOperands,
+ std::optional<ArrayAttr> bundleTags,
+ LLVM::ModuleTranslation &moduleTranslation) {
+ if (!bundleTags)
+ return {};
+ return convertOperandBundles(bundleOperands, *bundleTags, moduleTranslation);
+}
+
/// Builder for LLVM_CallIntrinsicOp
static LogicalResult
convertCallLLVMIntrinsicOp(CallIntrinsicOp op, llvm::IRBuilderBase &builder,
diff --git a/mlir/lib/Target/LLVMIR/Dialect/NVVM/LLVMIRToNVVMTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/NVVM/LLVMIRToNVVMTranslation.cpp
index bc830a77f3c580..bc009f261f7fb7 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/NVVM/LLVMIRToNVVMTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/NVVM/LLVMIRToNVVMTranslation.cpp
@@ -50,6 +50,12 @@ static LogicalResult convertIntrinsicImpl(OpBuilder &odsBuilder,
if (isConvertibleIntrinsic(intrinsicID)) {
SmallVector<llvm::Value *> args(inst->args());
ArrayRef<llvm::Value *> llvmOperands(args);
+
+ SmallVector<llvm::OperandBundleUse> opBundles;
+ opBundles.reserve(inst->getNumOperandBundles());
+ for (unsigned i = 0; i < inst->getNumOperandBundles(); ++i)
+ opBundles.push_back(inst->getOperandBundleAt(i));
+
#include "mlir/Dialect/LLVMIR/NVVMFromLLVMIRConversions.inc"
}
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 4ff1f1135b0a88..d595f161d22bcf 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1291,8 +1291,10 @@ ModuleImport::convertValues(ArrayRef<llvm::Value *> values) {
}
LogicalResult ModuleImport::convertIntrinsicArguments(
- ArrayRef<llvm::Value *> values, ArrayRef<unsigned> immArgPositions,
- ArrayRef<StringLiteral> immArgAttrNames, SmallVectorImpl<Value> &valuesOut,
+ ArrayRef<llvm::Value *> values, ArrayRef<llvm::OperandBundleUse> opBundles,
+ ArrayRef<unsigned> immArgPositions, ArrayRef<StringLiteral> immArgAttrNames,
+ StringLiteral opBundleSizesAttrName, StringLiteral opBundleTagsAttrName,
+ SmallVectorImpl<Value> &valuesOut,
SmallVectorImpl<NamedAttribute> &attrsOut) {
assert(immArgPositions.size() == immArgAttrNames.size() &&
"LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
@@ -1321,6 +1323,37 @@ LogicalResult ModuleImport::convertIntrinsicArguments(
valuesOut.push_back(*mlirValue);
}
+ SmallVector<int> opBundleSizes;
+ SmallVector<Attribute> opBundleTagAttrs;
+ if (!opBundles.empty()) {
+ opBundleSizes.reserve(opBundles.size());
+ opBundleTagAttrs.reserve(opBundles.size());
+
+ for (const llvm::OperandBundleUse &bundle : opBundles) {
+ opBundleSizes.push_back(bundle.Inputs.size());
+ opBundleTagAttrs.push_back(StringAttr::get(context, bundle.getTagName()));
+
+ for (const llvm::Use &opBundleOperand : bundle.Inputs) {
+ auto operandMlirValue = convertValue(opBundleOperand.get());
+ if (failed(operandMlirValue))
+ return failure();
+ valuesOut.push_back(*operandMlirValue);
+ }
+ }
+ }
+ if (!opBundleSizesAttrName.empty()) {
+ auto opBundleSizesAttr = DenseI32ArrayAttr::get(context, opBundleSizes);
+ auto opBundleSizesAttrNameAttr =
+ StringAttr::get(context, opBundleSizesAttrName);
+ attrsOut.push_back({opBundleSizesAttrNameAttr, opBundleSizesAttr});
+ }
+ if (!opBundleTagsAttrName.empty()) {
+ auto opBundleTagsAttr = ArrayAttr::get(context, opBundleTagAttrs);
+ auto opBundleTagsAttrNameAttr =
+ StringAttr::get(context, opBundleTagsAttrName);
+ attrsOut.push_back({opBundleTagsAttrNameAttr, opBundleTagsAttr});
+ }
+
return success();
}
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index add0a31c114f8d..161eff08cc0e11 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -55,6 +55,7 @@
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
+#include <numeric>
#include <optional>
#define DEBUG_TYPE "llvm-dialect-to-llvm-ir"
@@ -848,14 +849,46 @@ llvm::CallInst *mlir::LLVM::detail::createIntrinsicCall(
llvm::IRBuilderBase &builder, ModuleTranslation &moduleTranslation,
Operation *intrOp, llvm::Intrinsic::ID intrinsic, unsigned numResults,
ArrayRef<unsigned> overloadedResults, ArrayRef<unsigned> overloadedOperands,
- ArrayRef<unsigned> immArgPositions,
- ArrayRef<StringLiteral> immArgAttrNames) {
+ ArrayRef<unsigned> immArgPositions, ArrayRef<StringLiteral> immArgAttrNames,
+ StringLiteral opBundleSizesAttrName, StringLiteral opBundleTagsAttrName) {
assert(immArgPositions.size() == immArgAttrNames.size() &&
"LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
"length");
+ SmallVector<llvm::OperandBundleDef> opBundles;
+ size_t numOpBundleOperands = 0;
+ if (!opBundleSizesAttrName.empty()) {
+ auto opBundleSizesAttr =
+ llvm::cast<DenseI32ArrayAttr>(intrOp->getAttr(opBundleSizesAttrName));
+ ArrayRef<int> opBundleSizes = opBundleSizesAttr.asArrayRef();
+
+ auto opBundleTagsAttr =
+ llvm::cast<ArrayAttr>(intrOp->getAttr(opBundleTagsAttrName));
+ assert(opBundleSizes.size() == opBundleTagsAttr.size() &&
+ "operand bundles and tags do not match");
+
+ numOpBundleOperands =
+ std::reduce(opBundleSizes.begin(), opBundleSizes.end());
+ assert(numOpBundleOperands <= intrOp->getNumOperands() &&
+ "operand bundle operands is more than the number of operands");
+
+ ValueRange operands = intrOp->getOperands().take_back(numOpBundleOperands);
+ size_t nextOperandIdx = 0;
+ opBundles.reserve(opBundleSizesAttr.size());
+
+ for (auto [opBundleTagAttr, bundleSize] :
+ llvm::zip(opBundleTagsAttr, opBundleSizes)) {
+ auto bundleTag = llvm::cast<StringAttr>(opBundleTagAttr).str();
+ auto bundleOperands = moduleTranslation.lookupValues(
+ operands.slice(nextOperandIdx, bundleSize));
+ opBundles.emplace_back(std::move(bundleTag), std::move(bundleOperands));
+ nextOperandIdx += bundleSize;
+ }
+ }
+
// Map operands and attributes to LLVM values.
- auto operands = moduleTranslation.lookupValues(intrOp->getOperands());
+ auto opOperands = intrOp->getOperands().drop_back(numOpBundleOperands);
+ auto operands = moduleTranslation.lookupValues(opOperands);
SmallVector<llvm::Value *> args(immArgPositions.size() + operands.size());
for (auto [immArgPos, immArgName] :
llvm::zip(immArgPositions, immArgAttrNames)) {
@@ -890,7 +923,7 @@ llvm::CallInst *mlir::LLVM::detail::createIntrinsicCall(
llvm::Function *llvmIntr = llvm::Intrinsic::getOrInsertDeclaration(
module, intrinsic, overloadedTypes);
- return builder.CreateCall(llvmIntr, args);
+ return builder.CreateCall(llvmIntr, args, opBundles);
}
/// Given a single MLIR operation, create the corresponding LLVM IR operation
diff --git a/mlir/test/Conversion/MemRefToLLVM/expand-then-convert-to-llvm.mlir b/mlir/test/Conversion/MemRefToLLVM/expand-then-convert-to-llvm.mlir
index b86103422b0745..8f579b206d6e10 100644
--- a/mlir/test/Conversion/MemRefToLLVM/expand-then-convert-to-llvm.mlir
+++ b/mlir/test/Conversion/MemRefToLLVM/expand-then-convert-to-llvm.mlir
@@ -684,7 +684,7 @@ func.func @collapse_static_shape_with_non_identity_layout(%arg: memref<1x1x8x8xf
// CHECK: %[[INT_TO_PTR:.*]] = llvm.ptrtoint %[[BUFF_ADDR]] : !llvm.ptr to i64
// CHECK: %[[AND:.*]] = llvm.and %[[INT_TO_PTR]], {{.*}} : i64
// CHECK: %[[CMP:.*]] = llvm.icmp "eq" %[[AND]], {{.*}} : i64
-// CHECK: "llvm.intr.assume"(%[[CMP]]) : (i1) -> ()
+// CHECK: llvm.intr.assume %[[CMP]] : (i1) -> ()
// CHECK: %[[LD_ADDR:.*]] = llvm.getelementptr %[[BUFF_ADDR]][%{{.*}}] : (!llvm.ptr, i64) -> !llvm.ptr, f32
// CHECK: %[[VAL:.*]] = llvm.load %[[LD_ADDR]] : !llvm.ptr -> f32
// CHECK: return %[[VAL]] : f32
diff --git a/mlir/test/Conversion/MemRefToLLVM/memref-to-llvm.mlir b/mlir/test/Conversion/MemRefToLLVM/memref-to-llvm.mlir
index 9dc22abf143bf0..a991d7508541f9 100644
--- a/mlir/test/Conversion/MemRefToLLVM/memref-to-llvm.mlir
+++ b/mlir/test/Conversion/MemRefToLLVM/memref-to-llvm.mlir
@@ -160,7 +160,7 @@ func.func @assume_alignment(%0 : memref<4x4xf16>) {
// CHECK-NEXT: %[[INT:.*]] = llvm.ptrtoint %[[PTR]] : !llvm.ptr to i64
// CHECK-NEXT: %[[MASKED_PTR:.*]] = llvm.and %[[INT]], %[[MASK:.*]] : i64
// CHECK-NEXT: %[[CONDITION:.*]] = llvm.icmp "eq" %[[MASKED_PTR]], %[[ZERO]] : i64
- // CHECK-NEXT: "llvm.intr.assume"(%[[CONDITION]]) : (i1) -> ()
+ // CHECK-NEXT: llvm.intr.assume %[[CONDITION]] : (i1) -> ()
memref.assume_alignment %0, 16 : memref<4x4xf16>
return
}
@@ -177,7 +177,7 @@ func.func @assume_alignment_w_offset(%0 : memref<4x4xf16, strided<[?, ?], offset
// CHECK-NEXT: %[[INT:.*]] = llvm.ptrtoint %[[BUFF_ADDR]] : !llvm.ptr to i64
// CHECK-NEXT: %[[MASKED_PTR:.*]] = llvm.and %[[INT]], %[[MASK:.*]] : i64
// CHECK-NEXT: %[[CONDITION:.*]] = llvm.icmp "eq" %[[MASKED_PTR]], %[[ZERO]] : i64
- // CHECK-NEXT: "llvm.intr.assume"(%[[CONDITION]]) : (i1) -> ()
+ // CHECK-NEXT: llvm.intr.assume %[[CONDITION]] : (i1) -> ()
memref.assume_alignment %0, 16 : memref<4x4xf16, strided<[?, ?], offset: ?>>
return
}
diff --git a/mlir/test/Dialect/LLVMIR/inlining.mlir b/mlir/test/Dialect/LLVMIR/inlining.mlir
index f9551e311df59f..739e9be53d6aa5 100644
--- a/mlir/test/Dialect/LLVMIR/inlining.mlir
+++ b/mlir/test/Dialect/LLVMIR/inlining.mlir
@@ -18,7 +18,7 @@ func.func @inner_func_inlinable(%ptr : !llvm.ptr) -> i32 {
"llvm.intr.memset"(%ptr, %byte, %0) <{isVolatile = true}> : (!llvm.ptr, i8, i32) -> ()
"llvm.intr.memmove"(%ptr, %ptr, %0) <{isVolatile = true}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
"llvm.intr.memcpy"(%ptr, %ptr, %0) <{isVolatile = true}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
- "llvm.intr.assume"(%true) : (i1) -> ()
+ llvm.intr.assume %true : (i1) -> ()
llvm.fence release
%2 = llvm.atomicrmw add %ptr, %0 monotonic : !llvm.ptr, i32
%3 = llvm.cmpxchg %ptr, %0, %1 acq_rel monotonic : !llvm.ptr, i32
@@ -44,7 +44,7 @@ func.func @inner_func_inlinable(%ptr : !llvm.ptr) -> i32 {
// CHECK: "llvm.intr.memset"(%[[PTR]]
// CHECK: "llvm.intr.memmove"(%[[PTR]], %[[PTR]]
// CHECK: "llvm.intr.memcpy"(%[[PTR]], %[[PTR]]
-// CHECK: "llvm.intr.assume"
+// CHECK: llvm.intr.assume
// CHECK: llvm.fence release
// CHECK: llvm.atomicrmw add %[[PTR]], %[[CST]] monotonic
// CHECK: llvm.cmpxchg %[[PTR]], %[[CST]], %[[RES]] acq_rel monotonic
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index 3062cdc38c0abb..cd83930915c239 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -836,3 +836,30 @@ llvm.func @test_call_intrin_with_opbundle(%arg0 : !llvm.ptr) {
llvm.call_intrinsic "llvm.assume"(%0) ["align"(%arg0, %1 : !llvm.ptr, i32)] : (i1) -> ()
llvm.return
}
+
+// CHECK-LABEL: @test_assume_intr
+llvm.func @test_assume_intr_no_opbundle(%arg0 : !llvm.ptr) {
+ %0 = llvm.mlir.constant(1 : i1) : i1
+ // CHECK: llvm.intr.assume %0 : (i1) -> ()
+ llvm.intr.assume %0 : (i1) -> ()
+ llvm.return
+}
+
+// CHECK-LABEL: @test_assume_intr
+llvm.func @test_assume_intr_empty_opbundle(%arg0 : !llvm.ptr) {
+ %0 = llvm.mlir.constant(1 : i1) : i1
+ // CHECK: llvm.intr.assume %0 : (i1) -> ()
+ llvm.intr.assume %0 [] : (i1) -> ()
+ llvm.return
+}
+
+// CHECK-LABEL: @test_assume_intr
+llvm.func @test_assume_intr_with_opbundles(%arg0 : !llvm.ptr) {
+ %0 = llvm.mlir.constant(1 : i1) : i1
+ %1 = llvm.mlir.constant(2 : i32) : i32
+ %2 = llvm.mlir.constant(3 : i32) : i32
+ %3 = llvm.mlir.constant(4 : i32) : i32
+ // CHECK: llvm.intr.assume %0 ["tag1"(%1, %2 : i32, i32), "tag2"(%3 : i32)] : (i1) -> ()
+ llvm.intr.assume %0 ["tag1"(%1, %2 : i32, i32), "tag2"(%3 : i32)] : (i1) -> ()
+ llvm.return
+}
diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic.ll b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
index 2fc2c3c6c32ffa..4fa3213f67ff4d 100644
--- a/mlir/test/Target/LLVMIR/Import/intrinsic.ll
+++ b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
@@ -612,7 +612,7 @@ define void @va_intrinsics_test(ptr %0, ptr %1, ...) {
; CHECK-LABEL: @assume
; CHECK-SAME: %[[TRUE:[a-zA-Z0-9]+]]
define void @assume(i1 %true) {
- ; CHECK: "llvm.intr.assume"(%[[TRUE]]) : (i1) -> ()
+ ; CHECK: llvm.intr.assume %[[TRUE]] : (i1) -> ()
call void @llvm.assume(i1 %true)
ret void
}
diff --git a/mlir/test/Target/LLVMIR/llvmir-invalid.mlir b/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
index af0981440a1776..4935cdbbc85b0c 100644
--- a/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-invalid.mlir
@@ -188,7 +188,7 @@ llvm.func @sadd_overflow_intr_wrong_type(%arg0 : i32, %arg1 : f32) -> !llvm.stru
llvm.func @assume_intr_wrong_type(%cond : i16) {
// expected-error @below{{op operand #0 must be 1-bit signless integer, but got 'i16'}}
- "llvm.intr.assume"(%cond) : (i16) -> ()
+ llvm.intr.assume %cond : (i16) -> ()
llvm.return
}
More information about the Mlir-commits
mailing list