Pattern matching G_[SU]ADD[OE] and G_[SU]SUB[OE]

Hi All,

In my education-purposes MC6809 backend, I’m trying to get rid of as much custom C++ as I can in favour of using existing compiler backend infrastructure.

It’s going really well so far. I’ve been able to write many SelectionDAG Pattern<> and Pat<> matches that have been imported and which allowed me to delete plenty of fragile hand-lowering.

I’m now turning my attention to simplifying my hand-lowering of G_[SU]ADD[OE] and G_[SU]SUB[OE]. Unlike G_ADD and G_SUB, which are now trivial to lower with imported SelectionDAG matches, the above are proving to be quite a pain. I’d like to pattern-match, but it doesn’t look like there are importable SelectionDAG idioms that will match the above opcodes.

Or am I wrong? What might work? I’m considering using the combiner also - is this the canonical way to do what I want?

Thanks!

M

AArch64 manually selects the overflow ops in C++:

Pattern matching the carry-changing instructions is problematic, because you cannot express all required constraints with a DAG pattern. Assume you have several G_UADDO / G_UADDE instructions in a basic block, then you need to make sure that the generated carry (by G_UADDO) is not destroyed (by another G_UADDO) before it is consumed (by G_UADDE). It seems the only way to ensure this is with custom lowering code.
After several tries, I ended up for my backend with the AArch64 approach. See https://github.com/redstar/llvm-m88k/blob/main-m88k/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp#L1230.

Kai

Thanks for the explanation! I still don’t quite understand something.

Surely the carry can be preserved just as any other register for the next consumer?

Or is this a problem for SSA’s having multiple outputs? I can sort-of see how the SSAs connect up in a way that may end up cyclic.

If this is the case, then how does hand-lowering not freak out the various validation passes?

Learning more every day! Thanks folks!

M

This is a DAG syntactical limitation. Since we don’t have a native globalisel way of writing selection patterns, we’re currently stuck with the same limitations as the DAG

The AArch64 approach is currently broken, but will hopefully be fixed without requiring changes on your side by [RFC][GlobalISel] InstructionSelect: Allow arbitrary instruction erasure.