Setting priority in instruction selection

I am having a problem with instruction selection with pattern fragments.

With my custom target, in order to simplify code generation patterns, I do not allow a constant to be used in an instruction(mainly because they have declare before use semantics).

Now the problem I am having is that I cannot get a instruction that contains pattern fragment that uses an immediate value to be selected before the immediate instruction itself.

So, my question is this, is there anyway to force the ordering of how the instructions get selected.

For example, take this pattern (A & B) | (C & ~B), I have the following PatFrag:

/// Pattern 1: (lhs & bitpat) | (rhs & ~bitpat)

def bfi_pat1 : PatFrag<(ops node:$lhs, node:$rhs, node:$bitpat),

(or

(and node:$lhs, node:$bitpat),

(and node:$rhs, (not node:$lhs)))>;

def BFI_i32 : ThreeInOneOut<IL_OP_BFI, (outs GPRI32:$dst),

(ins GPRI32:$lhs, GPRI32:$rhs, GPRI32:$bitpat),

!strconcat(IL_OP_BFI.Text, " $dst, $lhs, $rhs, $bitpat"),

[(set GPRI32:$dst, (bfi_pat1 GPRI32:$lhs, GPRI32:$rhs, GPRI32:$bitpat))]>;

and also this instruction:

def LOADCONST_i32 : ILFormat<IL_OP_MOV, (outs GPRI32:$dst),

(ins i32imm:$val),

“mov $dst, $src”,

[(set GPRI32:$dst, imm:$val)]>;

Now, what is happening with this code, (A & B) | (C & ~B), where B is an immedate and ~B is an inverse of it,

instead of getting

LOADCONST_i32 r0 B

BFI_i32 r1, A, C, r0

I am getting

LOADCONST_i32 r0, B

LOADCONST_i32 r1, ~B

AND_i32 r2, A, r0

AND_i32 r3, C, r1

OR_i32 r4, r2, r3

because the LOADCONST is getting matched before the bfi_pat1 pattern fragment.

I know I can write C++ code that will generate a pattern fragment and handle this issue, but I don’t want to duplicate behavior if it already exists.

Any ideas?

Thanks,

Micah

NM, I figured it out. if I create a target SDNode for constants and use that instead of just ‘set’, then I can match the pattern.

Micah

I'm pretty sure (not node:$lhs)) will never match an immediate.

-Eli

From: Eli Friedman [mailto:eli.friedman@gmail.com]
Sent: Monday, September 12, 2011 7:15 PM
To: Villmow, Micah
Cc: llvmdev@cs.uiuc.edu
Subject: Re: [LLVMdev] Setting priority in instruction selection

> I am having a problem with instruction selection with pattern
fragments.
>
> With my custom target, in order to simplify code generation patterns,
I do
> not allow a constant to be used in an instruction(mainly because they
have
> declare before use semantics).
>
>
>
> Now the problem I am having is that I cannot get a instruction that
contains
> pattern fragment that uses an immediate value to be selected before
the
> immediate instruction itself.
>
>
>
> So, my question is this, is there anyway to force the ordering of how
the
> instructions get selected.
>
>
>
> For example, take this pattern (A & B) | (C & ~B), I have the
following
> PatFrag:
>
> /// Pattern 1: (lhs & bitpat) | (rhs & ~bitpat)
>
> def bfi_pat1 : PatFrag<(ops node:$lhs, node:$rhs, node:$bitpat),
>
> (or
>
> (and node:$lhs, node:$bitpat),
>
> (and node:$rhs, (not node:$lhs)))>;
>
> def BFI_i32 : ThreeInOneOut<IL_OP_BFI, (outs GPRI32:$dst),
>
> (ins GPRI32:$lhs, GPRI32:$rhs, GPRI32:$bitpat),
>
> !strconcat(IL_OP_BFI.Text, " $dst, $lhs, $rhs, $bitpat"),
>
> [(set GPRI32:$dst, (bfi_pat1 GPRI32:$lhs, GPRI32:$rhs,
> GPRI32:$bitpat))]>;
>
> and also this instruction:
>
>
>
> def LOADCONST_i32 : ILFormat<IL_OP_MOV, (outs GPRI32:$dst),
>
> (ins i32imm:$val),
>
> "mov $dst, $src",
>
> [(set GPRI32:$dst, imm:$val)]>;
>
>
>
>
>
> Now, what is happening with this code, (A & B) | (C & ~B), where B is
an
> immedate and ~B is an inverse of it,
>
> instead of getting
>
> LOADCONST_i32 r0 B
>
> BFI_i32 r1, A, C, r0
>
> I am getting
>
> LOADCONST_i32 r0, B
>
> LOADCONST_i32 r1, ~B
>
> AND_i32 r2, A, r0
>
> AND_i32 r3, C, r1
>
> OR_i32 r4, r2, r3
>
> because the LOADCONST is getting matched before the bfi_pat1 pattern
> fragment.
>
>
>
> I know I can write C++ code that will generate a pattern fragment and
handle
> this issue, but I don't want to duplicate behavior if it already
exists.
>
>
>
> Any ideas?

I'm pretty sure (not node:$lhs)) will never match an immediate.

[Villmow, Micah] (not node:$lhs) expands into (xor node:$lhs, imm:-1), this is the immediate that was getting lowered to LOADCONST before the pattern was being matched.

Right... the point is that we fold immediates, so there is no xor
node, so it will never match.

-Eli