Porting use of target-specific node types in SelectionISel to GlobalISel?

I am in the process of porting our target to GlobalISel and have encountered the following problem. In our target, the predicate for conditional branching is placed on the branch instruction instead of the compare instruction. To make this work in our SelectionISel-based implementation, we declare our own nodes, e.g.:

def XYZ_COMPARE_SIGNED : SDNode<“XYZISD::COMPARE_SIGNED”, SDT_PHXiCmp, [SDNPHasChain, SDNPOutGlue]>;

During legalization, we lower BR_CC nodes into:

XYZISD::COMPARE_SIGNED

XYZISD::CONDBRANCH

These are then used for pattern matching, e.g.:

def : Pat<(XYZ_COMPARE_SIGNED i16:$src1, (i16 Imm_m32768_32767_i16:$SImm)), (cmp_nimm16_a16 $src1, imm:$SImm)>;

Now to my question: What is the best way to achieve the same thing in GlobalISel? Is it possible to introduce new node types in GlobalISel? If so, how? If not, what’s a suitable work-around that allows me to reuse the tablegen-declared patterns?

Cheers,

Gabriel

Okay, I managed to figure this out myself and will describe the workaround here in case there is someone else with the same problem.

There is apparently a TableGen class called GINodeEquiv which is used for making a G_* instruction equivalent to a specific ISD node. This can be used as follows, which is actually how GlobalISel handles all normal G_* instructions:

def G_XYZ_COMPARE_SIGNED : GenericInstruction{ … };

def : GINodeEquiv<G_XYZ_COMPARE_SIGNED, XYZ_COMPARE_SIGNED>;

This way, I can reuse the patterns already defined in the *.td files with minimal modifications.

Cheers,

Gabriel