-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[MLIR][LLVMIR] llvm.call_intrinsic: support operand/result attributes #129640
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MLIR][LLVMIR] llvm.call_intrinsic: support operand/result attributes #129640
Conversation
…lyFormat This is in prep for adding operand and result atritbues to llvm.call_intrinsic, in the same fashion as llvm.call. While here, reuse `parseCallTypeAndResolveOperands` and `call_interface_impl::printFunctionSignature`. There's more that can be refactored once the order of attribute and call type are flipped to match llvm.call.
Basically catch up with llvm.call. - Similar approach to llvm.call. - Add support for translate and import to LLVM IR.
@llvm/pr-subscribers-mlir @llvm/pr-subscribers-mlir-llvm Author: Bruno Cardoso Lopes (bcardosolopes) ChangesBasically catch up with llvm.call and add support for translate and import to LLVM IR. This PR is split into two commits in case it's easier to review the refactoring part, which comes first (happy to split the PR if necessary). Full diff: https://github.com/llvm/llvm-project/pull/129640.diff 10 Files Affected:
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index eed3b2cdb91ea..121cf53393f15 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -2107,18 +2107,14 @@ def LLVM_CallIntrinsicOp
VariadicOfVariadic<LLVM_Type,
"op_bundle_sizes">:$op_bundle_operands,
DenseI32ArrayAttr:$op_bundle_sizes,
- OptionalAttr<ArrayAttr>:$op_bundle_tags);
+ OptionalAttr<ArrayAttr>:$op_bundle_tags,
+ OptionalAttr<DictArrayAttr>:$arg_attrs,
+ OptionalAttr<DictArrayAttr>:$res_attrs);
let results = (outs Optional<LLVM_Type>:$results);
let llvmBuilder = [{
return convertCallLLVMIntrinsicOp(op, builder, moduleTranslation);
}];
- let assemblyFormat = [{
- $intrin `(` $args `)`
- ( custom<OpBundles>($op_bundle_operands, type($op_bundle_operands),
- $op_bundle_tags)^ )?
- `:` functional-type($args, $results)
- attr-dict
- }];
+ let hasCustomAssemblyFormat = 1;
let builders = [
OpBuilder<(ins "StringAttr":$intrin, "ValueRange":$args)>,
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
index 6c673295d8dcc..de1692982a310 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
@@ -272,6 +272,11 @@ class ModuleImport {
SmallVectorImpl<Value> &valuesOut,
SmallVectorImpl<NamedAttribute> &attrsOut);
+ /// Converts the parameter and result attributes attached to `call` and adds
+ /// them to the `callOp`.
+ void convertParameterAttributes(llvm::CallBase *call, ArrayAttr &argsAttr,
+ ArrayAttr &resAttr, OpBuilder &builder);
+
private:
/// Clears the accumulated state before processing a new region.
void clearRegionState() {
@@ -350,7 +355,8 @@ class ModuleImport {
DictionaryAttr convertParameterAttribute(llvm::AttributeSet llvmParamAttrs,
OpBuilder &builder);
/// Converts the parameter and result attributes attached to `call` and adds
- /// them to the `callOp`.
+ /// them to the `callOp`. Implemented in terms of the other definition of
+ /// the public definition of convertParameterAttributes.
void convertParameterAttributes(llvm::CallBase *call, CallOpInterface callOp,
OpBuilder &builder);
/// Converts the attributes attached to `inst` and adds them to the `op`.
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
index eb59ef8c62266..4e984baa65f16 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
@@ -237,7 +237,7 @@ class ModuleTranslation {
/// Translates parameter attributes of a call and adds them to the returned
/// AttrBuilder. Returns failure if any of the translations failed.
- FailureOr<llvm::AttrBuilder> convertParameterAttrs(CallOpInterface callOp,
+ FailureOr<llvm::AttrBuilder> convertParameterAttrs(mlir::Location loc,
DictionaryAttr paramAttrs);
/// Gets the named metadata in the LLVM IR module being constructed, creating
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index fb9236fcc640d..b1964481f7272 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -3547,7 +3547,8 @@ void CallIntrinsicOp::build(OpBuilder &builder, OperationState &state,
mlir::StringAttr intrin, mlir::ValueRange args) {
build(builder, state, /*resultTypes=*/TypeRange{}, intrin, args,
FastmathFlagsAttr{},
- /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{});
+ /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{}, /*arg_attrs=*/{},
+ /*res_attrs=*/{});
}
void CallIntrinsicOp::build(OpBuilder &builder, OperationState &state,
@@ -3555,14 +3556,16 @@ void CallIntrinsicOp::build(OpBuilder &builder, OperationState &state,
mlir::LLVM::FastmathFlagsAttr fastMathFlags) {
build(builder, state, /*resultTypes=*/TypeRange{}, intrin, args,
fastMathFlags,
- /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{});
+ /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{}, /*arg_attrs=*/{},
+ /*res_attrs=*/{});
}
void CallIntrinsicOp::build(OpBuilder &builder, OperationState &state,
mlir::Type resultType, mlir::StringAttr intrin,
mlir::ValueRange args) {
build(builder, state, {resultType}, intrin, args, FastmathFlagsAttr{},
- /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{});
+ /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{}, /*arg_attrs=*/{},
+ /*res_attrs=*/{});
}
void CallIntrinsicOp::build(OpBuilder &builder, OperationState &state,
@@ -3570,7 +3573,105 @@ void CallIntrinsicOp::build(OpBuilder &builder, OperationState &state,
mlir::StringAttr intrin, mlir::ValueRange args,
mlir::LLVM::FastmathFlagsAttr fastMathFlags) {
build(builder, state, resultTypes, intrin, args, fastMathFlags,
- /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{});
+ /*op_bundle_operands=*/{}, /*op_bundle_tags=*/{}, /*arg_attrs=*/{},
+ /*res_attrs=*/{});
+}
+
+ParseResult CallIntrinsicOp::parse(OpAsmParser &parser,
+ OperationState &result) {
+ StringAttr intrinAttr;
+ SmallVector<OpAsmParser::UnresolvedOperand, 4> operands;
+ SmallVector<SmallVector<OpAsmParser::UnresolvedOperand>> opBundleOperands;
+ SmallVector<SmallVector<Type>> opBundleOperandTypes;
+ ArrayAttr opBundleTags;
+
+ // Parse intrinsic name
+ if (parser.parseCustomAttributeWithFallback(
+ intrinAttr, parser.getBuilder().getType<mlir::NoneType>())) {
+ return mlir::failure();
+ }
+ result.addAttribute(CallIntrinsicOp::getIntrinAttrName(result.name),
+ intrinAttr);
+
+ if (parser.parseLParen())
+ return mlir::failure();
+
+ // Parse the function arguments.
+ if (parser.parseOperandList(operands))
+ return mlir::failure();
+
+ if (parser.parseRParen())
+ return mlir::failure();
+
+ // Handle bundles.
+ SMLoc opBundlesLoc = parser.getCurrentLocation();
+ if (std::optional<ParseResult> result = parseOpBundles(
+ parser, opBundleOperands, opBundleOperandTypes, opBundleTags);
+ result && failed(*result))
+ return failure();
+ if (opBundleTags && !opBundleTags.empty())
+ result.addAttribute(
+ CallIntrinsicOp::getOpBundleTagsAttrName(result.name).getValue(),
+ opBundleTags);
+
+ SmallVector<DictionaryAttr> argAttrs;
+ SmallVector<DictionaryAttr> resultAttrs;
+ // TODO: add argument/result attribute support
+ if (parseCallTypeAndResolveOperands(parser, result, /*isDirect=*/true,
+ operands, argAttrs, resultAttrs))
+ return failure();
+ call_interface_impl::addArgAndResultAttrs(
+ parser.getBuilder(), result, argAttrs, resultAttrs,
+ getArgAttrsAttrName(result.name), getResAttrsAttrName(result.name));
+
+ // TODO: In CallOp, the attr dict happens *before* the call type.
+ // CallIntrinsicOp should mimic that, allowing most of this function to be
+ // shared between the two ops.
+ if (parser.parseOptionalAttrDict(result.attributes))
+ return mlir::failure();
+
+ if (resolveOpBundleOperands(parser, opBundlesLoc, result, opBundleOperands,
+ opBundleOperandTypes,
+ getOpBundleSizesAttrName(result.name)))
+ return failure();
+
+ int32_t numOpBundleOperands = 0;
+ for (const auto &operands : opBundleOperands)
+ numOpBundleOperands += operands.size();
+
+ result.addAttribute(
+ CallIntrinsicOp::getOperandSegmentSizeAttr(),
+ parser.getBuilder().getDenseI32ArrayAttr(
+ {static_cast<int32_t>(operands.size()), numOpBundleOperands}));
+
+ return mlir::success();
+}
+
+void CallIntrinsicOp::print(OpAsmPrinter &p) {
+ p << ' ';
+ p.printAttributeWithoutType(getIntrinAttr());
+
+ OperandRange args = getArgs();
+ p << "(" << args << ")";
+
+ // Operand bundles.
+ if (!getOpBundleOperands().empty()) {
+ p << ' ';
+ printOpBundles(p, *this, getOpBundleOperands(),
+ getOpBundleOperands().getTypes(), getOpBundleTagsAttr());
+ }
+ p << " : ";
+
+ // Reconstruct the MLIR function type from operand and result types.
+ call_interface_impl::printFunctionSignature(
+ p, args.getTypes(), getArgAttrsAttr(),
+ /*isVariadic=*/false, getResultTypes(), getResAttrsAttr());
+
+ p.printOptionalAttrDict(processFMFAttr((*this)->getAttrs()),
+ {getOperandSegmentSizesAttrName(),
+ getOpBundleSizesAttrName(), getIntrinAttrName(),
+ getOpBundleTagsAttrName(), getArgAttrsAttrName(),
+ getResAttrsAttrName()});
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 4f89ee703ebb9..25599efe64322 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -135,6 +135,46 @@ convertOperandBundles(OperandRangeRange bundleOperands,
return convertOperandBundles(bundleOperands, *bundleTags, moduleTranslation);
}
+static LogicalResult
+convertParameterAndResultAttrs(mlir::Location loc, ArrayAttr argAttrsArray,
+ ArrayAttr resAttrsArray, llvm::CallBase *call,
+ LLVM::ModuleTranslation &moduleTranslation) {
+ if (argAttrsArray) {
+ for (auto [argIdx, argAttrsAttr] : llvm::enumerate(argAttrsArray)) {
+ if (auto argAttrs = cast<DictionaryAttr>(argAttrsAttr);
+ !argAttrs.empty()) {
+ FailureOr<llvm::AttrBuilder> attrBuilder =
+ moduleTranslation.convertParameterAttrs(loc, argAttrs);
+ if (failed(attrBuilder))
+ return failure();
+ call->addParamAttrs(argIdx, *attrBuilder);
+ }
+ }
+ }
+
+ if (resAttrsArray && resAttrsArray.size() > 0) {
+ if (resAttrsArray.size() != 1)
+ return mlir::emitError(loc, "llvm.func cannot have multiple results");
+ if (auto resAttrs = cast<DictionaryAttr>(resAttrsArray[0]);
+ !resAttrs.empty()) {
+ FailureOr<llvm::AttrBuilder> attrBuilder =
+ moduleTranslation.convertParameterAttrs(loc, resAttrs);
+ if (failed(attrBuilder))
+ return failure();
+ call->addRetAttrs(*attrBuilder);
+ }
+ }
+ return success();
+}
+
+static LogicalResult
+convertParameterAndResultAttrs(CallOpInterface callOp, llvm::CallBase *call,
+ LLVM::ModuleTranslation &moduleTranslation) {
+ return convertParameterAndResultAttrs(
+ callOp.getLoc(), callOp.getArgAttrsAttr(), callOp.getResAttrsAttr(), call,
+ moduleTranslation);
+}
+
/// Builder for LLVM_CallIntrinsicOp
static LogicalResult
convertCallLLVMIntrinsicOp(CallIntrinsicOp op, llvm::IRBuilderBase &builder,
@@ -201,6 +241,12 @@ convertCallLLVMIntrinsicOp(CallIntrinsicOp op, llvm::IRBuilderBase &builder,
fn, moduleTranslation.lookupValues(op.getArgs()),
convertOperandBundles(op.getOpBundleOperands(), op.getOpBundleTags(),
moduleTranslation));
+
+ if (failed(convertParameterAndResultAttrs(op.getLoc(), op.getArgAttrsAttr(),
+ op.getResAttrsAttr(), inst,
+ moduleTranslation)))
+ return failure();
+
if (op.getNumResults() == 1)
moduleTranslation.mapValue(op->getResults().front()) = inst;
return success();
@@ -224,39 +270,6 @@ static void convertLinkerOptionsOp(ArrayAttr options,
linkerMDNode->addOperand(listMDNode);
}
-static LogicalResult
-convertParameterAndResultAttrs(CallOpInterface callOp, llvm::CallBase *call,
- LLVM::ModuleTranslation &moduleTranslation) {
- if (ArrayAttr argAttrsArray = callOp.getArgAttrsAttr()) {
- for (auto [argIdx, argAttrsAttr] : llvm::enumerate(argAttrsArray)) {
- if (auto argAttrs = cast<DictionaryAttr>(argAttrsAttr);
- !argAttrs.empty()) {
- FailureOr<llvm::AttrBuilder> attrBuilder =
- moduleTranslation.convertParameterAttrs(callOp, argAttrs);
- if (failed(attrBuilder))
- return failure();
- call->addParamAttrs(argIdx, *attrBuilder);
- }
- }
- }
-
- ArrayAttr resAttrsArray = callOp.getResAttrsAttr();
- if (resAttrsArray && resAttrsArray.size() > 0) {
- if (resAttrsArray.size() != 1)
- return mlir::emitError(callOp.getLoc(),
- "llvm.func cannot have multiple results");
- if (auto resAttrs = cast<DictionaryAttr>(resAttrsArray[0]);
- !resAttrs.empty()) {
- FailureOr<llvm::AttrBuilder> attrBuilder =
- moduleTranslation.convertParameterAttrs(callOp, resAttrs);
- if (failed(attrBuilder))
- return failure();
- call->addRetAttrs(*attrBuilder);
- }
- }
- return success();
-}
-
static LogicalResult
convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
LLVM::ModuleTranslation &moduleTranslation) {
diff --git a/mlir/lib/Target/LLVMIR/LLVMImportInterface.cpp b/mlir/lib/Target/LLVMIR/LLVMImportInterface.cpp
index 24f500557c6de..fbf2d709c240c 100644
--- a/mlir/lib/Target/LLVMIR/LLVMImportInterface.cpp
+++ b/mlir/lib/Target/LLVMIR/LLVMImportInterface.cpp
@@ -45,6 +45,11 @@ LogicalResult mlir::LLVMImportInterface::convertUnregisteredIntrinsic(
moduleImport.setFastmathFlagsAttr(inst, op);
+ ArrayAttr argsAttr, resAttr;
+ moduleImport.convertParameterAttributes(inst, argsAttr, resAttr, builder);
+ op.setArgAttrsAttr(argsAttr);
+ op.setResAttrsAttr(resAttr);
+
// Update importer tracking of results.
unsigned numRes = op.getNumResults();
if (numRes == 1)
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 7ea82f61fadbb..2d3c0efd9a972 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -2213,7 +2213,8 @@ void ModuleImport::convertParameterAttributes(llvm::Function *func,
}
void ModuleImport::convertParameterAttributes(llvm::CallBase *call,
- CallOpInterface callOp,
+ ArrayAttr &argsAttr,
+ ArrayAttr &resAttr,
OpBuilder &builder) {
llvm::AttributeList llvmAttrs = call->getAttributes();
SmallVector<llvm::AttributeSet> llvmArgAttrsSet;
@@ -2233,14 +2234,23 @@ void ModuleImport::convertParameterAttributes(llvm::CallBase *call,
SmallVector<DictionaryAttr> argAttrs;
for (auto &llvmArgAttrs : llvmArgAttrsSet)
argAttrs.emplace_back(convertParameterAttribute(llvmArgAttrs, builder));
- callOp.setArgAttrsAttr(getArrayAttr(argAttrs));
+ argsAttr = getArrayAttr(argAttrs);
}
llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
if (!llvmResAttr.hasAttributes())
return;
DictionaryAttr resAttrs = convertParameterAttribute(llvmResAttr, builder);
- callOp.setResAttrsAttr(getArrayAttr({resAttrs}));
+ resAttr = getArrayAttr({resAttrs});
+}
+
+void ModuleImport::convertParameterAttributes(llvm::CallBase *call,
+ CallOpInterface callOp,
+ OpBuilder &builder) {
+ ArrayAttr argsAttr, resAttr;
+ convertParameterAttributes(call, argsAttr, resAttr, builder);
+ callOp.setArgAttrsAttr(argsAttr);
+ callOp.setResAttrsAttr(resAttr);
}
template <typename Op>
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index eda6b51ff45ea..46d73ded4ca9a 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1696,10 +1696,9 @@ ModuleTranslation::convertParameterAttrs(LLVMFuncOp func, int argIdx,
}
FailureOr<llvm::AttrBuilder>
-ModuleTranslation::convertParameterAttrs(CallOpInterface callOp,
+ModuleTranslation::convertParameterAttrs(Location loc,
DictionaryAttr paramAttrs) {
llvm::AttrBuilder attrBuilder(llvmModule->getContext());
- Location loc = callOp.getLoc();
auto attrNameToKindMapping = getAttrNameToKindMapping();
for (auto namedAttr : paramAttrs) {
diff --git a/mlir/test/Dialect/LLVMIR/call-intrin.mlir b/mlir/test/Dialect/LLVMIR/call-intrin.mlir
index 24aa38fca4a65..e41428bb40b58 100644
--- a/mlir/test/Dialect/LLVMIR/call-intrin.mlir
+++ b/mlir/test/Dialect/LLVMIR/call-intrin.mlir
@@ -105,3 +105,12 @@ llvm.func @bad_args() {
%res = llvm.call_intrinsic "llvm.x86.sse41.round.ss"(%1, %1, %0) : (vector<4xf32>, vector<4xf32>, i64) -> vector<4xf32> {fastmathFlags = #llvm.fastmath<reassoc>}
llvm.return
}
+
+// -----
+
+// CHECK-LABEL: intrinsic_call_arg_attrs
+llvm.func @intrinsic_call_arg_attrs(%arg0: i32) -> i32 {
+ // CHECK: call i32 @llvm.riscv.sha256sig0(i32 signext %{{.*}})
+ %0 = llvm.call_intrinsic "llvm.riscv.sha256sig0"(%arg0) : (i32 {llvm.signext}) -> (i32)
+ llvm.return %0 : i32
+}
diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll b/mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll
index 554be8f797b75..80e45f3479e2c 100644
--- a/mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll
+++ b/mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll
@@ -66,3 +66,14 @@ define void @lround_test(float %0, double %1) {
%3 = call i32 @llvm.lround.i32.f32(float %0)
ret void
}
+
+; // -----
+
+declare i32 @llvm.riscv.sha256sig0(i32)
+
+; CHECK-LABEL: test_intrin_arg_attr
+define signext i32 @test_intrin_arg_attr(i32 signext %a) nounwind {
+ ; CHECK: llvm.call_intrinsic "llvm.riscv.sha256sig0"({{.*}}) : (i32 {llvm.signext}) -> i32
+ %val = call i32 @llvm.riscv.sha256sig0(i32 signext %a)
+ ret i32 %val
+}
\ No newline at end of file
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
I think this generally looks nice. We should definitely have some roundtrip test for the printer and parser though possibly including parameter attributes and operand bundles. I would also like to understand if there is really no way to move the printing and parsing partially to an assembly format (maybe by printing the call_intrinsic more like a call as your todo seems to suggest?).
@@ -350,7 +355,8 @@ class ModuleImport { | |||
DictionaryAttr convertParameterAttribute(llvm::AttributeSet llvmParamAttrs, | |||
OpBuilder &builder); | |||
/// Converts the parameter and result attributes attached to `call` and adds | |||
/// them to the `callOp`. | |||
/// them to the `callOp`. Implemented in terms of the other definition of | |||
/// the public definition of convertParameterAttributes. | |||
void convertParameterAttributes(llvm::CallBase *call, CallOpInterface callOp, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this function would be a good use case for a ArgumentAndResultAttributeInterface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean In the future or as part of this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No this is definitely a separate PR.
p << " : "; | ||
|
||
// Reconstruct the MLIR function type from operand and result types. | ||
call_interface_impl::printFunctionSignature( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yesterday you mentioned something can be bound only once which prevents us from using an assembly format. Was it the args?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, like mentioned in the other comment, perhaps it was due to lack of trying out ref()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parseFunctionSignature
in CallInterfaces seems to be missing the operation as second argument (as is the function is probably incompatibly with the custom directive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I tried to do:
let assemblyFormat = [{
$intrin `(` $args `)`
( custom<OpBundles>($op_bundle_operands, type($op_bundle_operands),
$op_bundle_tags)^ )?
attr-dict `:`
custom<IntrinCallArgsAndRet>($_state, ref($args), type($args), type($results))
}];
But you cannot pass $state
(OperationState) because expected variable to refer to an argument, region, result, or successor
and that is needed (in the parser case) by parseCallTypeAndResolveOperands
.
lgtm, I have nothing to add to @gysit comments |
Replacing |
This seems like it deserves it own PR, lots of "unrelated" changes for the scope here (but happy to try it once this lands) |
Co-authored-by: Tobias Gysi <[email protected]>
Co-authored-by: Tobias Gysi <[email protected]>
✅ With the latest revision this PR passed the C/C++ code formatter. |
I just see there is printFunctionTypes which actually prints the !llvm.func type which is not really useful. Is there an actual print/parseFunctionSignature somewhere? I would assume that it would consume the type of the operands not the operands themselves? Does this still trigger the bind twice problem? |
The problem is the actual lack of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for trying to convert to the assembly format!
Let's move forward with the custom printer then. It seems like an assembly format probably requires changes of these call helper functions as well.
LGTM module last nits.
Yeah we probably would like to have something that just parses the call type and does not try to resolve the operands. AFAIK the code to resolve the call types should be generated by tablegen when using an assembly format. I would suggest to move forward with what we have for now. We can still follow up with an assembly format version if we want to. |
Co-authored-by: Tobias Gysi <[email protected]>
Co-authored-by: Tobias Gysi <[email protected]>
Exactly! And because
Great, thanks! |
…llvm#129640) Basically catch up with llvm.call and add support for translate and import to LLVM IR. This PR is split into two commits in case it's easier to review the refactoring part, which comes first (happy to split the PR if necessary). --------- Co-authored-by: Tobias Gysi <[email protected]>
Basically catch up with llvm.call and add support for translate and import to LLVM IR.
This PR is split into two commits in case it's easier to review the refactoring part, which comes first (happy to split the PR if necessary).