[Mlir-commits] [mlir] [MLIR][LLVM] Add vararg support in LLVM::LLVMFuncOp (PR #67274)
Ivan R. Ivanov
llvmlistbot at llvm.org
Wed Sep 27 05:03:50 PDT 2023
https://github.com/ivanradanov updated https://github.com/llvm/llvm-project/pull/67274
>From 8d39692649fd0352657f7a205fbd9c2d8c5e43a1 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Sat, 23 Sep 2023 17:46:17 +0900
Subject: [PATCH 01/40] Build LLVM::CallOp with callee type info
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 9 +++-
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 51 ++++++++++++++++++---
2 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index c0216d1971e58d2..18be12a10cc0da6 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -618,7 +618,8 @@ def LLVM_CallOp : LLVM_MemAccessOpBase<"call",
```
}];
- dag args = (ins OptionalAttr<FlatSymbolRefAttr>:$callee,
+ dag args = (ins TypeAttrOf<LLVM_FunctionType>:$callee_type,
+ OptionalAttr<FlatSymbolRefAttr>:$callee,
Variadic<LLVM_Type>:$callee_operands,
DefaultValuedAttr<LLVM_FastmathFlagsAttr,
"{}">:$fastmathFlags,
@@ -633,6 +634,12 @@ def LLVM_CallOp : LLVM_MemAccessOpBase<"call",
OpBuilder<(ins "TypeRange":$results, "FlatSymbolRefAttr":$callee,
CArg<"ValueRange", "{}">:$args)>,
OpBuilder<(ins "TypeRange":$results, "StringRef":$callee,
+ CArg<"ValueRange", "{}">:$args)>,
+ OpBuilder<(ins "LLVMFunctionType":$calleeType, "StringAttr":$callee,
+ CArg<"ValueRange", "{}">:$args)>,
+ OpBuilder<(ins "LLVMFunctionType":$calleeType, "FlatSymbolRefAttr":$callee,
+ CArg<"ValueRange", "{}">:$args)>,
+ OpBuilder<(ins "LLVMFunctionType":$calleeType, "StringRef":$callee,
CArg<"ValueRange", "{}">:$args)>
];
let hasCustomAssemblyFormat = 1;
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 1cf91bde28183ac..c42dcbdbb3830f8 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1018,6 +1018,16 @@ static void printStoreType(OpAsmPrinter &printer, Operation *op,
// CallOp
//===----------------------------------------------------------------------===//
+namespace {
+static TypeRange getCallOpResults(LLVMFunctionType calleeType) {
+ SmallVector<Type> results;
+ Type resultType = calleeType.getReturnType();
+ if (!llvm::isa<LLVM::LLVMVoidType>(resultType))
+ results.push_back(resultType);
+ return results;
+}
+} // namespace
+
void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
StringRef callee, ValueRange args) {
build(builder, state, results, builder.getStringAttr(callee), args);
@@ -1030,7 +1040,38 @@ void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
FlatSymbolRefAttr callee, ValueRange args) {
- build(builder, state, results, callee, args, /*fastmathFlags=*/nullptr,
+ Type resultType;
+ if (results.empty())
+ resultType = LLVMVoidType::get(builder.getContext());
+ else
+ resultType = results.front();
+ std::vector<Type> argTypes(args.getTypes().begin(), args.getTypes().end());
+ auto calleeType =
+ LLVMFunctionType::get(resultType, argTypes, /*isVariadic*/ false);
+ build(builder, state, results, TypeAttr::get(calleeType), callee, args,
+ /*fastmathFlags=*/nullptr,
+ /*branch_weights=*/nullptr,
+ /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
+ /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
+}
+
+void CallOp::build(OpBuilder &builder, OperationState &state,
+ LLVMFunctionType calleeType, StringRef callee,
+ ValueRange args) {
+ build(builder, state, calleeType, builder.getStringAttr(callee), args);
+}
+
+void CallOp::build(OpBuilder &builder, OperationState &state,
+ LLVMFunctionType calleeType, StringAttr callee,
+ ValueRange args) {
+ build(builder, state, calleeType, SymbolRefAttr::get(callee), args);
+}
+
+void CallOp::build(OpBuilder &builder, OperationState &state,
+ LLVMFunctionType calleeType, FlatSymbolRefAttr callee,
+ ValueRange args) {
+ build(builder, state, getCallOpResults(calleeType), TypeAttr::get(calleeType),
+ callee, args, /*fastmathFlags=*/nullptr,
/*branch_weights=*/nullptr,
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
@@ -1038,11 +1079,9 @@ void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
void CallOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
ValueRange args) {
- SmallVector<Type> results;
- Type resultType = func.getFunctionType().getReturnType();
- if (!llvm::isa<LLVM::LLVMVoidType>(resultType))
- results.push_back(resultType);
- build(builder, state, results, SymbolRefAttr::get(func), args,
+ auto calleeType = func.getFunctionType();
+ build(builder, state, getCallOpResults(calleeType), TypeAttr::get(calleeType),
+ SymbolRefAttr::get(func), args,
/*fastmathFlags=*/nullptr,
/*branch_weights=*/nullptr,
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
>From fa45a1e6a37093653102c36dd417df82774cbb98 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Sat, 23 Sep 2023 17:54:54 +0900
Subject: [PATCH 02/40] Fix Conversion of CallOp func type
---
.../LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 9b438090c84cacc..c27bc1b6f29076b 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -211,9 +211,10 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
call = builder.CreateCall(
moduleTranslation.lookupFunction(attr.getValue()), operandsRef);
} else {
- call = builder.CreateCall(getCalleeFunctionType(callOp.getResultTypes(),
- callOp.getArgOperands()),
- operandsRef.front(), operandsRef.drop_front());
+ call = builder.CreateCall(
+ llvm::cast<llvm::FunctionType>(
+ moduleTranslation.convertType(callOp.getCalleeType())),
+ operandsRef.front(), operandsRef.drop_front());
}
moduleTranslation.setAccessGroupsMetadata(callOp, call);
moduleTranslation.setAliasScopeMetadata(callOp, call);
>From 0a6c945170b180f765b7ecc004f3283f5a36daeb Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Mon, 25 Sep 2023 10:37:30 +0900
Subject: [PATCH 03/40] Print vararg info
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 2 +-
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 36 ++++++++++++++++---
.../LLVMIR/LLVMToLLVMIRTranslation.cpp | 2 +-
3 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 18be12a10cc0da6..853bb7f3405e0f0 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -618,7 +618,7 @@ def LLVM_CallOp : LLVM_MemAccessOpBase<"call",
```
}];
- dag args = (ins TypeAttrOf<LLVM_FunctionType>:$callee_type,
+ dag args = (ins OptionalAttr<TypeAttrOf<LLVM_FunctionType>>:$callee_type,
OptionalAttr<FlatSymbolRefAttr>:$callee,
Variadic<LLVM_Type>:$callee_operands,
DefaultValuedAttr<LLVM_FastmathFlagsAttr,
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index c42dcbdbb3830f8..f67818092f0f1f1 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1240,6 +1240,8 @@ LogicalResult CallOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
void CallOp::print(OpAsmPrinter &p) {
auto callee = getCallee();
bool isDirect = callee.has_value();
+ auto calleeType = *getCalleeType();
+ bool isVarArg = calleeType.isVarArg();
// Print the direct callee if present as a function attribute, or an indirect
// callee (first operand) otherwise.
@@ -1249,9 +1251,13 @@ void CallOp::print(OpAsmPrinter &p) {
else
p << getOperand(0);
+ if (isVarArg)
+ p << " vararg " << getCalleeType() << ' ';
+
auto args = getOperands().drop_front(isDirect ? 0 : 1);
p << '(' << args << ')';
- p.printOptionalAttrDict(processFMFAttr((*this)->getAttrs()), {"callee"});
+ p.printOptionalAttrDict(processFMFAttr((*this)->getAttrs()),
+ {"callee", "callee_type"});
p << " : ";
if (!isDirect)
@@ -1265,7 +1271,7 @@ void CallOp::print(OpAsmPrinter &p) {
/// succeeds. Returns failure otherwise.
static ParseResult parseCallTypeAndResolveOperands(
OpAsmParser &parser, OperationState &result, bool isDirect,
- ArrayRef<OpAsmParser::UnresolvedOperand> operands) {
+ ArrayRef<OpAsmParser::UnresolvedOperand> operands, bool isVarArg) {
SMLoc trailingTypesLoc = parser.getCurrentLocation();
SmallVector<Type> types;
if (parser.parseColonTypeList(types))
@@ -1301,6 +1307,18 @@ static ParseResult parseCallTypeAndResolveOperands(
if (funcType.getNumResults() != 0)
result.addTypes(funcType.getResults());
+ if (!isVarArg) {
+ Type returnType;
+ if (funcType.getNumResults() == 0)
+ returnType = LLVM::LLVMVoidType::get(result.getContext());
+ else
+ returnType = funcType.getResult(0);
+ result.addAttribute(
+ "callee_type",
+ TypeAttr::get(LLVM::LLVMFunctionType::get(
+ returnType, funcType.getInputs(), /*isVarArg*/ false)));
+ }
+
return success();
}
@@ -1319,10 +1337,12 @@ static ParseResult parseOptionalCallFuncPtr(
return success();
}
-// <operation> ::= `llvm.call` (function-id | ssa-use)`(` ssa-use-list `)`
+// <operation> ::= `llvm.call` (function-id | ssa-use) var-arg-func-type?
+// `(` ssa-use-list `)`
// attribute-dict? `:` (type `,`)? function-type
ParseResult CallOp::parse(OpAsmParser &parser, OperationState &result) {
SymbolRefAttr funcAttr;
+ TypeAttr calleeType;
SmallVector<OpAsmParser::UnresolvedOperand> operands;
// Parse a function pointer for indirect calls.
@@ -1335,13 +1355,18 @@ ParseResult CallOp::parse(OpAsmParser &parser, OperationState &result) {
if (parser.parseAttribute(funcAttr, "callee", result.attributes))
return failure();
+ bool isVarArg = parser.parseOptionalKeyword("vararg").succeeded();
+ if (isVarArg)
+ parser.parseOptionalAttribute(calleeType, "callee_type", result.attributes);
+
// Parse the function arguments.
if (parser.parseOperandList(operands, OpAsmParser::Delimiter::Paren) ||
parser.parseOptionalAttrDict(result.attributes))
return failure();
// Parse the trailing type list and resolve the operands.
- return parseCallTypeAndResolveOperands(parser, result, isDirect, operands);
+ return parseCallTypeAndResolveOperands(parser, result, isDirect, operands,
+ isVarArg);
}
///===---------------------------------------------------------------------===//
@@ -1456,7 +1481,8 @@ ParseResult InvokeOp::parse(OpAsmParser &parser, OperationState &result) {
return failure();
// Parse the trailing type list and resolve the function operands.
- if (parseCallTypeAndResolveOperands(parser, result, isDirect, operands))
+ if (parseCallTypeAndResolveOperands(parser, result, isDirect, operands,
+ /*isVarArg*/ false))
return failure();
result.addSuccessors({normalDest, unwindDest});
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index c27bc1b6f29076b..cdd22f116a4ef9d 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -213,7 +213,7 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
} else {
call = builder.CreateCall(
llvm::cast<llvm::FunctionType>(
- moduleTranslation.convertType(callOp.getCalleeType())),
+ moduleTranslation.convertType(*callOp.getCalleeType())),
operandsRef.front(), operandsRef.drop_front());
}
moduleTranslation.setAccessGroupsMetadata(callOp, call);
>From 842982663d876b331fb14b8c6737b80ab38f867d Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 12:03:03 +0900
Subject: [PATCH 04/40] Fixes
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 49 ++++++++++++-------
.../LLVMIR/LLVMToLLVMIRTranslation.cpp | 13 +++--
2 files changed, 41 insertions(+), 21 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index f67818092f0f1f1..5296b5a34a750f4 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1018,15 +1018,14 @@ static void printStoreType(OpAsmPrinter &printer, Operation *op,
// CallOp
//===----------------------------------------------------------------------===//
-namespace {
-static TypeRange getCallOpResults(LLVMFunctionType calleeType) {
- SmallVector<Type> results;
+/// Get the MLIR Op-like result types of a LLVM fuction type
+static SmallVector<Type, 1> getCallOpResults(LLVMFunctionType calleeType) {
+ SmallVector<Type, 1> results;
Type resultType = calleeType.getReturnType();
- if (!llvm::isa<LLVM::LLVMVoidType>(resultType))
+ if (!isa<LLVM::LLVMVoidType>(resultType))
results.push_back(resultType);
return results;
}
-} // namespace
void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
StringRef callee, ValueRange args) {
@@ -1045,9 +1044,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
resultType = LLVMVoidType::get(builder.getContext());
else
resultType = results.front();
- std::vector<Type> argTypes(args.getTypes().begin(), args.getTypes().end());
- auto calleeType =
- LLVMFunctionType::get(resultType, argTypes, /*isVariadic*/ false);
+ auto calleeType = LLVMFunctionType::get(
+ resultType, llvm::to_vector(args.getTypes()), /*isVariadic*/ false);
build(builder, state, results, TypeAttr::get(calleeType), callee, args,
/*fastmathFlags=*/nullptr,
/*branch_weights=*/nullptr,
@@ -1240,8 +1238,17 @@ LogicalResult CallOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
void CallOp::print(OpAsmPrinter &p) {
auto callee = getCallee();
bool isDirect = callee.has_value();
- auto calleeType = *getCalleeType();
- bool isVarArg = calleeType.isVarArg();
+
+ LLVMFunctionType calleeType;
+ bool isVarArg;
+
+ std::optional<LLVMFunctionType> optionalCalleeType = getCalleeType();
+ if (optionalCalleeType.has_value()) {
+ calleeType = *optionalCalleeType;
+ isVarArg = calleeType.isVarArg();
+ } else {
+ isVarArg = false;
+ }
// Print the direct callee if present as a function attribute, or an indirect
// callee (first operand) otherwise.
@@ -1251,11 +1258,12 @@ void CallOp::print(OpAsmPrinter &p) {
else
p << getOperand(0);
- if (isVarArg)
- p << " vararg " << getCalleeType() << ' ';
-
auto args = getOperands().drop_front(isDirect ? 0 : 1);
p << '(' << args << ')';
+
+ if (isVarArg)
+ p << " vararg(" << calleeType << ") ";
+
p.printOptionalAttrDict(processFMFAttr((*this)->getAttrs()),
{"callee", "callee_type"});
@@ -1355,15 +1363,22 @@ ParseResult CallOp::parse(OpAsmParser &parser, OperationState &result) {
if (parser.parseAttribute(funcAttr, "callee", result.attributes))
return failure();
- bool isVarArg = parser.parseOptionalKeyword("vararg").succeeded();
- if (isVarArg)
- parser.parseOptionalAttribute(calleeType, "callee_type", result.attributes);
-
// Parse the function arguments.
if (parser.parseOperandList(operands, OpAsmParser::Delimiter::Paren) ||
parser.parseOptionalAttrDict(result.attributes))
return failure();
+ bool isVarArg = parser.parseOptionalKeyword("vararg").succeeded();
+ if (isVarArg) {
+ if (parser.parseLParen().failed() ||
+ !parser
+ .parseOptionalAttribute(calleeType, "callee_type",
+ result.attributes)
+ .has_value() ||
+ parser.parseRParen().failed())
+ return failure();
+ }
+
// Parse the trailing type list and resolve the operands.
return parseCallTypeAndResolveOperands(parser, result, isDirect, operands,
isVarArg);
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index cdd22f116a4ef9d..61f9088d7e30f73 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -211,10 +211,15 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
call = builder.CreateCall(
moduleTranslation.lookupFunction(attr.getValue()), operandsRef);
} else {
- call = builder.CreateCall(
- llvm::cast<llvm::FunctionType>(
- moduleTranslation.convertType(*callOp.getCalleeType())),
- operandsRef.front(), operandsRef.drop_front());
+ llvm::FunctionType *calleeType;
+ if (callOp.getCalleeType().has_value())
+ calleeType = llvm::cast<llvm::FunctionType>(
+ moduleTranslation.convertType(*callOp.getCalleeType()));
+ else
+ calleeType = getCalleeFunctionType(callOp.getResultTypes(),
+ callOp.getArgOperands());
+ call = builder.CreateCall(calleeType, operandsRef.front(),
+ operandsRef.drop_front());
}
moduleTranslation.setAccessGroupsMetadata(callOp, call);
moduleTranslation.setAliasScopeMetadata(callOp, call);
>From 370f3e4d27959438c3aba33e1f33d4be48639d4d Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 13:11:09 +0900
Subject: [PATCH 05/40] Also add callee type to invoke op
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 19 ++--
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 95 +++++++++++++++----
.../LLVMIR/LLVMToLLVMIRTranslation.cpp | 10 +-
3 files changed, 90 insertions(+), 34 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 853bb7f3405e0f0..af6d45966eeebca 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -542,7 +542,9 @@ def LLVM_InvokeOp : LLVM_Op<"invoke", [
DeclareOpInterfaceMethods<CallOpInterface>,
DeclareOpInterfaceMethods<BranchWeightOpInterface>,
Terminator]> {
- let arguments = (ins OptionalAttr<FlatSymbolRefAttr>:$callee,
+ let arguments = (ins
+ OptionalAttr<TypeAttrOf<LLVM_FunctionType>>:$callee_type,
+ OptionalAttr<FlatSymbolRefAttr>:$callee,
Variadic<LLVM_Type>:$callee_operands,
Variadic<LLVM_Type>:$normalDestOperands,
Variadic<LLVM_Type>:$unwindDestOperands,
@@ -552,19 +554,14 @@ def LLVM_InvokeOp : LLVM_Op<"invoke", [
AnySuccessor:$unwindDest);
let builders = [
+ OpBuilder<(ins "LLVMFuncOp":$func,
+ "ValueRange":$ops, "Block*":$normal, "ValueRange":$normalOps,
+ "Block*":$unwind, "ValueRange":$unwindOps)>,
OpBuilder<(ins "TypeRange":$tys, "FlatSymbolRefAttr":$callee,
"ValueRange":$ops, "Block*":$normal, "ValueRange":$normalOps,
- "Block*":$unwind, "ValueRange":$unwindOps),
- [{
- $_state.addAttribute("callee", callee);
- build($_builder, $_state, tys, ops, normal, normalOps, unwind, unwindOps);
- }]>,
+ "Block*":$unwind, "ValueRange":$unwindOps)>,
OpBuilder<(ins "TypeRange":$tys, "ValueRange":$ops, "Block*":$normal,
- "ValueRange":$normalOps, "Block*":$unwind, "ValueRange":$unwindOps),
- [{
- build($_builder, $_state, tys, /*callee=*/FlatSymbolRefAttr(), ops, normalOps,
- unwindOps, nullptr, normal, unwind);
- }]>];
+ "ValueRange":$normalOps, "Block*":$unwind, "ValueRange":$unwindOps)>];
let hasCustomAssemblyFormat = 1;
let hasVerifier = 1;
}
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 5296b5a34a750f4..8995b8e0ac52dab 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1018,7 +1018,7 @@ static void printStoreType(OpAsmPrinter &printer, Operation *op,
// CallOp
//===----------------------------------------------------------------------===//
-/// Get the MLIR Op-like result types of a LLVM fuction type
+/// Get the MLIR Op-like result types of a LLVMFunctionType
static SmallVector<Type, 1> getCallOpResults(LLVMFunctionType calleeType) {
SmallVector<Type, 1> results;
Type resultType = calleeType.getReturnType();
@@ -1027,6 +1027,18 @@ static SmallVector<Type, 1> getCallOpResults(LLVMFunctionType calleeType) {
return results;
}
+/// Construct a LLVMFunctionType from MLIR results and args
+static LLVMFunctionType getLLVMFuncType(OpBuilder &builder, TypeRange results,
+ ValueRange args) {
+ Type resultType;
+ if (results.empty())
+ resultType = LLVMVoidType::get(builder.getContext());
+ else
+ resultType = results.front();
+ return LLVMFunctionType::get(resultType, llvm::to_vector(args.getTypes()),
+ /*isVariadic*/ false);
+}
+
void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
StringRef callee, ValueRange args) {
build(builder, state, results, builder.getStringAttr(callee), args);
@@ -1039,14 +1051,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
FlatSymbolRefAttr callee, ValueRange args) {
- Type resultType;
- if (results.empty())
- resultType = LLVMVoidType::get(builder.getContext());
- else
- resultType = results.front();
- auto calleeType = LLVMFunctionType::get(
- resultType, llvm::to_vector(args.getTypes()), /*isVariadic*/ false);
- build(builder, state, results, TypeAttr::get(calleeType), callee, args,
+ build(builder, state, results,
+ TypeAttr::get(getLLVMFuncType(builder, results, args)), callee, args,
/*fastmathFlags=*/nullptr,
/*branch_weights=*/nullptr,
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
@@ -1185,14 +1191,8 @@ LogicalResult CallOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
if (!funcType)
return emitOpError("callee does not have a functional type: ") << fnType;
- // Indirect variadic function calls are not supported since the translation to
- // LLVM IR reconstructs the LLVM function type from the argument and result
- // types. An additional type attribute that stores the LLVM function type
- // would be needed to distinguish normal and variadic function arguments.
- // TODO: Support indirect calls to variadic function pointers.
- if (isIndirect && funcType.isVarArg())
- return emitOpError()
- << "indirect calls to variadic functions are not supported";
+ if (funcType.isVarArg() && !getCalleeType().has_value())
+ return emitOpError() << "Missing callee type attribute for vararg call";
// Verify that the operand and result types match the callee.
@@ -1388,6 +1388,30 @@ ParseResult CallOp::parse(OpAsmParser &parser, OperationState &result) {
/// LLVM::InvokeOp
///===---------------------------------------------------------------------===//
+void InvokeOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
+ ValueRange ops, Block *normal, ValueRange normalOps,
+ Block *unwind, ValueRange unwindOps) {
+ auto calleeType = func.getFunctionType();
+ build(builder, state, getCallOpResults(calleeType), TypeAttr::get(calleeType),
+ SymbolRefAttr::get(func), ops, normalOps, unwindOps, nullptr, normal,
+ unwind);
+}
+
+void InvokeOp::build(OpBuilder &builder, OperationState &state, TypeRange tys,
+ FlatSymbolRefAttr callee, ValueRange ops, Block *normal,
+ ValueRange normalOps, Block *unwind,
+ ValueRange unwindOps) {
+ build(builder, state, tys, TypeAttr::get(getLLVMFuncType(builder, tys, ops)),
+ callee, ops, normalOps, unwindOps, nullptr, normal, unwind);
+}
+
+void InvokeOp::build(OpBuilder &builder, OperationState &state, TypeRange tys,
+ ValueRange ops, Block *normal, ValueRange normalOps,
+ Block *unwind, ValueRange unwindOps) {
+ build(builder, state, tys, TypeAttr::get(getLLVMFuncType(builder, tys, ops)),
+ /*callee=*/nullptr, ops, normalOps, unwindOps, nullptr, normal, unwind);
+}
+
SuccessorOperands InvokeOp::getSuccessorOperands(unsigned index) {
assert(index < getNumSuccessors() && "invalid successor index");
return SuccessorOperands(index == 0 ? getNormalDestOperandsMutable()
@@ -1441,6 +1465,17 @@ void InvokeOp::print(OpAsmPrinter &p) {
auto callee = getCallee();
bool isDirect = callee.has_value();
+ LLVMFunctionType calleeType;
+ bool isVarArg;
+
+ std::optional<LLVMFunctionType> optionalCalleeType = getCalleeType();
+ if (optionalCalleeType.has_value()) {
+ calleeType = *optionalCalleeType;
+ isVarArg = calleeType.isVarArg();
+ } else {
+ isVarArg = false;
+ }
+
p << ' ';
// Either function name or pointer
@@ -1455,8 +1490,12 @@ void InvokeOp::print(OpAsmPrinter &p) {
p << " unwind ";
p.printSuccessorAndUseList(getUnwindDest(), getUnwindDestOperands());
- p.printOptionalAttrDict((*this)->getAttrs(),
- {InvokeOp::getOperandSegmentSizeAttr(), "callee"});
+ if (isVarArg)
+ p << " vararg(" << calleeType << ") ";
+
+ p.printOptionalAttrDict(
+ (*this)->getAttrs(),
+ {InvokeOp::getOperandSegmentSizeAttr(), "callee", "callee_type"});
p << " : ";
if (!isDirect)
@@ -1473,6 +1512,7 @@ void InvokeOp::print(OpAsmPrinter &p) {
ParseResult InvokeOp::parse(OpAsmParser &parser, OperationState &result) {
SmallVector<OpAsmParser::UnresolvedOperand, 8> operands;
SymbolRefAttr funcAttr;
+ TypeAttr calleeType;
Block *normalDest, *unwindDest;
SmallVector<Value, 4> normalOperands, unwindOperands;
Builder &builder = parser.getBuilder();
@@ -1491,8 +1531,21 @@ ParseResult InvokeOp::parse(OpAsmParser &parser, OperationState &result) {
parser.parseKeyword("to") ||
parser.parseSuccessorAndUseList(normalDest, normalOperands) ||
parser.parseKeyword("unwind") ||
- parser.parseSuccessorAndUseList(unwindDest, unwindOperands) ||
- parser.parseOptionalAttrDict(result.attributes))
+ parser.parseSuccessorAndUseList(unwindDest, unwindOperands))
+ return failure();
+
+ bool isVarArg = parser.parseOptionalKeyword("vararg").succeeded();
+ if (isVarArg) {
+ if (parser.parseLParen().failed() ||
+ !parser
+ .parseOptionalAttribute(calleeType, "callee_type",
+ result.attributes)
+ .has_value() ||
+ parser.parseRParen().failed())
+ return failure();
+ }
+
+ if (parser.parseOptionalAttrDict(result.attributes))
return failure();
// Parse the trailing type list and resolve the function operands.
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 61f9088d7e30f73..8c84e80494e324a 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -303,9 +303,15 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
moduleTranslation.lookupBlock(invOp.getSuccessor(0)),
moduleTranslation.lookupBlock(invOp.getSuccessor(1)), operandsRef);
} else {
+ llvm::FunctionType *calleeType;
+ if (invOp.getCalleeType().has_value())
+ calleeType = llvm::cast<llvm::FunctionType>(
+ moduleTranslation.convertType(*invOp.getCalleeType()));
+ else
+ calleeType = getCalleeFunctionType(invOp.getResultTypes(),
+ invOp.getArgOperands());
result = builder.CreateInvoke(
- getCalleeFunctionType(invOp.getResultTypes(), invOp.getArgOperands()),
- operandsRef.front(),
+ calleeType, operandsRef.front(),
moduleTranslation.lookupBlock(invOp.getSuccessor(0)),
moduleTranslation.lookupBlock(invOp.getSuccessor(1)),
operandsRef.drop_front());
>From db39a9921eeeec64f9a4f254a9e8a8cb48e13c48 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 13:24:13 +0900
Subject: [PATCH 06/40] Add builder with func type to InvokeOp
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 5 +++--
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 7 ++++---
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index af6d45966eeebca..308e848addbf605 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -560,8 +560,9 @@ def LLVM_InvokeOp : LLVM_Op<"invoke", [
OpBuilder<(ins "TypeRange":$tys, "FlatSymbolRefAttr":$callee,
"ValueRange":$ops, "Block*":$normal, "ValueRange":$normalOps,
"Block*":$unwind, "ValueRange":$unwindOps)>,
- OpBuilder<(ins "TypeRange":$tys, "ValueRange":$ops, "Block*":$normal,
- "ValueRange":$normalOps, "Block*":$unwind, "ValueRange":$unwindOps)>];
+ OpBuilder<(ins "LLVMFunctionType":$calleeType, "FlatSymbolRefAttr":$callee,
+ "ValueRange":$ops, "Block*":$normal, "ValueRange":$normalOps,
+ "Block*":$unwind, "ValueRange":$unwindOps)>];
let hasCustomAssemblyFormat = 1;
let hasVerifier = 1;
}
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 8995b8e0ac52dab..832e6e9cdc0e2bc 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1405,11 +1405,12 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state, TypeRange tys,
callee, ops, normalOps, unwindOps, nullptr, normal, unwind);
}
-void InvokeOp::build(OpBuilder &builder, OperationState &state, TypeRange tys,
+void InvokeOp::build(OpBuilder &builder, OperationState &state,
+ LLVMFunctionType calleeType, FlatSymbolRefAttr callee,
ValueRange ops, Block *normal, ValueRange normalOps,
Block *unwind, ValueRange unwindOps) {
- build(builder, state, tys, TypeAttr::get(getLLVMFuncType(builder, tys, ops)),
- /*callee=*/nullptr, ops, normalOps, unwindOps, nullptr, normal, unwind);
+ build(builder, state, getCallOpResults(calleeType), TypeAttr::get(calleeType),
+ callee, ops, normalOps, unwindOps, nullptr, normal, unwind);
}
SuccessorOperands InvokeOp::getSuccessorOperands(unsigned index) {
>From 73a3a878f42de769cff942cab64d0b77b44ba912 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 13:24:44 +0900
Subject: [PATCH 07/40] Fix importing of LLVM Call and Invoke Instruction
---
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index c6c30880d4f2c15..ffd3857b467024a 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1347,12 +1347,17 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
if (failed(convertCallTypeAndOperands(callInst, types, operands)))
return failure();
+ auto funcTy =
+ dyn_cast<LLVMFunctionType>(convertType(callInst->getFunctionType()));
+
CallOp callOp;
+
if (llvm::Function *callee = callInst->getCalledFunction()) {
callOp = builder.create<CallOp>(
- loc, types, SymbolRefAttr::get(context, callee->getName()), operands);
+ loc, funcTy, SymbolRefAttr::get(context, callee->getName()),
+ operands);
} else {
- callOp = builder.create<CallOp>(loc, types, operands);
+ callOp = builder.create<CallOp>(loc, funcTy, operands);
}
setFastmathFlagsAttr(inst, callOp);
if (!callInst->getType()->isVoidTy())
@@ -1411,20 +1416,23 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
unwindArgs)))
return failure();
+ auto funcTy =
+ dyn_cast<LLVMFunctionType>(convertType(invokeInst->getFunctionType()));
+
// Create the invoke operation. Normal destination block arguments will be
// added later on to handle the case in which the operation result is
// included in this list.
InvokeOp invokeOp;
if (llvm::Function *callee = invokeInst->getCalledFunction()) {
invokeOp = builder.create<InvokeOp>(
- loc, types,
+ loc, funcTy,
SymbolRefAttr::get(builder.getContext(), callee->getName()), operands,
directNormalDest, ValueRange(),
lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
} else {
invokeOp = builder.create<InvokeOp>(
- loc, types, operands, directNormalDest, ValueRange(),
- lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
+ loc, funcTy, /*callee*/ nullptr, operands, directNormalDest,
+ ValueRange(), lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
}
if (!invokeInst->getType()->isVoidTy())
mapValue(inst, invokeOp.getResults().front());
>From 6a44d1bcf07802bda1fff4823a218a25ac9479a8 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 13:47:37 +0900
Subject: [PATCH 08/40] Add a builder for indirect calls
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 1 +
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 10 ++++++++++
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 4 ++++
3 files changed, 15 insertions(+)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 308e848addbf605..f55a1449fd062f9 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -627,6 +627,7 @@ def LLVM_CallOp : LLVM_MemAccessOpBase<"call",
let results = (outs Optional<LLVM_Type>:$result);
let builders = [
OpBuilder<(ins "LLVMFuncOp":$func, "ValueRange":$args)>,
+ OpBuilder<(ins "LLVMFunctionType":$calleeType, "ValueRange":$args)>,
OpBuilder<(ins "TypeRange":$results, "StringAttr":$callee,
CArg<"ValueRange", "{}">:$args)>,
OpBuilder<(ins "TypeRange":$results, "FlatSymbolRefAttr":$callee,
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 832e6e9cdc0e2bc..36a54a2ce1f1df7 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1081,6 +1081,16 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
}
+void CallOp::build(OpBuilder &builder, OperationState &state,
+ LLVMFunctionType calleeType, ValueRange args) {
+ build(builder, state, getCallOpResults(calleeType), TypeAttr::get(calleeType),
+ /*callee=*/nullptr, args,
+ /*fastmathFlags=*/nullptr,
+ /*branch_weights=*/nullptr,
+ /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
+ /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
+}
+
void CallOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
ValueRange args) {
auto calleeType = func.getFunctionType();
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index ffd3857b467024a..5e5adb4238c57b2 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1349,6 +1349,8 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
auto funcTy =
dyn_cast<LLVMFunctionType>(convertType(callInst->getFunctionType()));
+ if (!funcTy)
+ return failure();
CallOp callOp;
@@ -1418,6 +1420,8 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
auto funcTy =
dyn_cast<LLVMFunctionType>(convertType(invokeInst->getFunctionType()));
+ if (!funcTy)
+ return failure();
// Create the invoke operation. Normal destination block arguments will be
// added later on to handle the case in which the operation result is
>From d282897808142b645985afc5baead1e8d4bcff88 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 13:58:50 +0900
Subject: [PATCH 09/40] Remove now supported case from failing test
---
mlir/test/Dialect/LLVMIR/invalid-typed-pointers.mlir | 8 --------
1 file changed, 8 deletions(-)
diff --git a/mlir/test/Dialect/LLVMIR/invalid-typed-pointers.mlir b/mlir/test/Dialect/LLVMIR/invalid-typed-pointers.mlir
index bb177eb1500ad68..a87b1952b6dca70 100644
--- a/mlir/test/Dialect/LLVMIR/invalid-typed-pointers.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid-typed-pointers.mlir
@@ -35,14 +35,6 @@ func.func @gep_too_few_dynamic(%base : !llvm.ptr<f32>) {
// -----
-func.func @call_variadic(%callee : !llvm.ptr<func<i8 (i8, ...)>>, %arg : i8) {
- // expected-error at +1 {{indirect calls to variadic functions are not supported}}
- llvm.call %callee(%arg) : !llvm.ptr<func<i8 (i8, ...)>>, (i8) -> (i8)
- llvm.return
-}
-
-// -----
-
func.func @indirect_callee_arg_mismatch(%arg0 : i32, %callee : !llvm.ptr<func<void(i8)>>) {
// expected-error at +1 {{'llvm.call' op operand type mismatch for operand 0: 'i32' != 'i8'}}
"llvm.call"(%callee, %arg0) : (!llvm.ptr<func<void(i8)>>, i32) -> ()
>From 20f6eb5c2cd6afe9d90dc949366d0f2a367c52ef Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 13:59:05 +0900
Subject: [PATCH 10/40] Add test for importing vararg indirect call
---
mlir/test/Target/LLVMIR/Import/instructions.ll | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/mlir/test/Target/LLVMIR/Import/instructions.ll b/mlir/test/Target/LLVMIR/Import/instructions.ll
index 3f5ade4f1573579..79712a2fadb9ea3 100644
--- a/mlir/test/Target/LLVMIR/Import/instructions.ll
+++ b/mlir/test/Target/LLVMIR/Import/instructions.ll
@@ -480,6 +480,17 @@ define void @indirect_call(ptr addrspace(42) %fn) {
; // -----
+; CHECK-LABEL: @indirect_vararg_call
+; CHECK-SAME: %[[PTR:[a-zA-Z0-9]+]]
+define void @indirect_vararg_call(ptr addrspace(42) %fn) {
+ ; CHECK: %[[C0:[0-9]+]] = llvm.mlir.constant(0 : i16) : i16
+ ; CHECK: llvm.call %[[PTR]](%[[C0]]) vararg(!llvm.func<void (...)>) : !llvm.ptr<42>, (i16) -> ()
+ call addrspace(42) void (...) %fn(i16 0)
+ ret void
+}
+
+; // -----
+
; CHECK-LABEL: @gep_static_idx
; CHECK-SAME: %[[PTR:[a-zA-Z0-9]+]]
define void @gep_static_idx(ptr %ptr) {
@@ -497,7 +508,7 @@ declare void @varargs(...)
; CHECK-LABEL: @varargs_call
; CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]
define void @varargs_call(i32 %0) {
- ; CHECK: llvm.call @varargs(%[[ARG1]]) : (i32) -> ()
+ ; CHECK: llvm.call @varargs(%[[ARG1]]) vararg(!llvm.func<void (...)>) : (i32) -> ()
call void (...) @varargs(i32 %0)
ret void
}
>From be4026e5a5da8c967bb3b085ba2a26f3bd1edeaf Mon Sep 17 00:00:00 2001
From: "Ivan R. Ivanov" <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 23:31:17 +0900
Subject: [PATCH 11/40] Update mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
Co-authored-by: Christian Ulmann <christianulmann at gmail.com>
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 36a54a2ce1f1df7..76e7e110e5b4d26 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1250,14 +1250,11 @@ void CallOp::print(OpAsmPrinter &p) {
bool isDirect = callee.has_value();
LLVMFunctionType calleeType;
- bool isVarArg;
+ bool isVarArg = false;
- std::optional<LLVMFunctionType> optionalCalleeType = getCalleeType();
- if (optionalCalleeType.has_value()) {
+ if (std::optional<LLVMFunctionType> optionalCalleeType = getCalleeType()) {
calleeType = *optionalCalleeType;
isVarArg = calleeType.isVarArg();
- } else {
- isVarArg = false;
}
// Print the direct callee if present as a function attribute, or an indirect
>From 68c932458d12600a9b08a14a36352869421ffd34 Mon Sep 17 00:00:00 2001
From: "Ivan R. Ivanov" <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 23:38:59 +0900
Subject: [PATCH 12/40] Update mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
Co-authored-by: Christian Ulmann <christianulmann at gmail.com>
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 76e7e110e5b4d26..7b47e654529cdaf 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1352,7 +1352,7 @@ static ParseResult parseOptionalCallFuncPtr(
return success();
}
-// <operation> ::= `llvm.call` (function-id | ssa-use) var-arg-func-type?
+// <operation> ::= `llvm.call` (function-id | ssa-use) ( `vararg(` var-arg-func-type `)` )?
// `(` ssa-use-list `)`
// attribute-dict? `:` (type `,`)? function-type
ParseResult CallOp::parse(OpAsmParser &parser, OperationState &result) {
>From 309f1fb5d3eca322a66bd4a6e91d65fe12086dc2 Mon Sep 17 00:00:00 2001
From: "Ivan R. Ivanov" <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 00:03:49 +0900
Subject: [PATCH 13/40] Update
mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
Co-authored-by: Christian Ulmann <christianulmann at gmail.com>
---
.../Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 8c84e80494e324a..6471f484928765c 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -212,7 +212,7 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
moduleTranslation.lookupFunction(attr.getValue()), operandsRef);
} else {
llvm::FunctionType *calleeType;
- if (callOp.getCalleeType().has_value())
+ if (callOp.getCalleeType())
calleeType = llvm::cast<llvm::FunctionType>(
moduleTranslation.convertType(*callOp.getCalleeType()));
else
>From b042a6b655823dec056356946a9509355b677389 Mon Sep 17 00:00:00 2001
From: "Ivan R. Ivanov" <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 00:04:23 +0900
Subject: [PATCH 14/40] Update mlir/lib/Target/LLVMIR/ModuleImport.cpp
Co-authored-by: Christian Ulmann <christianulmann at gmail.com>
---
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 5e5adb4238c57b2..bd22b93966f58c5 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1435,7 +1435,7 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
} else {
invokeOp = builder.create<InvokeOp>(
- loc, funcTy, /*callee*/ nullptr, operands, directNormalDest,
+ loc, funcTy, /*callee=*/nullptr, operands, directNormalDest,
ValueRange(), lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
}
if (!invokeInst->getType()->isVoidTy())
>From 27a6be457a87d18d042597be67537e13843b6a90 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 23:40:39 +0900
Subject: [PATCH 15/40] Comments
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 7b47e654529cdaf..2fc9bf651a4fb68 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1035,8 +1035,8 @@ static LLVMFunctionType getLLVMFuncType(OpBuilder &builder, TypeRange results,
resultType = LLVMVoidType::get(builder.getContext());
else
resultType = results.front();
- return LLVMFunctionType::get(resultType, llvm::to_vector(args.getTypes()),
- /*isVariadic*/ false);
+ return LLVMFunctionType::get(resultType, args.getTypes(),
+ /*isVariadic=*/false);
}
void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
@@ -1331,7 +1331,7 @@ static ParseResult parseCallTypeAndResolveOperands(
result.addAttribute(
"callee_type",
TypeAttr::get(LLVM::LLVMFunctionType::get(
- returnType, funcType.getInputs(), /*isVarArg*/ false)));
+ returnType, funcType.getInputs(), /*isVarArg=*/false)));
}
return success();
>From 40887da8219612c40639ca7443ce3435d60fd287 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 23:42:11 +0900
Subject: [PATCH 16/40] fix grammar
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 2fc9bf651a4fb68..baaedf018d73b77 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1352,8 +1352,9 @@ static ParseResult parseOptionalCallFuncPtr(
return success();
}
-// <operation> ::= `llvm.call` (function-id | ssa-use) ( `vararg(` var-arg-func-type `)` )?
+// <operation> ::= `llvm.call` (function-id | ssa-use)
// `(` ssa-use-list `)`
+// ( `vararg(` var-arg-func-type `)` )?
// attribute-dict? `:` (type `,`)? function-type
ParseResult CallOp::parse(OpAsmParser &parser, OperationState &result) {
SymbolRefAttr funcAttr;
>From f1223a1ef78f4721303223ae61c00370a0e0de74 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 23:44:27 +0900
Subject: [PATCH 17/40] Fix wrong parseAttrib call
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index baaedf018d73b77..a7aff70d4149549 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1379,10 +1379,8 @@ ParseResult CallOp::parse(OpAsmParser &parser, OperationState &result) {
bool isVarArg = parser.parseOptionalKeyword("vararg").succeeded();
if (isVarArg) {
if (parser.parseLParen().failed() ||
- !parser
- .parseOptionalAttribute(calleeType, "callee_type",
- result.attributes)
- .has_value() ||
+ parser.parseAttribute(calleeType, "callee_type", result.attributes)
+ .failed() ||
parser.parseRParen().failed())
return failure();
}
>From ce9b03c5018b2a9d3ad6f081e5823240f9cdb686 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 23:50:57 +0900
Subject: [PATCH 18/40] Add back to_vector
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index a7aff70d4149549..f2ecc60e9ed2567 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1035,8 +1035,8 @@ static LLVMFunctionType getLLVMFuncType(OpBuilder &builder, TypeRange results,
resultType = LLVMVoidType::get(builder.getContext());
else
resultType = results.front();
- return LLVMFunctionType::get(resultType, args.getTypes(),
- /*isVariadic=*/false);
+ return LLVMFunctionType::get(resultType, llvm::to_vector(args.getTypes()),
+ /*isVarArg=*/false);
}
void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
>From c6c9df000ec3ec50e1ed4e2a3544895c7406524b Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 23:55:33 +0900
Subject: [PATCH 19/40] Do not start error messages with a capital
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index f2ecc60e9ed2567..b07bda223246e14 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1202,7 +1202,7 @@ LogicalResult CallOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
return emitOpError("callee does not have a functional type: ") << fnType;
if (funcType.isVarArg() && !getCalleeType().has_value())
- return emitOpError() << "Missing callee type attribute for vararg call";
+ return emitOpError() << "missing callee type attribute for vararg call";
// Verify that the operand and result types match the callee.
>From 0a6d403b5bacdf9c8371f70304090ee395b55927 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Tue, 26 Sep 2023 23:59:52 +0900
Subject: [PATCH 20/40] Nit
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index b07bda223246e14..4e71d94feb7b6b3 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1473,14 +1473,11 @@ void InvokeOp::print(OpAsmPrinter &p) {
bool isDirect = callee.has_value();
LLVMFunctionType calleeType;
- bool isVarArg;
+ bool isVarArg = false;
- std::optional<LLVMFunctionType> optionalCalleeType = getCalleeType();
- if (optionalCalleeType.has_value()) {
+ if (std::optional<LLVMFunctionType> optionalCalleeType = getCalleeType()) {
calleeType = *optionalCalleeType;
isVarArg = calleeType.isVarArg();
- } else {
- isVarArg = false;
}
p << ' ';
@@ -1544,10 +1541,8 @@ ParseResult InvokeOp::parse(OpAsmParser &parser, OperationState &result) {
bool isVarArg = parser.parseOptionalKeyword("vararg").succeeded();
if (isVarArg) {
if (parser.parseLParen().failed() ||
- !parser
- .parseOptionalAttribute(calleeType, "callee_type",
- result.attributes)
- .has_value() ||
+ parser.parseAttribute(calleeType, "callee_type", result.attributes)
+ .failed() ||
parser.parseRParen().failed())
return failure();
}
>From ad7a9cc4eadadc73d8895ccac48d087d3d9bc243 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 00:01:42 +0900
Subject: [PATCH 21/40] Wrong arg
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 4e71d94feb7b6b3..b90e6e93601d4d4 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1552,7 +1552,7 @@ ParseResult InvokeOp::parse(OpAsmParser &parser, OperationState &result) {
// Parse the trailing type list and resolve the function operands.
if (parseCallTypeAndResolveOperands(parser, result, isDirect, operands,
- /*isVarArg*/ false))
+ isVarArg))
return failure();
result.addSuccessors({normalDest, unwindDest});
>From a964b07824db3deb2f35e95de65f3d8cc78ca1eb Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 00:07:04 +0900
Subject: [PATCH 22/40] invoke grammar
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index b90e6e93601d4d4..df19e24fae5c343 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1512,6 +1512,7 @@ void InvokeOp::print(OpAsmPrinter &p) {
// `(` ssa-use-list `)`
// `to` bb-id (`[` ssa-use-and-type-list `]`)?
// `unwind` bb-id (`[` ssa-use-and-type-list `]`)?
+// ( `vararg(` var-arg-func-type `)` )?
// attribute-dict? `:` (type `,`)? function-type
ParseResult InvokeOp::parse(OpAsmParser &parser, OperationState &result) {
SmallVector<OpAsmParser::UnresolvedOperand, 8> operands;
>From 194d07f63a61de1be669a3bb4cc8c0fd8508e47f Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 00:13:50 +0900
Subject: [PATCH 23/40] Fix LLVM::CallOp description
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index f55a1449fd062f9..42f8ba0d0da6aa2 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -579,9 +579,6 @@ def LLVM_LandingpadOp : LLVM_Op<"landingpad"> {
// CallOp
//===----------------------------------------------------------------------===//
-// FIXME: Add a type attribute that carries the LLVM function type to support
-// indirect calls to variadic functions. The type attribute is necessary to
-// distinguish normal and variadic arguments.
def LLVM_CallOp : LLVM_MemAccessOpBase<"call",
[DeclareOpInterfaceMethods<FastmathFlagsInterface>,
DeclareOpInterfaceMethods<CallOpInterface>,
@@ -597,10 +594,11 @@ def LLVM_CallOp : LLVM_MemAccessOpBase<"call",
The `call` instruction supports both direct and indirect calls. Direct calls
start with a function name (`@`-prefixed) and indirect calls start with an
SSA value (`%`-prefixed). The direct callee, if present, is stored as a
- function attribute `callee`. The trailing type list contains the optional
- indirect callee type and the MLIR function type, which differs from the
- LLVM function type that uses a explicit void type to model functions that do
- not return a value.
+ function attribute `callee`. If the callee is a variadic function, then the
+ `callee_type` attribute must carry the function type. The trailing type list
+ contains the optional indirect callee type and the MLIR function type, which
+ differs from the LLVM function type that uses a explicit void type to model
+ functions that do not return a value.
Examples:
@@ -613,6 +611,12 @@ def LLVM_CallOp : LLVM_MemAccessOpBase<"call",
// Indirect call with an argument and without a result.
llvm.call %1(%0) : !llvm.ptr, (f32) -> ()
+
+ // Direct varaidic call
+ llvm.call @printf(%0, %1) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i32) -> i32
+
+ // Indirect variadic call
+ llvm.call %1(%0) vararg(!llvm.func<void (...)>) : !llvm.ptr, (i32) -> ()
```
}];
>From a75de7db5c4e6e74e94f683ca79d3c611ed04394 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 00:59:47 +0900
Subject: [PATCH 24/40] Test CallOp verifier
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 2 +-
mlir/test/Dialect/LLVMIR/invalid.mlir | 10 ++++++++++
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index df19e24fae5c343..07e152e22217b85 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1201,7 +1201,7 @@ LogicalResult CallOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
if (!funcType)
return emitOpError("callee does not have a functional type: ") << fnType;
- if (funcType.isVarArg() && !getCalleeType().has_value())
+ if (funcType.isVarArg() && !getCalleeType())
return emitOpError() << "missing callee type attribute for vararg call";
// Verify that the operand and result types match the callee.
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index fc959009ff20c81..d5a4e78a2350475 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -1411,3 +1411,13 @@ func.func @invalid_zext_target_type_two(%arg: vector<1xi32>) {
// expected-error at +1 {{input type is a vector but output type is an integer}}
%0 = llvm.zext %arg : vector<1xi32> to i64
}
+
+// -----
+
+llvm.func @variadic(...)
+
+llvm.func @invalid_variadic_call(%arg: i32) {
+ // expected-error at +1 {{missing callee type attribute for vararg call}}
+ "llvm.call"(%arg) <{callee = @variadic}> : (i32) -> ()
+ llvm.return
+}
>From 875932bc9901ce9aa1f9108999595201856e4a4c Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 01:21:35 +0900
Subject: [PATCH 25/40] Add to-llvm test
---
mlir/test/Target/LLVMIR/llvmir.mlir | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index d08f5b2776ee1b7..fd77a7faf4e4bb6 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -1238,7 +1238,14 @@ llvm.func @varargs(...)
// CHECK-LABEL: define void @varargs_call
llvm.func @varargs_call(%arg0 : i32) {
// CHECK: call void (...) @varargs(i32 %{{.*}})
- llvm.call @varargs(%arg0) : (i32) -> ()
+ llvm.call @varargs(%arg0) vararg(!llvm.func<void (...)>) : (i32) -> ()
+ llvm.return
+}
+
+// CHECK-LABEL: define void @indirect_varargs_call(ptr %0, i32 %1)
+llvm.func @indirect_varargs_call(%arg0 : !llvm.ptr, %arg1 : i32) {
+// CHECK: call void (...) %0(i32 %1)
+ llvm.call %arg0(%arg1) vararg(!llvm.func<void (...)>) : !llvm.ptr, (i32) -> ()
llvm.return
}
>From b6978489e26020b65f71cac45304acb84fbde9af Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 11:26:19 +0900
Subject: [PATCH 26/40] Fix printing
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 07e152e22217b85..b68a0f06a53bd1e 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1269,7 +1269,7 @@ void CallOp::print(OpAsmPrinter &p) {
p << '(' << args << ')';
if (isVarArg)
- p << " vararg(" << calleeType << ") ";
+ p << " vararg(" << calleeType << ")";
p.printOptionalAttrDict(processFMFAttr((*this)->getAttrs()),
{"callee", "callee_type"});
@@ -1495,7 +1495,7 @@ void InvokeOp::print(OpAsmPrinter &p) {
p.printSuccessorAndUseList(getUnwindDest(), getUnwindDestOperands());
if (isVarArg)
- p << " vararg(" << calleeType << ") ";
+ p << " vararg(" << calleeType << ")";
p.printOptionalAttrDict(
(*this)->getAttrs(),
>From 608c005c6fed626739d5554c2539bc131d4d3307 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 11:27:49 +0900
Subject: [PATCH 27/40] Fix tests
---
mlir/test/Conversion/GPUToROCDL/gpu-to-rocdl-opencl.mlir | 2 +-
mlir/test/Conversion/GPUToROCDL/typed-pointers.mlir | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/mlir/test/Conversion/GPUToROCDL/gpu-to-rocdl-opencl.mlir b/mlir/test/Conversion/GPUToROCDL/gpu-to-rocdl-opencl.mlir
index dc776051c8aa7aa..68dfb852b88b52e 100644
--- a/mlir/test/Conversion/GPUToROCDL/gpu-to-rocdl-opencl.mlir
+++ b/mlir/test/Conversion/GPUToROCDL/gpu-to-rocdl-opencl.mlir
@@ -8,7 +8,7 @@ gpu.module @test_module {
gpu.func @test_printf(%arg0: i32) {
// CHECK: %[[IMM0:.*]] = llvm.mlir.addressof @[[$PRINT_GLOBAL]] : !llvm.ptr<4>
// CHECK-NEXT: %[[IMM2:.*]] = llvm.getelementptr %[[IMM0]][0, 0] : (!llvm.ptr<4>) -> !llvm.ptr<4>, !llvm.array<11 x i8>
- // CHECK-NEXT: %{{.*}} = llvm.call @printf(%[[IMM2]], %[[ARG0]]) : (!llvm.ptr<4>, i32) -> i32
+ // CHECK-NEXT: %{{.*}} = llvm.call @printf(%[[IMM2]], %[[ARG0]]) vararg(!llvm.func<i32 (ptr<4>, ...)>) : (!llvm.ptr<4>, i32) -> i32
gpu.printf "Hello: %d\n" %arg0 : i32
gpu.return
}
diff --git a/mlir/test/Conversion/GPUToROCDL/typed-pointers.mlir b/mlir/test/Conversion/GPUToROCDL/typed-pointers.mlir
index e6f3ed7f2a5e4bf..004a526790fc513 100644
--- a/mlir/test/Conversion/GPUToROCDL/typed-pointers.mlir
+++ b/mlir/test/Conversion/GPUToROCDL/typed-pointers.mlir
@@ -14,7 +14,7 @@ gpu.module @test_module {
gpu.func @test_printf(%arg0: i32) {
// OCL: %[[IMM0:.*]] = llvm.mlir.addressof @[[$PRINT_GLOBAL]] : !llvm.ptr<array<11 x i8>, 4>
// OCL-NEXT: %[[IMM2:.*]] = llvm.getelementptr %[[IMM0]][0, 0] : (!llvm.ptr<array<11 x i8>, 4>) -> !llvm.ptr<i8, 4>
- // OCL-NEXT: %{{.*}} = llvm.call @printf(%[[IMM2]], %[[ARG0]]) : (!llvm.ptr<i8, 4>, i32) -> i32
+ // OCL-NEXT: %{{.*}} = llvm.call @printf(%[[IMM2]], %[[ARG0]]) vararg(!llvm.func<i32 (ptr<i8, 4>, ...)>) : (!llvm.ptr<i8, 4>, i32) -> i32
// HIP: %[[CST0:.*]] = llvm.mlir.constant(0 : i64) : i64
// HIP-NEXT: %[[DESC0:.*]] = llvm.call @__ockl_printf_begin(%0) : (i64) -> i64
>From 112e26632963697ae1021e3e6e11a04d88364cf6 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 12:54:41 +0900
Subject: [PATCH 28/40] Roundtrip test
---
mlir/test/Dialect/LLVMIR/roundtrip.mlir | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index 558ed3058fe7585..3eb28810c65dffc 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -71,6 +71,14 @@ func.func @ops(%arg0: i32, %arg1: f32,
%20 = llvm.mlir.addressof @foo : !llvm.ptr
%21 = llvm.call %20(%arg0) : !llvm.ptr, (i32) -> !llvm.struct<(i32, f64, i32)>
+// Variadic calls
+// CHECK: llvm.call @variadic(%arg0, %arg0) vararg(!llvm.func<void (i32, ...)>) : (i32, i32) -> ()
+// CHECK: %[[VARIADIC_FUNC:.*]] = llvm.mlir.addressof @variadic : !llvm.ptr
+// CHECK: llvm.call %[[VARIADIC_FUNC]](%[[I32]], %[[I32]]) vararg(!llvm.func<void (i32, ...)>) : !llvm.ptr, (i32, i32) -> ()
+ llvm.call @variadic(%arg0, %arg0) vararg(!llvm.func<void (i32, ...)>) : (i32, i32) -> ()
+ %variadic_func = llvm.mlir.addressof @variadic : !llvm.ptr
+ llvm.call %variadic_func(%arg0, %arg0) vararg(!llvm.func<void (i32, ...)>) : !llvm.ptr, (i32, i32) -> ()
+
// Terminator operations and their successors.
//
// CHECK: llvm.br ^[[BB1:.*]]
@@ -586,3 +594,5 @@ llvm.func @experimental_noalias_scope_decl() {
llvm.intr.experimental.noalias.scope.decl #alias_scope
llvm.return
}
+
+llvm.func @variadic(i32, ...)
>From 805c2f50522b07428f2538ceab07527e866ad448 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 15:38:26 +0900
Subject: [PATCH 29/40] Fix toy example lowering to llvm
---
mlir/examples/toy/Ch6/mlir/LowerToLLVM.cpp | 28 +++++++++++++---------
mlir/examples/toy/Ch7/mlir/LowerToLLVM.cpp | 28 +++++++++++++---------
2 files changed, 34 insertions(+), 22 deletions(-)
diff --git a/mlir/examples/toy/Ch6/mlir/LowerToLLVM.cpp b/mlir/examples/toy/Ch6/mlir/LowerToLLVM.cpp
index a10588e51d9b4f3..4154d018c5537c1 100644
--- a/mlir/examples/toy/Ch6/mlir/LowerToLLVM.cpp
+++ b/mlir/examples/toy/Ch6/mlir/LowerToLLVM.cpp
@@ -61,6 +61,7 @@ class PrintOpLowering : public ConversionPattern {
LogicalResult
matchAndRewrite(Operation *op, ArrayRef<Value> operands,
ConversionPatternRewriter &rewriter) const override {
+ auto context = rewriter.getContext();
auto memRefType = llvm::cast<MemRefType>((*op->operand_type_begin()));
auto memRefShape = memRefType.getShape();
auto loc = op->getLoc();
@@ -92,8 +93,8 @@ class PrintOpLowering : public ConversionPattern {
// Insert a newline after each of the inner dimensions of the shape.
if (i != e - 1)
- rewriter.create<func::CallOp>(loc, printfRef,
- rewriter.getIntegerType(32), newLineCst);
+ rewriter.create<LLVM::CallOp>(loc, getPrintfType(context), printfRef,
+ newLineCst);
rewriter.create<scf::YieldOp>(loc);
rewriter.setInsertionPointToStart(loop.getBody());
}
@@ -102,8 +103,8 @@ class PrintOpLowering : public ConversionPattern {
auto printOp = cast<toy::PrintOp>(op);
auto elementLoad =
rewriter.create<memref::LoadOp>(loc, printOp.getInput(), loopIvs);
- rewriter.create<func::CallOp>(
- loc, printfRef, rewriter.getIntegerType(32),
+ rewriter.create<LLVM::CallOp>(
+ loc, getPrintfType(context), printfRef,
ArrayRef<Value>({formatSpecifierCst, elementLoad}));
// Notify the rewriter that this operation has been removed.
@@ -112,6 +113,16 @@ class PrintOpLowering : public ConversionPattern {
}
private:
+ /// Create a function declaration for printf, the signature is:
+ /// * `i32 (i8*, ...)`
+ static LLVM::LLVMFunctionType getPrintfType(MLIRContext *context) {
+ auto llvmI32Ty = IntegerType::get(context, 32);
+ auto llvmI8PtrTy = LLVM::LLVMPointerType::get(IntegerType::get(context, 8));
+ auto llvmFnType = LLVM::LLVMFunctionType::get(llvmI32Ty, llvmI8PtrTy,
+ /*isVarArg=*/true);
+ return llvmFnType;
+ }
+
/// Return a symbol reference to the printf function, inserting it into the
/// module if necessary.
static FlatSymbolRefAttr getOrInsertPrintf(PatternRewriter &rewriter,
@@ -120,17 +131,12 @@ class PrintOpLowering : public ConversionPattern {
if (module.lookupSymbol<LLVM::LLVMFuncOp>("printf"))
return SymbolRefAttr::get(context, "printf");
- // Create a function declaration for printf, the signature is:
- // * `i32 (i8*, ...)`
- auto llvmI32Ty = IntegerType::get(context, 32);
- auto llvmI8PtrTy = LLVM::LLVMPointerType::get(IntegerType::get(context, 8));
- auto llvmFnType = LLVM::LLVMFunctionType::get(llvmI32Ty, llvmI8PtrTy,
- /*isVarArg=*/true);
// Insert the printf function into the body of the parent module.
PatternRewriter::InsertionGuard insertGuard(rewriter);
rewriter.setInsertionPointToStart(module.getBody());
- rewriter.create<LLVM::LLVMFuncOp>(module.getLoc(), "printf", llvmFnType);
+ rewriter.create<LLVM::LLVMFuncOp>(module.getLoc(), "printf",
+ getPrintfType(context));
return SymbolRefAttr::get(context, "printf");
}
diff --git a/mlir/examples/toy/Ch7/mlir/LowerToLLVM.cpp b/mlir/examples/toy/Ch7/mlir/LowerToLLVM.cpp
index a10588e51d9b4f3..4154d018c5537c1 100644
--- a/mlir/examples/toy/Ch7/mlir/LowerToLLVM.cpp
+++ b/mlir/examples/toy/Ch7/mlir/LowerToLLVM.cpp
@@ -61,6 +61,7 @@ class PrintOpLowering : public ConversionPattern {
LogicalResult
matchAndRewrite(Operation *op, ArrayRef<Value> operands,
ConversionPatternRewriter &rewriter) const override {
+ auto context = rewriter.getContext();
auto memRefType = llvm::cast<MemRefType>((*op->operand_type_begin()));
auto memRefShape = memRefType.getShape();
auto loc = op->getLoc();
@@ -92,8 +93,8 @@ class PrintOpLowering : public ConversionPattern {
// Insert a newline after each of the inner dimensions of the shape.
if (i != e - 1)
- rewriter.create<func::CallOp>(loc, printfRef,
- rewriter.getIntegerType(32), newLineCst);
+ rewriter.create<LLVM::CallOp>(loc, getPrintfType(context), printfRef,
+ newLineCst);
rewriter.create<scf::YieldOp>(loc);
rewriter.setInsertionPointToStart(loop.getBody());
}
@@ -102,8 +103,8 @@ class PrintOpLowering : public ConversionPattern {
auto printOp = cast<toy::PrintOp>(op);
auto elementLoad =
rewriter.create<memref::LoadOp>(loc, printOp.getInput(), loopIvs);
- rewriter.create<func::CallOp>(
- loc, printfRef, rewriter.getIntegerType(32),
+ rewriter.create<LLVM::CallOp>(
+ loc, getPrintfType(context), printfRef,
ArrayRef<Value>({formatSpecifierCst, elementLoad}));
// Notify the rewriter that this operation has been removed.
@@ -112,6 +113,16 @@ class PrintOpLowering : public ConversionPattern {
}
private:
+ /// Create a function declaration for printf, the signature is:
+ /// * `i32 (i8*, ...)`
+ static LLVM::LLVMFunctionType getPrintfType(MLIRContext *context) {
+ auto llvmI32Ty = IntegerType::get(context, 32);
+ auto llvmI8PtrTy = LLVM::LLVMPointerType::get(IntegerType::get(context, 8));
+ auto llvmFnType = LLVM::LLVMFunctionType::get(llvmI32Ty, llvmI8PtrTy,
+ /*isVarArg=*/true);
+ return llvmFnType;
+ }
+
/// Return a symbol reference to the printf function, inserting it into the
/// module if necessary.
static FlatSymbolRefAttr getOrInsertPrintf(PatternRewriter &rewriter,
@@ -120,17 +131,12 @@ class PrintOpLowering : public ConversionPattern {
if (module.lookupSymbol<LLVM::LLVMFuncOp>("printf"))
return SymbolRefAttr::get(context, "printf");
- // Create a function declaration for printf, the signature is:
- // * `i32 (i8*, ...)`
- auto llvmI32Ty = IntegerType::get(context, 32);
- auto llvmI8PtrTy = LLVM::LLVMPointerType::get(IntegerType::get(context, 8));
- auto llvmFnType = LLVM::LLVMFunctionType::get(llvmI32Ty, llvmI8PtrTy,
- /*isVarArg=*/true);
// Insert the printf function into the body of the parent module.
PatternRewriter::InsertionGuard insertGuard(rewriter);
rewriter.setInsertionPointToStart(module.getBody());
- rewriter.create<LLVM::LLVMFuncOp>(module.getLoc(), "printf", llvmFnType);
+ rewriter.create<LLVM::LLVMFuncOp>(module.getLoc(), "printf",
+ getPrintfType(context));
return SymbolRefAttr::get(context, "printf");
}
>From 99f3cbbfd4e8e39a1962fcc81679cdc599e81826 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 16:02:29 +0900
Subject: [PATCH 30/40] Fix formatting
---
mlir/examples/toy/Ch6/mlir/LowerToLLVM.cpp | 1 -
mlir/examples/toy/Ch7/mlir/LowerToLLVM.cpp | 1 -
2 files changed, 2 deletions(-)
diff --git a/mlir/examples/toy/Ch6/mlir/LowerToLLVM.cpp b/mlir/examples/toy/Ch6/mlir/LowerToLLVM.cpp
index 4154d018c5537c1..684ce37b2398ce2 100644
--- a/mlir/examples/toy/Ch6/mlir/LowerToLLVM.cpp
+++ b/mlir/examples/toy/Ch6/mlir/LowerToLLVM.cpp
@@ -131,7 +131,6 @@ class PrintOpLowering : public ConversionPattern {
if (module.lookupSymbol<LLVM::LLVMFuncOp>("printf"))
return SymbolRefAttr::get(context, "printf");
-
// Insert the printf function into the body of the parent module.
PatternRewriter::InsertionGuard insertGuard(rewriter);
rewriter.setInsertionPointToStart(module.getBody());
diff --git a/mlir/examples/toy/Ch7/mlir/LowerToLLVM.cpp b/mlir/examples/toy/Ch7/mlir/LowerToLLVM.cpp
index 4154d018c5537c1..684ce37b2398ce2 100644
--- a/mlir/examples/toy/Ch7/mlir/LowerToLLVM.cpp
+++ b/mlir/examples/toy/Ch7/mlir/LowerToLLVM.cpp
@@ -131,7 +131,6 @@ class PrintOpLowering : public ConversionPattern {
if (module.lookupSymbol<LLVM::LLVMFuncOp>("printf"))
return SymbolRefAttr::get(context, "printf");
-
// Insert the printf function into the body of the parent module.
PatternRewriter::InsertionGuard insertGuard(rewriter);
rewriter.setInsertionPointToStart(module.getBody());
>From a13f136b144e38ac4b42ead9f8c5d6619ea24028 Mon Sep 17 00:00:00 2001
From: "Ivan R. Ivanov" <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 16:20:43 +0900
Subject: [PATCH 31/40] Apply suggestions from code review
Co-authored-by: Tobias Gysi <tobias.gysi at nextsilicon.com>
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 2 +-
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 4 ++--
.../Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 42f8ba0d0da6aa2..b935eadfb218290 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -612,7 +612,7 @@ def LLVM_CallOp : LLVM_MemAccessOpBase<"call",
// Indirect call with an argument and without a result.
llvm.call %1(%0) : !llvm.ptr, (f32) -> ()
- // Direct varaidic call
+ // Direct variadic call.
llvm.call @printf(%0, %1) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i32) -> i32
// Indirect variadic call
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index b68a0f06a53bd1e..68b2326a547d05f 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1018,7 +1018,7 @@ static void printStoreType(OpAsmPrinter &printer, Operation *op,
// CallOp
//===----------------------------------------------------------------------===//
-/// Get the MLIR Op-like result types of a LLVMFunctionType
+/// Gets the MLIR Op-like result types of a LLVMFunctionType.
static SmallVector<Type, 1> getCallOpResults(LLVMFunctionType calleeType) {
SmallVector<Type, 1> results;
Type resultType = calleeType.getReturnType();
@@ -1027,7 +1027,7 @@ static SmallVector<Type, 1> getCallOpResults(LLVMFunctionType calleeType) {
return results;
}
-/// Construct a LLVMFunctionType from MLIR results and args
+/// Constructs a LLVMFunctionType from MLIR `results` and `args`.
static LLVMFunctionType getLLVMFuncType(OpBuilder &builder, TypeRange results,
ValueRange args) {
Type resultType;
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 6471f484928765c..913ee70a4cee06a 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -304,7 +304,7 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
moduleTranslation.lookupBlock(invOp.getSuccessor(1)), operandsRef);
} else {
llvm::FunctionType *calleeType;
- if (invOp.getCalleeType().has_value())
+ if (invOp.getCalleeType())
calleeType = llvm::cast<llvm::FunctionType>(
moduleTranslation.convertType(*invOp.getCalleeType()));
else
>From 283c86bbdc9448bd03d64cf89cc4556cc78b4a0b Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 16:23:29 +0900
Subject: [PATCH 32/40] Rename getCallOpResults -> getCallOpResultTypes
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 68b2326a547d05f..f16f44449af4f8f 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1019,7 +1019,7 @@ static void printStoreType(OpAsmPrinter &printer, Operation *op,
//===----------------------------------------------------------------------===//
/// Gets the MLIR Op-like result types of a LLVMFunctionType.
-static SmallVector<Type, 1> getCallOpResults(LLVMFunctionType calleeType) {
+static SmallVector<Type, 1> getCallOpResultTypes(LLVMFunctionType calleeType) {
SmallVector<Type, 1> results;
Type resultType = calleeType.getReturnType();
if (!isa<LLVM::LLVMVoidType>(resultType))
@@ -1074,7 +1074,7 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
void CallOp::build(OpBuilder &builder, OperationState &state,
LLVMFunctionType calleeType, FlatSymbolRefAttr callee,
ValueRange args) {
- build(builder, state, getCallOpResults(calleeType), TypeAttr::get(calleeType),
+ build(builder, state, getCallOpResultTypes(calleeType), TypeAttr::get(calleeType),
callee, args, /*fastmathFlags=*/nullptr,
/*branch_weights=*/nullptr,
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
@@ -1083,7 +1083,7 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
void CallOp::build(OpBuilder &builder, OperationState &state,
LLVMFunctionType calleeType, ValueRange args) {
- build(builder, state, getCallOpResults(calleeType), TypeAttr::get(calleeType),
+ build(builder, state, getCallOpResultTypes(calleeType), TypeAttr::get(calleeType),
/*callee=*/nullptr, args,
/*fastmathFlags=*/nullptr,
/*branch_weights=*/nullptr,
@@ -1094,7 +1094,7 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
void CallOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
ValueRange args) {
auto calleeType = func.getFunctionType();
- build(builder, state, getCallOpResults(calleeType), TypeAttr::get(calleeType),
+ build(builder, state, getCallOpResultTypes(calleeType), TypeAttr::get(calleeType),
SymbolRefAttr::get(func), args,
/*fastmathFlags=*/nullptr,
/*branch_weights=*/nullptr,
@@ -1398,7 +1398,7 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
ValueRange ops, Block *normal, ValueRange normalOps,
Block *unwind, ValueRange unwindOps) {
auto calleeType = func.getFunctionType();
- build(builder, state, getCallOpResults(calleeType), TypeAttr::get(calleeType),
+ build(builder, state, getCallOpResultTypes(calleeType), TypeAttr::get(calleeType),
SymbolRefAttr::get(func), ops, normalOps, unwindOps, nullptr, normal,
unwind);
}
@@ -1415,7 +1415,7 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state,
LLVMFunctionType calleeType, FlatSymbolRefAttr callee,
ValueRange ops, Block *normal, ValueRange normalOps,
Block *unwind, ValueRange unwindOps) {
- build(builder, state, getCallOpResults(calleeType), TypeAttr::get(calleeType),
+ build(builder, state, getCallOpResultTypes(calleeType), TypeAttr::get(calleeType),
callee, ops, normalOps, unwindOps, nullptr, normal, unwind);
}
>From d1fbeb143711df05e85d05070e7ad25c826c1a7f Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 16:49:21 +0900
Subject: [PATCH 33/40] Do not set the calle type attrib if not variadic
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 20 +++-----------------
1 file changed, 3 insertions(+), 17 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index f16f44449af4f8f..14ae891e177082c 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1286,7 +1286,7 @@ void CallOp::print(OpAsmPrinter &p) {
/// succeeds. Returns failure otherwise.
static ParseResult parseCallTypeAndResolveOperands(
OpAsmParser &parser, OperationState &result, bool isDirect,
- ArrayRef<OpAsmParser::UnresolvedOperand> operands, bool isVarArg) {
+ ArrayRef<OpAsmParser::UnresolvedOperand> operands) {
SMLoc trailingTypesLoc = parser.getCurrentLocation();
SmallVector<Type> types;
if (parser.parseColonTypeList(types))
@@ -1322,18 +1322,6 @@ static ParseResult parseCallTypeAndResolveOperands(
if (funcType.getNumResults() != 0)
result.addTypes(funcType.getResults());
- if (!isVarArg) {
- Type returnType;
- if (funcType.getNumResults() == 0)
- returnType = LLVM::LLVMVoidType::get(result.getContext());
- else
- returnType = funcType.getResult(0);
- result.addAttribute(
- "callee_type",
- TypeAttr::get(LLVM::LLVMFunctionType::get(
- returnType, funcType.getInputs(), /*isVarArg=*/false)));
- }
-
return success();
}
@@ -1386,8 +1374,7 @@ ParseResult CallOp::parse(OpAsmParser &parser, OperationState &result) {
}
// Parse the trailing type list and resolve the operands.
- return parseCallTypeAndResolveOperands(parser, result, isDirect, operands,
- isVarArg);
+ return parseCallTypeAndResolveOperands(parser, result, isDirect, operands);
}
///===---------------------------------------------------------------------===//
@@ -1552,8 +1539,7 @@ ParseResult InvokeOp::parse(OpAsmParser &parser, OperationState &result) {
return failure();
// Parse the trailing type list and resolve the function operands.
- if (parseCallTypeAndResolveOperands(parser, result, isDirect, operands,
- isVarArg))
+ if (parseCallTypeAndResolveOperands(parser, result, isDirect, operands))
return failure();
result.addSuccessors({normalDest, unwindDest});
>From e8fec7bfc269dad790b7a33791a39f9ed4d7fa49 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 16:57:25 +0900
Subject: [PATCH 34/40] Fix tests
---
mlir/test/Target/LLVMIR/openmp-nested.mlir | 2 +-
mlir/test/mlir-cpu-runner/x86-varargs.mlir | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/mlir/test/Target/LLVMIR/openmp-nested.mlir b/mlir/test/Target/LLVMIR/openmp-nested.mlir
index 5e047d5a58d288e..4a96746cbbc9137 100644
--- a/mlir/test/Target/LLVMIR/openmp-nested.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-nested.mlir
@@ -23,7 +23,7 @@ module {
%20 = llvm.trunc %19 : i64 to i32
%5 = llvm.mlir.addressof @str0 : !llvm.ptr<array<29 x i8>>
%6 = llvm.getelementptr %5[%4, %4] : (!llvm.ptr<array<29 x i8>>, i32, i32) -> !llvm.ptr<i8>
- %21 = llvm.call @printf(%6, %20, %20) : (!llvm.ptr<i8>, i32, i32) -> i32
+ %21 = llvm.call @printf(%6, %20, %20) vararg(!llvm.func<i32 (ptr<i8>, ...)>): (!llvm.ptr<i8>, i32, i32) -> i32
omp.yield
}
omp.terminator
diff --git a/mlir/test/mlir-cpu-runner/x86-varargs.mlir b/mlir/test/mlir-cpu-runner/x86-varargs.mlir
index 44024113c2b7b68..f3f4322ce87975e 100644
--- a/mlir/test/mlir-cpu-runner/x86-varargs.mlir
+++ b/mlir/test/mlir-cpu-runner/x86-varargs.mlir
@@ -10,7 +10,7 @@ llvm.func @caller() -> i32 {
%0 = llvm.mlir.constant(3 : i32) : i32
%1 = llvm.mlir.constant(2 : i32) : i32
%2 = llvm.mlir.constant(1 : i32) : i32
- %3 = llvm.call @foo(%2, %1, %0) : (i32, i32, i32) -> i32
+ %3 = llvm.call @foo(%2, %1, %0) vararg(!llvm.func<i32 (i32, ...)>) : (i32, i32, i32) -> i32
llvm.return %3 : i32
}
>From 6af94f347b21086a2c32609fb9de271eb9450db3 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 17:26:53 +0900
Subject: [PATCH 35/40] Invoke tests
---
mlir/test/Dialect/LLVMIR/invalid.mlir | 10 +++++++++
mlir/test/Dialect/LLVMIR/roundtrip.mlir | 27 ++++++++++++++++++-------
2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index d5a4e78a2350475..644111277d7d8d6 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -1421,3 +1421,13 @@ llvm.func @invalid_variadic_call(%arg: i32) {
"llvm.call"(%arg) <{callee = @variadic}> : (i32) -> ()
llvm.return
}
+
+// -----
+
+llvm.func @variadic(...)
+
+llvm.func @invalid_variadic_call(%arg: i32) {
+ // expected-error at +1 {{missing callee type attribute for vararg call}}
+ "llvm.call"(%arg) <{callee = @variadic}> : (i32) -> ()
+ llvm.return
+}
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index 3eb28810c65dffc..ddcae938f16423f 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -72,11 +72,11 @@ func.func @ops(%arg0: i32, %arg1: f32,
%21 = llvm.call %20(%arg0) : !llvm.ptr, (i32) -> !llvm.struct<(i32, f64, i32)>
// Variadic calls
-// CHECK: llvm.call @variadic(%arg0, %arg0) vararg(!llvm.func<void (i32, ...)>) : (i32, i32) -> ()
-// CHECK: %[[VARIADIC_FUNC:.*]] = llvm.mlir.addressof @variadic : !llvm.ptr
+// CHECK: llvm.call @vararg_func(%arg0, %arg0) vararg(!llvm.func<void (i32, ...)>) : (i32, i32) -> ()
+// CHECK: %[[VARIADIC_FUNC:.*]] = llvm.mlir.addressof @vararg_func : !llvm.ptr
// CHECK: llvm.call %[[VARIADIC_FUNC]](%[[I32]], %[[I32]]) vararg(!llvm.func<void (i32, ...)>) : !llvm.ptr, (i32, i32) -> ()
- llvm.call @variadic(%arg0, %arg0) vararg(!llvm.func<void (i32, ...)>) : (i32, i32) -> ()
- %variadic_func = llvm.mlir.addressof @variadic : !llvm.ptr
+ llvm.call @vararg_func(%arg0, %arg0) vararg(!llvm.func<void (i32, ...)>) : (i32, i32) -> ()
+ %variadic_func = llvm.mlir.addressof @vararg_func : !llvm.ptr
llvm.call %variadic_func(%arg0, %arg0) vararg(!llvm.func<void (i32, ...)>) : !llvm.ptr, (i32, i32) -> ()
// Terminator operations and their successors.
@@ -191,6 +191,8 @@ llvm.func @gep(%ptr: !llvm.ptr, %idx: i64, %ptr2: !llvm.ptr) {
llvm.return
}
+llvm.func @vararg_foo(i32, ...) -> !llvm.struct<(i32, f64, i32)>
+
// An larger self-contained function.
// CHECK-LABEL: llvm.func @foo(%{{.*}}: i32) -> !llvm.struct<(i32, f64, i32)> {
llvm.func @foo(%arg0: i32) -> !llvm.struct<(i32, f64, i32)> {
@@ -435,8 +437,21 @@ llvm.func @invokeLandingpad() -> i32 attributes { personality = @__gxx_personali
%13 = llvm.invoke %12(%5) to ^bb2 unwind ^bb1 : !llvm.ptr, (i32) -> !llvm.struct<(i32, f64, i32)>
// CHECK: ^[[BB5:.*]]:
-// CHECK: llvm.return %[[V0]] : i32
+// CHECK: %{{.*}} = llvm.invoke @{{.*}} vararg(!llvm.func<struct<(i32, f64, i32)> (i32, ...)>) : (i32, i32) -> !llvm.struct<(i32, f64, i32)>
+
^bb5:
+ %14 = llvm.invoke @vararg_foo(%5, %5) to ^bb2 unwind ^bb1 vararg(!llvm.func<struct<(i32, f64, i32)> (i32, ...)>) : (i32, i32) -> !llvm.struct<(i32, f64, i32)>
+
+// CHECK: ^[[BB6:.*]]:
+// CHECK: %[[FUNCV:.*]] = llvm.mlir.addressof @vararg_foo : !llvm.ptr
+// CHECK: %{{.*}} = llvm.invoke %[[FUNCV]]{{.*}} vararg(!llvm.func<struct<(i32, f64, i32)> (i32, ...)>) : !llvm.ptr, (i32, i32) -> !llvm.struct<(i32, f64, i32)>
+^bb6:
+ %15 = llvm.mlir.addressof @vararg_foo : !llvm.ptr
+ %16 = llvm.invoke %15(%5, %5) to ^bb2 unwind ^bb1 vararg(!llvm.func<!llvm.struct<(i32, f64, i32)> (i32, ...)>) : !llvm.ptr, (i32, i32) -> !llvm.struct<(i32, f64, i32)>
+
+// CHECK: ^[[BB7:.*]]:
+// CHECK: llvm.return %[[V0]] : i32
+^bb7:
llvm.return %0 : i32
}
@@ -594,5 +609,3 @@ llvm.func @experimental_noalias_scope_decl() {
llvm.intr.experimental.noalias.scope.decl #alias_scope
llvm.return
}
-
-llvm.func @variadic(i32, ...)
>From 6f4217bbf85dcd7952d960cb8d28c38eb0d76908 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 17:31:35 +0900
Subject: [PATCH 36/40] Invoke translation test
---
mlir/test/Target/LLVMIR/llvmir.mlir | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index fd77a7faf4e4bb6..07fdb5361df5ce6 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -1533,6 +1533,7 @@ llvm.func @cmpxchg(%ptr : !llvm.ptr<i32>, %cmp : i32, %val: i32) {
llvm.mlir.global external constant @_ZTIi() : !llvm.ptr<i8>
llvm.func @foo(!llvm.ptr<i8>)
+llvm.func @vararg_foo(!llvm.ptr<i8>, ...)
llvm.func @bar(!llvm.ptr<i8>) -> !llvm.ptr<i8>
llvm.func @__gxx_personality_v0(...) -> i32
@@ -1570,6 +1571,19 @@ llvm.func @invokeLandingpad() -> i32 attributes { personality = @__gxx_personali
// CHECK-NEXT: to label %[[normal]] unwind label %[[unwind]]
^bb3: // pred: ^bb1
%8 = llvm.invoke @bar(%6) to ^bb2 unwind ^bb1 : (!llvm.ptr<i8>) -> !llvm.ptr<i8>
+
+// CHECK: [[BB4:.*]]:
+// CHECK: invoke void (ptr, ...) @vararg_foo(ptr %[[a1]], i32 0)
+// CHECK-NEXT: to label %[[normal:[0-9]+]] unwind label %[[unwind:[0-9]+]]
+^bb4:
+ llvm.invoke @vararg_foo(%6, %0) to ^bb2 unwind ^bb1 vararg(!llvm.func<void (ptr<i8>, ...)>) : (!llvm.ptr<i8>, i32) -> ()
+
+// CHECK: [[BB5:.*]]:
+// CHECK: invoke void (ptr, ...) undef(ptr %[[a1]], i32 0)
+// CHECK-NEXT: to label %[[normal:[0-9]+]] unwind label %[[unwind:[0-9]+]]
+^bb5:
+ %9 = llvm.mlir.undef : !llvm.ptr
+ llvm.invoke %9(%6, %0) to ^bb2 unwind ^bb1 vararg(!llvm.func<void (ptr<i8>, ...)>) : !llvm.ptr, (!llvm.ptr<i8>, i32) -> ()
}
// -----
>From 639f4da89040fd5f6a8bbe8579dc1285ba36ebb1 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 17:38:41 +0900
Subject: [PATCH 37/40] Add import invoke test
---
mlir/test/Target/LLVMIR/Import/exception.ll | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/mlir/test/Target/LLVMIR/Import/exception.ll b/mlir/test/Target/LLVMIR/Import/exception.ll
index 944e5de6badd9d7..e688cc258ebce32 100644
--- a/mlir/test/Target/LLVMIR/Import/exception.ll
+++ b/mlir/test/Target/LLVMIR/Import/exception.ll
@@ -3,6 +3,7 @@
@_ZTIi = external dso_local constant ptr
@_ZTIii= external dso_local constant ptr
declare void @foo(ptr)
+declare void @vararg_foo(ptr, ...)
declare ptr @bar(ptr)
declare i32 @__gxx_personality_v0(...)
@@ -29,6 +30,14 @@ define i32 @invokeLandingpad() personality ptr @__gxx_personality_v0 {
%6 = invoke ptr @bar(ptr %1) to label %4 unwind label %2
; CHECK: ^bb4:
+ ; CHECK: llvm.invoke @vararg_foo(%[[a3]], %{{.*}}) to ^bb2 unwind ^bb1 vararg(!llvm.func<void (ptr, ...)>) : (!llvm.ptr, i32) -> ()
+ invoke void (ptr, ...) @vararg_foo(ptr %1, i32 0) to label %4 unwind label %2
+
+; CHECK: ^bb5:
+ ; CHECK: llvm.invoke %{{.*}}(%[[a3]], %{{.*}}) to ^bb2 unwind ^bb1 vararg(!llvm.func<void (ptr, ...)>) : !llvm.ptr, (!llvm.ptr, i32) -> ()
+ invoke void (ptr, ...) undef(ptr %1, i32 0) to label %4 unwind label %2
+
+; CHECK: ^bb6:
; CHECK: llvm.return %{{[0-9]+}} : i32
ret i32 0
}
>From 6b6af0da1a7b534028258ece923774df42234e9e Mon Sep 17 00:00:00 2001
From: "Ivan R. Ivanov" <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 20:58:00 +0900
Subject: [PATCH 38/40] Apply suggestions from code review
Co-authored-by: Tobias Gysi <tobias.gysi at nextsilicon.com>
---
mlir/test/Target/LLVMIR/llvmir.mlir | 2 --
1 file changed, 2 deletions(-)
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 07fdb5361df5ce6..81ffba6a358f9c7 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -1574,13 +1574,11 @@ llvm.func @invokeLandingpad() -> i32 attributes { personality = @__gxx_personali
// CHECK: [[BB4:.*]]:
// CHECK: invoke void (ptr, ...) @vararg_foo(ptr %[[a1]], i32 0)
-// CHECK-NEXT: to label %[[normal:[0-9]+]] unwind label %[[unwind:[0-9]+]]
^bb4:
llvm.invoke @vararg_foo(%6, %0) to ^bb2 unwind ^bb1 vararg(!llvm.func<void (ptr<i8>, ...)>) : (!llvm.ptr<i8>, i32) -> ()
// CHECK: [[BB5:.*]]:
// CHECK: invoke void (ptr, ...) undef(ptr %[[a1]], i32 0)
-// CHECK-NEXT: to label %[[normal:[0-9]+]] unwind label %[[unwind:[0-9]+]]
^bb5:
%9 = llvm.mlir.undef : !llvm.ptr
llvm.invoke %9(%6, %0) to ^bb2 unwind ^bb1 vararg(!llvm.func<void (ptr<i8>, ...)>) : !llvm.ptr, (!llvm.ptr<i8>, i32) -> ()
>From 9f2ee3b4660a2c22460b498bceb1cf9049cef4e8 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 20:59:35 +0900
Subject: [PATCH 39/40] FUNCV -> FUNC
---
mlir/test/Dialect/LLVMIR/roundtrip.mlir | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index ddcae938f16423f..8cc47df1ac40dae 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -443,8 +443,8 @@ llvm.func @invokeLandingpad() -> i32 attributes { personality = @__gxx_personali
%14 = llvm.invoke @vararg_foo(%5, %5) to ^bb2 unwind ^bb1 vararg(!llvm.func<struct<(i32, f64, i32)> (i32, ...)>) : (i32, i32) -> !llvm.struct<(i32, f64, i32)>
// CHECK: ^[[BB6:.*]]:
-// CHECK: %[[FUNCV:.*]] = llvm.mlir.addressof @vararg_foo : !llvm.ptr
-// CHECK: %{{.*}} = llvm.invoke %[[FUNCV]]{{.*}} vararg(!llvm.func<struct<(i32, f64, i32)> (i32, ...)>) : !llvm.ptr, (i32, i32) -> !llvm.struct<(i32, f64, i32)>
+// CHECK: %[[FUNC:.*]] = llvm.mlir.addressof @vararg_foo : !llvm.ptr
+// CHECK: %{{.*}} = llvm.invoke %[[FUNC]]{{.*}} vararg(!llvm.func<struct<(i32, f64, i32)> (i32, ...)>) : !llvm.ptr, (i32, i32) -> !llvm.struct<(i32, f64, i32)>
^bb6:
%15 = llvm.mlir.addressof @vararg_foo : !llvm.ptr
%16 = llvm.invoke %15(%5, %5) to ^bb2 unwind ^bb1 vararg(!llvm.func<!llvm.struct<(i32, f64, i32)> (i32, ...)>) : !llvm.ptr, (i32, i32) -> !llvm.struct<(i32, f64, i32)>
>From 580d2dba5a9f85933fb32ba12d7e24281fe2b278 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Wed, 27 Sep 2023 21:02:43 +0900
Subject: [PATCH 40/40] clang-format
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 14ae891e177082c..eff960eff614d45 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1074,8 +1074,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
void CallOp::build(OpBuilder &builder, OperationState &state,
LLVMFunctionType calleeType, FlatSymbolRefAttr callee,
ValueRange args) {
- build(builder, state, getCallOpResultTypes(calleeType), TypeAttr::get(calleeType),
- callee, args, /*fastmathFlags=*/nullptr,
+ build(builder, state, getCallOpResultTypes(calleeType),
+ TypeAttr::get(calleeType), callee, args, /*fastmathFlags=*/nullptr,
/*branch_weights=*/nullptr,
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
/*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
@@ -1083,7 +1083,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
void CallOp::build(OpBuilder &builder, OperationState &state,
LLVMFunctionType calleeType, ValueRange args) {
- build(builder, state, getCallOpResultTypes(calleeType), TypeAttr::get(calleeType),
+ build(builder, state, getCallOpResultTypes(calleeType),
+ TypeAttr::get(calleeType),
/*callee=*/nullptr, args,
/*fastmathFlags=*/nullptr,
/*branch_weights=*/nullptr,
@@ -1094,8 +1095,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
void CallOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
ValueRange args) {
auto calleeType = func.getFunctionType();
- build(builder, state, getCallOpResultTypes(calleeType), TypeAttr::get(calleeType),
- SymbolRefAttr::get(func), args,
+ build(builder, state, getCallOpResultTypes(calleeType),
+ TypeAttr::get(calleeType), SymbolRefAttr::get(func), args,
/*fastmathFlags=*/nullptr,
/*branch_weights=*/nullptr,
/*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
@@ -1385,9 +1386,9 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
ValueRange ops, Block *normal, ValueRange normalOps,
Block *unwind, ValueRange unwindOps) {
auto calleeType = func.getFunctionType();
- build(builder, state, getCallOpResultTypes(calleeType), TypeAttr::get(calleeType),
- SymbolRefAttr::get(func), ops, normalOps, unwindOps, nullptr, normal,
- unwind);
+ build(builder, state, getCallOpResultTypes(calleeType),
+ TypeAttr::get(calleeType), SymbolRefAttr::get(func), ops, normalOps,
+ unwindOps, nullptr, normal, unwind);
}
void InvokeOp::build(OpBuilder &builder, OperationState &state, TypeRange tys,
@@ -1402,8 +1403,9 @@ void InvokeOp::build(OpBuilder &builder, OperationState &state,
LLVMFunctionType calleeType, FlatSymbolRefAttr callee,
ValueRange ops, Block *normal, ValueRange normalOps,
Block *unwind, ValueRange unwindOps) {
- build(builder, state, getCallOpResultTypes(calleeType), TypeAttr::get(calleeType),
- callee, ops, normalOps, unwindOps, nullptr, normal, unwind);
+ build(builder, state, getCallOpResultTypes(calleeType),
+ TypeAttr::get(calleeType), callee, ops, normalOps, unwindOps, nullptr,
+ normal, unwind);
}
SuccessorOperands InvokeOp::getSuccessorOperands(unsigned index) {
More information about the Mlir-commits
mailing list