About the operation and its builder

This is my td file contents:

def xxxOp : xxxOp<"xxx", [RecursiveMemoryEffects,
      SingleBlockImplicitTerminator<"YieldOp">,
      ParentOneOf<["func::FuncOp", "AffineForOp"]>]> {
   ...
  let results = (outs Variadic<AnyType>:$results);
  let regions = (region SizedRegion<1>:$body);
  let assemblyFormat = "attr-dict-with-keyword ( `:` type($results)^ )? $body";

  let hasVerifier = 1;
  let hasCanonicalizer = 1;


  let extraClassDeclaration = [{
    /// Get the terminator yield op.
    YieldOp getYieldOp();
  }];
}

My LLVM is 17.0.0. I have some problems with builder or rewiter. Here’s how I use them.

auto new =
          rewriter.create<xxOp>(op.getLoc(), ValueRange());

auto new = builder.create<xxOp>(loc,  returnValues);

I get an error when compiling:

error: no matching function for call to ‘mlir::xxx::Op::build(mlir::OpBuilder&, mlir::OperationState&, mlir::ValueRange)’
  489 |     OpTy::build(*this, state, std::forward<Args>(args)...);

If I modify it to the following:

auto new = builder.create<xxOp>(loc,  returnType, returnValues);

I don’t have problems when compiling, but I get these problems with mlir-opt :

:build(mlir::OpBuilder&, mlir::OperationState&, mlir::TypeRange, mlir::ValueRange, llvm::ArrayRef<mlir::NamedAttribute>): Assertion `operands.size() == 0u && "mismatched number of parameters"' failed.

I’m not sure what’s wrong and I’m looking for suggestions.

OOC have you switched your dialect to use properties?

Have you checked the available codegen’ed build()'s?
e.g., Tosa ops : $build/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.cpp.inc

void AbsOp::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type output, ::mlir::Value input1) {
...
}
void AbsOp::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value input1) {
...
}
void AbsOp::build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ...

I’m not sure exactly how they’re generated but you can also add your own version of build() wrapping the existing version of build() in yourDialectOps.cpp as per your need.

I am a little confused, are you trying to say attributes, I have added to my dialect.

I actually wrote the custom builder in the td file, but I may need to manually rewrite it in the DialectOps.cpp . It’s worth mentioning that I’ve seen a similar format in someone else’s project file, but the pj compiles and executes fine, which is the point of my confusion.
Thanks.

I don’t think it’s necessary to implement in .cpp if you have a custom build in .td
But the error message suggests there’s something wrong in calling it (probably argument number/type mismatch)
You may want to check the generated code in .cpp.inc (I’ve pointed wrong path in my previous comment, it’s under $build/tools/mlir/…)

For example,

mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.td

def SparseTensor_ForeachOp : SparseTensor_Op<"foreach",
    [SingleBlockImplicitTerminator<"YieldOp">]>,
     Arguments<(ins AnyTensor:$tensor,
   ...

  let builders = [
    OpBuilder<(ins "Value":$tensor, "ValueRange":$iterArgs, "AffineMapAttr":$order,
      "function_ref<void(OpBuilder &, Location, ValueRange, Value, ValueRange)>")>,
    OpBuilder<(ins "Value":$tensor, "AffineMapAttr":$order,
      "function_ref<void(OpBuilder &, Location, ValueRange, Value, ValueRange)>":$bodyBuilder),
    [{
      build($_builder, $_state, tensor, ValueRange(), order, bodyBuilder);
    }]>,
    OpBuilder<(ins "Value":$tensor,
      "function_ref<void(OpBuilder &, Location, ValueRange, Value, ValueRange)>":$bodyBuilder),
    [{
      build($_builder, $_state, tensor, ValueRange(), nullptr, bodyBuilder);
    }]>,
    OpBuilder<(ins "Value":$tensor, "ValueRange":$iterArgs,
      "function_ref<void(OpBuilder &, Location, ValueRange, Value, ValueRange)>":$bodyBuilder),
    [{
      build($_builder, $_state, tensor, iterArgs, nullptr, bodyBuilder);
    }]>
  ];

generates
build/tools/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.cpp.inc

void ForeachOp::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, Value tensor, AffineMapAttr order, function_ref<void(OpBuilder &, Location, ValueRange, Value, ValueRange)> bodyBuilder) {
      build(odsBuilder, odsState, tensor, ValueRange(), order, bodyBuilder);
}
void ForeachOp::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, Value tensor, function_ref<void(OpBuilder &, Location, ValueRange, Value, ValueRange)> bodyBuilder) {
      build(odsBuilder, odsState, tensor, ValueRange(), nullptr, bodyBuilder);
}
void ForeachOp::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, Value tensor, ValueRange iterArgs, function_ref<void(OpBuilder &, Location, ValueRange, Value, ValueRange)> bodyBuilder) {
      build(odsBuilder, odsState, tensor, iterArgs, nullptr, bodyBuilder);
}
void ForeachOp::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange results, ::mlir::Value tensor, ::mlir::ValueRange initArgs, /*optional*/::mlir::AffineMapAttr order) {
  ... }

void ForeachOp::build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes) {
  ... }

Yes, thanks for your reply.

OK, fine. The problem is with the LLVM/MLIR version, i was using previously gcc, but switching to clang resloved it.