RegisterClass constraints in TableGen


I’ve come across a problem while working on an LLVM backend for a new target architecture.

This architecture has two single-ported register files. Each instruction can only read one operand from each register file, but can write to either. I tried implementing it naïvely in TableGen with two definitions per instruction, so I had:

def AllRegs : RegisterClass< … (add interleave (XRegs, YRegs))>;

and in the

def Instr_xy: Instruction(outs AllRegs:$dst), (ins XRegs:$src1, YRegs:$src2), “…”, [(set AllRegs:$dst, (OpNode XRegs:$src1, YRegs:$src2))]

def Instr_yx: Instruction(outs AllRegs:$dst), (ins YRegs:$src1, XRegs:$src2), “…”, [(set AllRegs:$dst, (OpNode YRegs:$src1, XRegs:$src2))]

for each instruction. However, upon failing the first match, it insisted on swapping the registers between the two classes and sticking with that instruction.

I also tried using ComplexPatterns, but to no avail. I’m sure this is entirely possible, but I can’t see how it’s done.


LLVM's register allocator's can't model that constraint, and we don't support the multiple alternatives you describe either.

Perhaps you could let isel always use one variant, and write a special pre-RA pass to switch the opcodes?


Excellent, I’ve implemented my own PBQP register allocator and solved the issue very painlessly.

Now onto those more interesting problems!

Thanks for your suggestion,