[GlobalISel][Combiner] How to find an instruction with the same source operands as the current one?

Hi all,

For my toy backend (MC6809), I wish to combine two gMIR instructions that have the same source operands. The 6809 has a MUL instruction that will multiply the A and B 8-bit accumulators giving the 16-bit result in D, which is A concat B. I want to combine the G_MUL and G_[US]MULH instruction that I’m presented with into a single, local G_MUL_FULL that I can further lower later.

In the combiner (or legalizer, or anywhere, for that matter) how can I look for/match an instruction that the same source operands as the one I currently have?

E.g. if MI = G_MUL %12, %23, how can I look for a G_SMULH %12, %23?

I cant find a way to find the G_SMULH. I can do it if I have its output vreg, but that is the very information I need to find.

The full combine will be

%11:accum(s8) = G_MUL %10:accum, %9:accum
%12:accum(s8) = G_[SU]MULH %10:accum, %9:accum

Combine to (having 2 8-bit registers to help intermediate sums in more complex cases)

%12:accum(s8), %11:accum(a8) = G_MUL_FULL %10:accum, %9:accum

Which will later lower to a pseudo-instruction

%12:acc8(s8), %11:acc8(s8), %13:cc(s1) = Mul8 %10:acc8(tied-def 0)(s8), %9:acc8(tied-def 1)(s8), implicit-def $z

and finally to

MULx implicit-def $ad, implicit-def $z, implicit-def $c, implicit $aa, implicit $ab


I’m assuming your problem is you’re trying to do this in a combine that inspects one of the instructions at a time. You need some kind of other pass to look over blocks for common uses. This is essentially the same problem that DivRemPairs solves, except in the IR

1 Like