Help on DAG pattern matching string

Hello,

I'm new to LLVM and I'm using it to translate from LLVM to another language rather than emitting actual machine code. The target language has instructions that operate on pointers which aren't naturally exposed in LLVM. Here's what I've done to add pointer support for an instruction called PADD that takes a pointers and an offset and returns the new pointer value:

def DefReg : Register<"r">;
def PtrReg : Register<"ptr">;
def I32RC : RegisterClass<"BE", [i32], 32, [DefReg]>;
def P32RC : RegisterClass<"BE", [i32], 32, [PtrReg]>;
def BEInst<bits<8> op, dag outs, dag ins, string asmstr, list<dag>

: Instruction { /* assign arguments to class members */ }

def BE_PADD : BEInst<0F, (outs P32RC:$dst), (ins P32RC:$src1, I32RC:$src2), "PADD",
                                       [(set P32RC:$dst, (add P32RC:$src1, I32RC:$src2))]>;

When I compile the project I get the error: Pattern '(add:i32 P32RC:i32:$src1, I32RC:i32:$src2)' is impossible to select! Does anyone have an idea of why I'm getting this error?

I've read the docs on table generator, code generator, back end, etc. but I'm still unclear on how to write pattern selection strings. Area there resources other than the LLVM docs that explain this more in detail?

Thanks,
Javier

Are there any other patterns in your TD file? If so, then one of the ones before this pattern will match everything, and this pattern will never be matched.

-bw

Hi Bill,

Yes, there are other patterns. I tried commenting out all the other instructions definitions and I still get this error. After debugging TblGen I found that the second pattern is being generated as a variant of the first. I think the reason is that the PADD instruction is inheriting the commutative property from ADD defined inTargetSelectionDAG.td. The variant ends up being the same as the original causing the error later on. If all this is correct then how can I mark the node to be non-commutable? I tried using “let isCommutable = 0” in the instruction definition but didn’t seem to work.

Thanks,
Javier

That's kind of strange. It might be some type of "default". However, you probably don't want to turn off the "commutative" property, unless it really isn't commutative. I know it's painful, but it might be best just to slog through the TableGen code in a debugger, and see why it is that your stuff inherits properties from the ADD in TargetSelectoinDAG.td and then why the two versions are "identical" in TableGen's mind.

-bw

Hello, Everyone

TargetSelectoinDAG.td and then why the two versions are "identical" in
TableGen's mind.

That's correct. The patterns are identical since the types of operands
involved are the same. DAG pattern matching is done before regalloc,
there are not regclasses actually at that point, thus both patterns
tries to select the same thing...

The patterns are identical since the types of operands
involved are the same.

This looks like the case since the I32RC and P32RC are both based on i32. Then, how can I make LLVM assign the pointer class to the register?

I just saw that ScheduleDAGSDNodesEmit.cpp in getInstrOperandRegCLass() where there’s a check of the operand’s flag. If the flag has the LookupPtrRegClass bit set then it looks like the target gets to return the pointer class to be used for the register. Is this the right way to proceed and if so how do I set the flag for an instruction?

Thanks,
Javier