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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110912/121572ce/attachment.html>
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 From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] On Behalf Of Villmow, Micah Sent: Monday, September 12, 2011 6:53 PM To: llvmdev at cs.uiuc.edu Subject: [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? Thanks, Micah -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110912/9d9fd8bd/attachment.html>
On Mon, Sep 12, 2011 at 6:53 PM, Villmow, Micah <Micah.Villmow at amd.com> wrote:> 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. -Eli
> -----Original Message----- > From: Eli Friedman [mailto:eli.friedman at gmail.com] > Sent: Monday, September 12, 2011 7:15 PM > To: Villmow, Micah > Cc: llvmdev at cs.uiuc.edu > Subject: Re: [LLVMdev] Setting priority in instruction selection > > On Mon, Sep 12, 2011 at 6:53 PM, Villmow, Micah <Micah.Villmow at amd.com> > wrote: > > 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.> > -Eli