Hi,
I am having some issues to make the assemblyFormat property work correctly for my custom op, and I am having a couple of questions about it.
Here is my code:
def GOM_LoadOp : GOM_Op<"load", []> {
let summary = "Load data from memory";
let arguments = (ins GOM_PointerType:$ptr);
let results = (outs GOM_Type:$result);
let assemblyFormat = "$ptr attr-dict `:` type($result)";
}
GOM_PointerType is defined as such:
def GOM_Float : TypeAlias<AnyTypeOf<[F16, F32]>, "floating point">;
def GOM_PointerType :
DialectType<GOM_Dialect, CPred<"$_self.isa<PointerType>()">,
"GOM pointer type">;
def GOM_Type : AnyTypeOf<[GOM_Float, GOM_PointerType]>;
And the C++ definition is:
class PointerType : public mlir::Type::TypeBase<PointerType, mlir::Type,
detail::PointerTypeStorage> {
public:
/// Inherit some necessary constructors from 'TypeBase'.
using Base::Base;
static PointerType get(Type pointeeType);
Type getPointeeType() const;
};
I am using assemblyFormt to simplify an instruction such as:
%1 = "gom.load"(%0) : (!gom.ptr<f32>) -> f32
into:
%1 = gom.load %0 : f32
But unfortunately my LoadOp TableGen definition fails to compile:
error: type of operand #0, named 'ptr', is not buildable and a buildable type cannot be inferred
$ptr attr-dict `:` type($result)
I was able to solve It by doing this instead:
def GOM_LoadOp : GOM_Op<"load",
[TypesMatchWith<"result type matches ipointee type of 'ptr'",
"ptr", "result",
"$_self.cast<PointerType>().getPointeeType()">]> {
let summary = "Load data from memory";
let arguments = (ins GOM_PointerType:$ptr);
let results = (outs GOM_Type:$result);
let assemblyFormat = "$ptr attr-dict `:` type($ptr)";
}
But it’s not exactly what I wanted, here the format is:
%1 = gom.load %0 : !gom.ptr<f32>
I looked more at the code, and found the error is triggered in OpFormatParser::verifyOperands
(llvm-project/OpFormatGen.cpp at main · llvm/llvm-project · GitHub).
The function starts with;
// Check that all of the operands are within the format, and their types can
// be inferred.
That’s what I don’t understand, why do we need to infer the operands types ? I assume this is used by the parser. Since the operands definition were already parsed, I would have thoughts the operands types would be known already. I am missing something ?