Error: (type) is not buildable and a buildable type cannot be inferred

Hi,

I am a beginner trying to make a new dialect with MLIR. I followed the " Defining Dialect Attributes and Types" tutorial to define new types, but when the new types are used in newly defined ops, the error is reported:

error: type of result #0, named ‘res’, is not buildable and a buildable type cannot be inferred

But I have provided the customed builder for the new type, why is this error reported?
Here is the code for defining a new type

def AccTensorType : AccTensor_Type<"AccTensorType", "tensor"> {
  let summary = "Tensor type for accelerators";
  let description = [{
    Tensor type for accelerators.
  }];

  let parameters = (ins "Type":$addr,
                        "Type":$bound,
                        "Type":$step);

  let assemblyFormat = "`<` $addr `,` $bound `,` $step `>`";

  let genVerifyDecl = 1;
  let skipDefaultBuilders = 1;

  let builders = [
    TypeBuilderWithInferredContext<(ins "Type":$addr,
                                        "Type":$bound,
                                        "Type":$step), [{
        return Base::get(addr.getContext(), addr, bound, step);
    }]>
  ];
}

Here is the code for defining the new op:

def AccTensor_Sum : AccTensor_Op<"sum", [NoSideEffect, 
                                       SameOperandsAndResultType]> {
  let summary = "Sum the sub-tensors";
  let description = [{
    Sum the sub-tensors.
  }];

  let arguments = (ins AccTensorType:$input1,
                       AccTensorType:$input2);
  let results = (outs AccTensorType:$res);

  let assemblyFormat = "$input1 `,` $input2 attr-dict" ;
}

The error comes from the fact that the syntax is missing type($res) somewhere: the system does not know how to create the op without it.

That said, you specified SameOperandsAndResultType on the operation, which should be enough for the system to handle it. Somehow this does not kick in here and I’m not sure why.
This is handled here: llvm-project/OpFormatGen.cpp at main · llvm/llvm-project · GitHub ; it is supposed to populate the variableTyResolver map which is then checked here: llvm-project/OpFormatGen.cpp at main · llvm/llvm-project · GitHub ; a few lines before the error you see.

1 Like

Thank you for your help! I solved the problem by adding type($res):

 let assemblyFormat = "$input1 `,` $input2 attr-dict `:` type($res)" ;

Actually I just realized that it makes sense: we need at least one of the type in the syntax. Providing it for any of the operands or the type will be enough (this is why type($res) is enough to fix it and you don’t need to provide the type of the operands: the trait is working as expected here).

1 Like