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
Alex Bradley via llvm-dev
2016-Oct-12 22:15 UTC
[llvm-dev] Generate Register Indirect mode instruction
Yes the result goes into memory. But the *address* of that destination memory location also needs to be loaded first into a register. Thanks. Regards, Alex On 13 Oct 2016 3:39 a.m., "Friedman, Eli" <efriedma at codeaurora.org> wrote:> 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 > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161012/748fa4f0/attachment.html>
Friedman, Eli via llvm-dev
2016-Oct-12 22:45 UTC
[llvm-dev] Generate Register Indirect mode instruction
On 10/12/2016 3:15 PM, Alex Bradley wrote:> > Yes the result goes into memory. But the *address* of that destination > memory location also needs to be loaded first into a register. >Your architecture has a single instruction for the following operation? define void @foo(i32 **%a, i32**%b) { entry: %l1 = load i32*, i32** %a, align 4 %l2 = load i32, i32* %l1, align 4 %l3 = load i32*, i32** %b, align 4 %l4 = load i32, i32* %l3, align 4 %add = add i32 %l2, %l4 store i32 %add, i32* %l1, align 4 ret void } In theory, it should be possible to match this, at least using C++ code. There isn't any other architecture like that in LLVM, though, so I'm not sure how that would work out in practice. -Eli -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161012/f5af4513/attachment.html>