[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