UI64ArrayAttr not found

Hi folks.
I need a U164ArrayAttr for my code but I see it is not defined MLIR: mlir::Builder Class Reference
Is there a particular reason ? If not, if I were to define it for my own code, would it be possible (e.g. I am not sure if
"$_builder.getUI64ArrayAttr($0)"; would work as is.
Where all would I need to add support code.

For my purpose I feel indexType would be right, but every time I try to use it I get stuck as it keeps erorring on ‘not an index type’. Also not sure if index type is uint64_t.


Index type is a separate integer type and is different from ui64. You might want to use $_builder.getIndexArrayAttr($0).

I found this definition

def UI64Attr : TypedUnsignedIntegerAttrBase<
    UI64, "uint64_t", "64-bit unsigned integer attribute">;

in include/mlir/IR/OpBase.td . But UI64ArrayAttr is missing.

Those methods are creating signless ints, not signed ones, so a UI64 method wouldn’t really make sense without also having a signed version.

These tablegen shorthands are generally added as necessary. Personally, I think having these shorthands in a generic place is frequently not great. They’re not exhaustive so you spend forever trying to figure out whether there’s already a shorthand for it.

“Those methods are creating signless ints” - did you mean ‘UI64Attr’ ?
This is confusing as I thought the U meant ‘unsigned’.

I mean I64ArrayAttr. UI64ArrayAttr doesn’t exist. The signed correspondence to UI64Attr is SI64Attr (llvm-project/OpBase.td at 2e02d2a62f3a86c105ea84323b38941c03ce37da · llvm/llvm-project · GitHub). The attribute created by I64Attr is a signless int (not unsigned), which means the type does not carry sign information. In the core dialects, sign information is carried in the operation, not the type. See MLIR Rationale - MLIR

Unfortunately, it is still confusing for me, so please bear with me as i try to ask with an example.

If I have a unsigned int val that needs to be attached as an attribute to an Op Foo, what is the right way to do it in mlir? Is this all consistent or will this cause problems for me later:

let arguments = (ins ....., I32Attr:$val)

Reading val from mlir::myDialect::FooOp
auto fooOp = llvm::dyn_cast<mlir::myDialect::FooOp>(mlir_inst);
unsigned val = fooOp.val();

Creating attr for FooOp
builder.create<mlir::myDialect::FooOp>(loc, type, value, builder.getI32IntegerAttr(value))

Or am i mixing it all up badly.
Also, if i have something like std::vector<uint64_t> values then what would be the right way to do this.

If I define my own def NonNegI32Attr : Confined<I32Attr, [IntNonNegative]> it works but I am not sure if this is good code.

Best Regards

It depends on what you are trying to do. Did you read the rationale section I linked? An I32 attr is just an integer with 32 bits. It does not carry information on whether the first bit should be interpreted as a sign bit. Whether you want to encode how to interpret the sign bit in your attribute is up to you. Having an attribute constrained to be non-negative is not the same as it being unsigned (in fact it implies that it is signed but always has a 0 as the first bit).

fooOp.val() will be an IntegerAttr, not unsigned. It contains an APInt

Hi Folks:

If I have something like std::vector<... e.g. int ... > values then what would be the right way to define an attribute in the ops.td for it? Should I use ArrayAttr ? Any help on similar codes that store and retrieve similar structures from ops and build ops with it will be useful. I have used DenseElementsAttr before but that seems more suited for multi-dim shapes.
Thanks a lot

If you want to store C++ integral values, you should define an attribute like

def MyDialect_IntegerArrayAttr : MyAttr<"IntegerArray"> {
  // ...
  let parameters = (ins ArrayRefParameter<"int", "">:$value);

Although I think there was a DimListAttr patch floating around somewhere, I can’t seem to find it at the moment.

I haven’t sent it out yet, making it look really nice led me to have to change a bunch of things in how we manage attributes, I’ll likely need one more week!