I've been unable to come up with the TableGen recipe to match a negated operand. My target asm syntax allows the following transform: FNEG r8, r5 MUL r6, r8, r9 to MUL r6, -r5, r9 Is there a Pattern<> syntax that would allow matching *any* opcode (or even some subset), not just MUL, with a FNEG'd operand? I expect I can define a PatFrag: def fneg_su : PatFrag<(ops node:$val), (fneg node:$val), [{ return N->hasOneUse(); }]>; and then use that in each target instruction patten in XXXInstrInfo.td, such as: def XXX_MUL : XXXInst< (outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), "mul $dst, -$src1, $src2", [(set $dst, (mul (fneg_su GPR32:$src1), GPR32:$src2))]>; but I would like to believe there's a way to do this with a Pattern<> definition instead, with help from PatFrag and the SDNode_XFORM perhaps. I looked at the ARM target code with PatFrag for negated immediates but that approach doesn't seem possible with register operands, as I don't know what xform would operate on. With immediates you have a DAG node you can generate. Also, it does seem like this is a folding operation PerformDAGCombine() could do but that approach seems like it needs to modify the registerclass, or something similar, that would eventually get you to a PrintMethod that could insert the dash/negate in front of the operand. I didn't want to define a 'mirror' registerclass for my existing register set that would just have the Name as the negated version. That would have its own complications. Is there a superior way to do this with DAG combine? Thanks, Joe
Hi Joe, Le 11/05/2012 02:13, Joe Matarazzo a écrit :> I've been unable to come up with the TableGen recipe to match a > negated operand. My target asm syntax allows the following transform: > > FNEG r8, r5 > MUL r6, r8, r9 > > to > > MUL r6, -r5, r9 > > Is there a Pattern<> syntax that would allow matching *any* opcode (or > even some subset), not just MUL, with a FNEG'd operand?You may custom lower all binops, no matter which one, and create custom nodes if it meets that condition. But I think a better solution would be to add pattern matching rules for all of them systematically. IMO it's cleaner and easier to maintain. You can use multiclasses : multiclass Inst< node op, string opc> { def _rr : Instruction<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), "!strcat(opc, " $dst, $src1, $src2")", [(set $dst, (op GPR32:$src1, GPR32:$src2))]>; def _fneg_rr : Instruction<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), "!strcat(opc, " $dst, -$src1, $src2")", [(set $dst, (op (fneg_su GPR32:$src1), GPR32:$src2)))]>; }> I expect I can > define a PatFrag: > > def fneg_su : PatFrag<(ops node:$val), (fneg node:$val), [{ return > N->hasOneUse(); }]>;AFAIK, you don't need to verify for hasOneUse() because the instruction selector will do it for you. Also, it's too restrictive if fneg_su is used alone in some other matching rule.> and then use that in each target instruction patten in XXXInstrInfo.td, such as: > > def XXX_MUL : XXXInst< > (outs GPR32:$dst), > (ins GPR32:$src1, GPR32:$src2), > "mul $dst, -$src1, $src2", > [(set $dst, (mul (fneg_su GPR32:$src1), GPR32:$src2))]>; > > but I would like to believe there's a way to do this with a Pattern<> > definition instead, with help from PatFrag and the SDNode_XFORM > perhaps. > > I looked at the ARM target code with PatFrag for negated immediates > but that approach doesn't seem possible with register operands, as I > don't know what xform would operate on. With immediates you have a DAG > node you can generate. > > Also, it does seem like this is a folding operation > PerformDAGCombine() could do but that approach seems like it needs to > modify the registerclass, or something similar, that would eventually > get you to a PrintMethod that could insert the dash/negate in front of > the operand. I didn't want to define a 'mirror' registerclass for my > existing register set that would just have the Name as the negated > version. That would have its own complications. Is there a superior > way to do this with DAG combine?I don't see how you can implement this in the combiner phase. May be someone else can help you. Ivan> > Thanks, > Joe > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Thanks for the reply Ivan. I ended up writing a MachineFunctionPass to handle it, using the code for FoldImmediate in the peephole optimizer as a guide. Just thought I'd reply to archive my solution on the mail list. Joe On Fri, May 11, 2012 at 2:55 AM, Ivan Llopard <ivanllopard at gmail.com> wrote:> Hi Joe, > > Le 11/05/2012 02:13, Joe Matarazzo a écrit : > >> I've been unable to come up with the TableGen recipe to match a >> negated operand. My target asm syntax allows the following transform: >> >> FNEG r8, r5 >> MUL r6, r8, r9 >> >> to >> >> MUL r6, -r5, r9 >> >> Is there a Pattern<> syntax that would allow matching *any* opcode (or >> even some subset), not just MUL, with a FNEG'd operand? > > > You may custom lower all binops, no matter which one, and create custom > nodes if it meets that condition. But I think a better solution would be to > add pattern matching rules for all of them systematically. IMO it's cleaner > and easier to maintain. You can use multiclasses : > > multiclass Inst< node op, string opc> { > def _rr : Instruction<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), > "!strcat(opc, " $dst, $src1, $src2")", > [(set $dst, (op GPR32:$src1, GPR32:$src2))]>; > > def _fneg_rr : Instruction<(outs GPR32:$dst), (ins GPR32:$src1, > GPR32:$src2), > "!strcat(opc, " $dst, -$src1, $src2")", > [(set $dst, (op (fneg_su GPR32:$src1), GPR32:$src2)))]>; > > } > >> I expect I can >> define a PatFrag: >> >> def fneg_su : PatFrag<(ops node:$val), (fneg node:$val), [{ return >> N->hasOneUse(); }]>; > > > AFAIK, you don't need to verify for hasOneUse() because the instruction > selector will do it for you. Also, it's too restrictive if fneg_su is used > alone in some other matching rule. > > >> and then use that in each target instruction patten in XXXInstrInfo.td, >> such as: >> >> def XXX_MUL : XXXInst< >> (outs GPR32:$dst), >> (ins GPR32:$src1, GPR32:$src2), >> "mul $dst, -$src1, $src2", >> [(set $dst, (mul (fneg_su GPR32:$src1), GPR32:$src2))]>; >> >> but I would like to believe there's a way to do this with a Pattern<> >> definition instead, with help from PatFrag and the SDNode_XFORM >> perhaps. >> >> I looked at the ARM target code with PatFrag for negated immediates >> but that approach doesn't seem possible with register operands, as I >> don't know what xform would operate on. With immediates you have a DAG >> node you can generate. >> >> Also, it does seem like this is a folding operation >> PerformDAGCombine() could do but that approach seems like it needs to >> modify the registerclass, or something similar, that would eventually >> get you to a PrintMethod that could insert the dash/negate in front of >> the operand. I didn't want to define a 'mirror' registerclass for my >> existing register set that would just have the Name as the negated >> version. That would have its own complications. Is there a superior >> way to do this with DAG combine? > > > I don't see how you can implement this in the combiner phase. May be someone > else can help you. > > Ivan > >> >> Thanks, >> Joe >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reasonably Related Threads
- [LLVMdev] TableGen pattern for negated operand
- [LLVMdev] Help regarding ad new functionality in Backend
- [LLVMdev] Operand order in dag pattern matching in td files
- [LLVMdev] Operand order in dag pattern matching in td files
- [LLVMdev] X86 Tablegen Description and VEX.W