Look-ahead instruction selection

In .td file, if the pattern to match the DAG is:

(vector_shuffle (mul build_vector, build_vector))

is it possible to return ‘mul’ (SDNode*) instead of returning the first ‘vector_shuffle’?

It seems to me that the default instruction selector can only return the ‘root’ node of the pattern.


The simplest thing to do is to map a vector_shuffle to another
vector_shuffle; there shouldn't be any issues with that, I think. Is
there some reason you don't want to write it that way?

Note that you can use a custom PatFrag to match an instruction with a
single use... see, for example, "and_su" in X86InstrInfo.td.


Maybe I didn't describe the question very well.

I want to match these patterns:

  (and (mul node:$val0, node:$val1))
  (and (add node:$val0, node:$val1))
  (and (sub node:$val0, node:$val1))
  (and (udiv node:$val0, node:$val1))

into "four" different machines instructions, respectively:


That is, this machine is capable of doing an arithmetic operation and a
"following" AND operation by a single machine instruction. There are a lot
of arithmetic operations but they can only be combined with a following AND
operation. It's important that only the following AND can be merged/combined
with the arithmetic operation. The pattern:

   (mul node:$val0, (AND))

can _not_ be matched.

The problem is, it seems to me, that the instruction returned in these
patterns is always the AND, which is the "root" of these partial DAG
pattern, instead of the arithmetic operation. The LLVM instruction selector
is capable of doing this "look ahead" matching? What is the suggested way to
do this?

PS: For GPU guys, I am trying to match the writemask operation after an
arithmetic operation.

Eli Friedman-2 wrote:

Have you tried using special patterns for these instructions? If you check in X86InstrInfo.td, there are some like this:

def : Pat<(store (or (srl (loadi16 addr:$dst), (i8 (trunc CX:$amt))),
                      (shl GR16:$src2, (i8 (trunc (sub 16, CX:$amt))))),
           (SHRD16mrCL addr:$dst, GR16:$src2)>;

You might have some luck with something along these lines:

def : Pat<(and (mul node:$val0, node:$val1), ...),
           (MUL_AND node:$val0, node:$val1)>;

(The pattern you have above seems incomplete because it lacks an extra "node:$val#" for the "and" part after the "mul" part.)