Alex Bradley via llvm-dev
2016-Oct-10 14:23 UTC
[llvm-dev] Generate Register Indirect mode instruction
Hi All, I am new to llvm backend. I am trying out few examples to understand backend codegen. I have ported llvm LEG @ https://github.com/frasercrmck/llvm-leg to llvm 3.9 successfully. Currently, the LEG instructions are RISC load-store type instruction. I want to generate some instructions for register indirect mode, like following: IR: @a = local_unnamed_addr global i32 0, align 4 @b = local_unnamed_addr global i32 0, align 4 @c = local_unnamed_addr global i32 0, align 4 ; Function Attrs: norecurse nounwind define void @foo() { entry: %0 = load i32, i32* @a, align 4 %1 = load i32, i32* @b, align 4 %add = add nsw i32 %1, %0 store i32 %add, i32* @c, align 4 ret void } Expected assembly instructions: MOV R0, #A // R0 pointing to address of A MOV R1, #B // R1 pointing to address of B ADD *R0, *R1 // Adding both memory operands MOV #C, *R0 // Moving result to address of C How should i define such mov and add instruction in my .td files? How will ISD::LOAD be seleted in ISelDAGtoDAG in select() function? I want to start with simple .td definitions and would later like to encapsulate them in multiclass once basic example works. Can someone please help how to achieve this? Regards, Alex -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161010/f336bdd5/attachment.html>
Ryan Taylor via llvm-dev
2016-Oct-10 15:22 UTC
[llvm-dev] Generate Register Indirect mode instruction
Alex, So, you are trying to do direct mem to mem add? Like: ADD A, B, C -Ryan On Mon, Oct 10, 2016 at 10:23 AM, Alex Bradley via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hi All, > > I am new to llvm backend. I am trying out few examples to understand > backend codegen. I have ported llvm LEG @ https://github.com/ > frasercrmck/llvm-leg to llvm 3.9 successfully. > > Currently, the LEG instructions are RISC load-store type instruction. I > want to generate some instructions for register indirect mode, like > following: > > IR: > > @a = local_unnamed_addr global i32 0, align 4 > @b = local_unnamed_addr global i32 0, align 4 > @c = local_unnamed_addr global i32 0, align 4 > > ; Function Attrs: norecurse nounwind > define void @foo() { > entry: > %0 = load i32, i32* @a, align 4 > %1 = load i32, i32* @b, align 4 > %add = add nsw i32 %1, %0 > store i32 %add, i32* @c, align 4 > ret void > } > > > Expected assembly instructions: > MOV R0, #A // R0 pointing to address of A > MOV R1, #B // R1 pointing to address of B > ADD *R0, *R1 // Adding both memory operands > MOV #C, *R0 // Moving result to address of C > > How should i define such mov and add instruction in my .td files? How will > ISD::LOAD be seleted in ISelDAGtoDAG in select() function? I want to start > with simple .td definitions and would later like to encapsulate them in > multiclass once basic example works. > > Can someone please help how to achieve this? > > Regards, > Alex > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161010/d15616ec/attachment.html>
Alex Bradley via llvm-dev
2016-Oct-10 16:01 UTC
[llvm-dev] Generate Register Indirect mode instruction
Hi Ryan, Somewhat yes. But the memory locations should be pointed by registers. Essentially, load the address of memory location onto the registers and then use them to point to memory location. Regards, Alex On 10 Oct 2016 8:52 p.m., "Ryan Taylor" <ryta1203 at gmail.com> wrote:> Alex, > > So, you are trying to do direct mem to mem add? > > Like: ADD A, B, C > > -Ryan > > On Mon, Oct 10, 2016 at 10:23 AM, Alex Bradley via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > >> Hi All, >> >> I am new to llvm backend. I am trying out few examples to understand >> backend codegen. I have ported llvm LEG @ https://github.com/frasercrmck >> /llvm-leg to llvm 3.9 successfully. >> >> Currently, the LEG instructions are RISC load-store type instruction. I >> want to generate some instructions for register indirect mode, like >> following: >> >> IR: >> >> @a = local_unnamed_addr global i32 0, align 4 >> @b = local_unnamed_addr global i32 0, align 4 >> @c = local_unnamed_addr global i32 0, align 4 >> >> ; Function Attrs: norecurse nounwind >> define void @foo() { >> entry: >> %0 = load i32, i32* @a, align 4 >> %1 = load i32, i32* @b, align 4 >> %add = add nsw i32 %1, %0 >> store i32 %add, i32* @c, align 4 >> ret void >> } >> >> >> Expected assembly instructions: >> MOV R0, #A // R0 pointing to address of A >> MOV R1, #B // R1 pointing to address of B >> ADD *R0, *R1 // Adding both memory operands >> MOV #C, *R0 // Moving result to address of C >> >> How should i define such mov and add instruction in my .td files? How >> will ISD::LOAD be seleted in ISelDAGtoDAG in select() function? I want to >> start with simple .td definitions and would later like to encapsulate them >> in multiclass once basic example works. >> >> Can someone please help how to achieve this? >> >> Regards, >> Alex >> >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161010/3a2b452f/attachment.html>
Ryan Taylor via llvm-dev
2016-Oct-12 17:40 UTC
[llvm-dev] Fwd: Generate Register Indirect mode instruction
Could you eliminate the load in the DAG and propagate the address to the add? Have you tried this, I'm curious. Then in table gen, just match the add appropriately. -Ryan On Mon, Oct 10, 2016 at 12:01 PM, Alex Bradley <alexbradley.bqc at gmail.com> wrote:> Hi Ryan, > > Somewhat yes. But the memory locations should be pointed by registers. > Essentially, load the address of memory location onto the registers and > then use them to point to memory location. > > Regards, > Alex > > On 10 Oct 2016 8:52 p.m., "Ryan Taylor" <ryta1203 at gmail.com> wrote: > >> Alex, >> >> So, you are trying to do direct mem to mem add? >> >> Like: ADD A, B, C >> >> -Ryan >> >> On Mon, Oct 10, 2016 at 10:23 AM, Alex Bradley via llvm-dev < >> llvm-dev at lists.llvm.org> wrote: >> >>> Hi All, >>> >>> I am new to llvm backend. I am trying out few examples to understand >>> backend codegen. I have ported llvm LEG @ https://github.com/frasercrmck >>> /llvm-leg to llvm 3.9 successfully. >>> >>> Currently, the LEG instructions are RISC load-store type instruction. I >>> want to generate some instructions for register indirect mode, like >>> following: >>> >>> IR: >>> >>> @a = local_unnamed_addr global i32 0, align 4 >>> @b = local_unnamed_addr global i32 0, align 4 >>> @c = local_unnamed_addr global i32 0, align 4 >>> >>> ; Function Attrs: norecurse nounwind >>> define void @foo() { >>> entry: >>> %0 = load i32, i32* @a, align 4 >>> %1 = load i32, i32* @b, align 4 >>> %add = add nsw i32 %1, %0 >>> store i32 %add, i32* @c, align 4 >>> ret void >>> } >>> >>> >>> Expected assembly instructions: >>> MOV R0, #A // R0 pointing to address of A >>> MOV R1, #B // R1 pointing to address of B >>> ADD *R0, *R1 // Adding both memory operands >>> MOV #C, *R0 // Moving result to address of C >>> >>> How should i define such mov and add instruction in my .td files? How >>> will ISD::LOAD be seleted in ISelDAGtoDAG in select() function? I want to >>> start with simple .td definitions and would later like to encapsulate them >>> in multiclass once basic example works. >>> >>> Can someone please help how to achieve this? >>> >>> Regards, >>> Alex >>> >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>> >>> >>-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161012/67e13426/attachment.html>
Alex Bradley via llvm-dev
2016-Oct-12 20:54 UTC
[llvm-dev] Generate Register Indirect mode instruction
Hi Ryan, Do you mean something like this - @a = local_unnamed_addr global i32 0, align 4 @b = local_unnamed_addr global i32 0, align 4 @c = local_unnamed_addr global i32 0, align 4 ; Function Attrs: norecurse nounwind define void @foo() { entry: %add = add nsw i32 @a, @b store i32 %add, i32* @c, align 4 ret void } If yes, should this be done at IR level or SelectionDAG? Any side effect of doing it at IR level? But above seems memory to memory without involving registers to point to memory locations, which doesn't match the addressing mode of my target. Thanks. Regards, Alex> On 12 Oct 2016 11:09 p.m., "Ryan Taylor" <ryta1203 at gmail.com> wrote: >> >> Could you eliminate the load in the DAG and propagate the address to theadd? Have you tried this, I'm curious.>> >> Then in table gen, just match the add appropriately. >> >> -Ryan >> >> On Mon, Oct 10, 2016 at 12:01 PM, Alex Bradley <alexbradley.bqc at gmail.com>wrote:>>> >>> Hi Ryan, >>> >>> Somewhat yes. But the memory locations should be pointed by registers.Essentially, load the address of memory location onto the registers and then use them to point to memory location.>>> >>> Regards, >>> Alex >>> >>> >>> On 10 Oct 2016 8:52 p.m., "Ryan Taylor" <ryta1203 at gmail.com> wrote: >>>> >>>> Alex, >>>> >>>> So, you are trying to do direct mem to mem add? >>>> >>>> Like: ADD A, B, C >>>> >>>> -Ryan >>>> >>>> On Mon, Oct 10, 2016 at 10:23 AM, Alex Bradley via llvm-dev <llvm-dev at lists.llvm.org> wrote:>>>>> >>>>> Hi All, >>>>> >>>>> I am new to llvm backend. I am trying out few examples to understandbackend codegen. I have ported llvm LEG @ https://github.com/frasercrmck/llvm-leg to llvm 3.9 successfully.>>>>> >>>>> Currently, the LEG instructions are RISC load-store type instruction.I want to generate some instructions for register indirect mode, like following:>>>>> >>>>> IR: >>>>> >>>>> @a = local_unnamed_addr global i32 0, align 4 >>>>> @b = local_unnamed_addr global i32 0, align 4 >>>>> @c = local_unnamed_addr global i32 0, align 4 >>>>> >>>>> ; Function Attrs: norecurse nounwind >>>>> define void @foo() { >>>>> entry: >>>>> %0 = load i32, i32* @a, align 4 >>>>> %1 = load i32, i32* @b, align 4 >>>>> %add = add nsw i32 %1, %0 >>>>> store i32 %add, i32* @c, align 4 >>>>> ret void >>>>> } >>>>> >>>>> >>>>> Expected assembly instructions: >>>>> MOV R0, #A // R0 pointing to address of A >>>>> MOV R1, #B // R1 pointing to address of B >>>>> ADD *R0, *R1 // Adding both memory operands >>>>> MOV #C, *R0 // Moving result to address of C >>>>> >>>>> How should i define such mov and add instruction in my .td files? Howwill ISD::LOAD be seleted in ISelDAGtoDAG in select() function? I want to start with simple .td definitions and would later like to encapsulate them in multiclass once basic example works.>>>>> >>>>> Can someone please help how to achieve this? >>>>> >>>>> Regards, >>>>> Alex >>>>> >>>>> >>>>> _______________________________________________ >>>>> LLVM Developers mailing list >>>>> llvm-dev at lists.llvm.org >>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>>>> >>>> >>-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161012/faf84067/attachment.html>
Friedman, Eli via llvm-dev
2016-Oct-12 21:10 UTC
[llvm-dev] Generate Register Indirect mode instruction
On 10/10/2016 7:23 AM, Alex Bradley via llvm-dev wrote:> Hi All, > > I am new to llvm backend. I am trying out few examples to understand > backend codegen. I have ported llvm LEG @ > https://github.com/frasercrmck/llvm-leg to llvm 3.9 successfully. > > Currently, the LEG instructions are RISC load-store type instruction. > I want to generate some instructions for register indirect mode, like > following: > > IR: > > @a = local_unnamed_addr global i32 0, align 4 > @b = local_unnamed_addr global i32 0, align 4 > @c = local_unnamed_addr global i32 0, align 4 > > ; Function Attrs: norecurse nounwind > define void @foo() { > entry: > %0 = load i32, i32* @a, align 4 > %1 = load i32, i32* @b, align 4 > %add = add nsw i32 %1, %0 > store i32 %add, i32* @c, align 4 > ret void > } > > > Expected assembly instructions: > MOV R0, #A // R0 pointing to address of A > MOV R1, #B // R1 pointing to address of B > ADD *R0, *R1 // Adding both memory operands > MOV #C, *R0 // Moving result to address of C > > How should i define such mov and add instruction in my .td files? How > will ISD::LOAD be seleted in ISelDAGtoDAG in select() function? I want > to start with simple .td definitions and would later like to > encapsulate them in multiclass once basic example works. > > Can someone please help how to achieve this?You probably want to look at the x86 backend; it has a lot of instructions which involve both computation and memory. Take the following IR, a variant of your example: define void @foo(i32 *%a, i32 *%b, i32 *%c) { entry: %0 = load i32, i32* %a, align 4 %1 = load i32, i32* %b, align 4 %add = add nsw i32 %1, %0 store i32 %add, i32* %c, align 4 ret void } The x86 backend generates the following: movl (%rsi), %eax addl (%rdi), %eax movl %eax, (%rdx) retq Note in particular the memory operand embedded into the addition. The way the LLVM x86 backend models this is just to pattern match it during instruction selection: it matches a pattern like (add r, (load addr)) to a single instruction. -Eli -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Alex Bradley via llvm-dev
2016-Oct-12 21:22 UTC
[llvm-dev] Generate Register Indirect mode instruction
> You probably want to look at the x86 backend; it has a lot ofinstructions which involve both computation and memory. Take the following IR, a variant of your example:> > define void @foo(i32 *%a, i32 *%b, i32 *%c) { > entry: > %0 = load i32, i32* %a, align 4 > %1 = load i32, i32* %b, align 4 > > %add = add nsw i32 %1, %0 > store i32 %add, i32* %c, align 4 > ret void > } > > The x86 backend generates the following: > > movl (%rsi), %eax > addl (%rdi), %eax > movl %eax, (%rdx) > retq > > Note in particular the memory operand embedded into the addition. > > The way the LLVM x86 backend models this is just to pattern match itduring instruction selection: it matches a pattern like (add r, (load addr)) to a single instruction. Thanks Eli. I will have a look into it. However, the above x86 code loads the content of the memory location into eax register and adds that register with another memory location. My target loads the address of the memory locations in the registers for both the operands and then uses add operation on the registers in an indirect way. How do I specify that in .td files so that it matches in ISelDAGToDAG select() function? Any small example? Thanks for example code :) Regards, Alex -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161012/21a3e6ca/attachment.html>
Ryan Taylor via llvm-dev
2016-Oct-12 21:36 UTC
[llvm-dev] Generate Register Indirect mode instruction
He's trying to load the memory address of the pointer. The (add r, (load addr)) is what we use for direct memory. I think you'll probably have to do a post iSel MI pass. On Oct 12, 2016 17:22, "Alex Bradley via llvm-dev" <llvm-dev at lists.llvm.org> wrote:> > > You probably want to look at the x86 backend; it has a lot of > instructions which involve both computation and memory. Take the following > IR, a variant of your example: > > > > define void @foo(i32 *%a, i32 *%b, i32 *%c) { > > entry: > > %0 = load i32, i32* %a, align 4 > > %1 = load i32, i32* %b, align 4 > > > > %add = add nsw i32 %1, %0 > > store i32 %add, i32* %c, align 4 > > ret void > > } > > > > The x86 backend generates the following: > > > > movl (%rsi), %eax > > addl (%rdi), %eax > > movl %eax, (%rdx) > > retq > > > > Note in particular the memory operand embedded into the addition. > > > > The way the LLVM x86 backend models this is just to pattern match it > during instruction selection: it matches a pattern like (add r, (load > addr)) to a single instruction. > > Thanks Eli. I will have a look into it. However, the above x86 code loads > the content of the memory location into eax register and adds that register > with another memory location. > > My target loads the address of the memory locations in the registers for > both the operands and then uses add operation on the registers in an > indirect way. How do I specify that in .td files so that it matches in > ISelDAGToDAG select() function? Any small example? > > Thanks for example code :) > > Regards, > Alex > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161012/fc45436f/attachment.html>
Friedman, Eli via llvm-dev
2016-Oct-12 22:09 UTC
[llvm-dev] Generate Register Indirect mode instruction
On 10/12/2016 2:22 PM, Alex Bradley wrote:> > > > You probably want to look at the x86 backend; it has a lot of > instructions which involve both computation and memory. Take the > following IR, a variant of your example: > > > > define void @foo(i32 *%a, i32 *%b, i32 *%c) { > > entry: > > %0 = load i32, i32* %a, align 4 > > %1 = load i32, i32* %b, align 4 > > > > %add = add nsw i32 %1, %0 > > store i32 %add, i32* %c, align 4 > > ret void > > } > > > > The x86 backend generates the following: > > > > movl (%rsi), %eax > > addl (%rdi), %eax > > movl %eax, (%rdx) > > retq > > > > Note in particular the memory operand embedded into the addition. > > > > The way the LLVM x86 backend models this is just to pattern match it > during instruction selection: it matches a pattern like (add r, (load > addr)) to a single instruction. > > Thanks Eli. I will have a look into it. However, the above x86 code > loads the content of the memory location into eax register and adds > that register with another memory location. > > My target loads the address of the memory locations in the registers > for both the operands and then uses add operation on the registers in > an indirect way. How do I specify that in .td files so that it matches > in ISelDAGToDAG select() function? Any small example? >Oh, you mean the result goes into memory, not a register? So, something like the following: define void @foo(i32 *%a) { entry: %0 = load i32, i32* %a, align 4 %add = add i32 %0, 3 store i32 %add, i32* %a, align 4 ret void } On x86, this gets turned into: addl $3, (%rdi) retq From X86InstrArithmetic.td: // BinOpMI8_RMW - Instructions like "add [mem], imm8". class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo, SDPatternOperator opnode, Format f> : BinOpMI8<mnemonic, typeinfo, f, [(store (opnode (load addr:$dst), typeinfo.Imm8Operator:$src), addr:$dst), (implicit EFLAGS)]>; -Eli -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Seemingly Similar Threads
- Generate Register Indirect mode instruction
- [LLVMdev] Operand order in dag pattern matching in td files
- [LLVMdev] Operand order in dag pattern matching in td files
- Instruction selection confusion at register - chooses vector register instead of scalar one
- Immediate operand for load instruction, in back end