[LLVMdev] TableGen pattern for negated operand
Joe Matarazzo
joe.matarazzo at gmail.com
Tue May 15 10:42:57 PDT 2012
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
More information about the llvm-dev
mailing list