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 manySelectionDAGPattern<> 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?
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.
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