Comparing an operand and attribute in mlir in ODS

Hi Folks.
In my code I need to check constraint on an attribute with respect to another operand. What is the right way to do it?

Below I try to ask with a simple example so it is easier for you to answer concretely. I show how I compare an operand trait with another operands and that works.
But when I try comparing and operand trait with an attribute value, i cant seem to get that working

class MyDialect_Op<string mnemonic, list<OpTrait> traits = []> :
    Op<MyDialect_Dialect, mnemonic, traits>;

class OpBitWidthsMatch<int i, int j> :
   CPred<"$_op.getOperand(" # " i # ").getType()....getIntOrFloatBitWidth()==" #
         "$_op.getOperand(" # " j # ").getType()...getIntOrFloatBitWidth()" 
def Op1 : MyDialect_Op<"Op1", 
       PredOpTrait<"my ops operands bit width match", OpBitWidthsMatch<0,1>>
      ]> {
      let summary = "ask mlir forum how to compare operand and attribute";
      let arguments = (ins MyType:$src1, MyType:$src2, I32Attr:$myAttr);

Above I want to check myAttr is , say, same as getIntOrFloatBitWidth returned value. How do i do it elegantly? Using …
Confined<I32Attr, [IntMinValue<5>]:myAttr

… I could check attribute value on itself, but in my case I need to, e.g. compare myAttr. with operand(0)....getIntOrFloatBitWidth().

You’ll want something similar to AllElementTypesMatch, which looks up properties on the op by name. For your specific example, there isn’t an existing class, so you’d need another subclass (or instance) of AllMatchSameOperatorTrait.

I am afraid that doesn’t solve the problem. Thanks for tying to help.

Not sure I followed what you want, but what about:

class OpBitWidthMatchAttr<int i, string attrName> :
   CPred<"$_op.getOperand(" # i # ").getType()....getIntOrFloatBitWidth()==" #
         "$_op.getAttrOfType<IntegerAttr>(" # attrName # ").getValue().ZExt()" 

You can decorate the op with PredOpTrait<"Op operand bit width match attribute", OpBitWidthMatchAttr <0,"myAttr">>

1 Like

Thanks Mehdi.

That works for me.

Also I was able to clean up code a bit using

let extraClassDeclaration = [{
    uint64_t getMyAttrValue() {
        return (*this)->getAttrOfType<IntegerAttr>("myAttr").getValue().getZExtValue();

And then

class OpBitWidthMatchAttr<int i, string attrName> :
   CPred<"$_op.getOperand(" # i # ").getType()....getIntOrFloatBitWidth()== getMyAttrValue()"  >;