Gleb Popov via llvm-dev
2019-Jun-25 05:25 UTC
[llvm-dev] How to handle ISD::STORE when both operands are FrameIndex?
On Mon, Jun 24, 2019 at 4:08 PM Tim Northover <t.p.northover at gmail.com> wrote:> On Mon, 24 Jun 2019 at 12:16, Gleb Popov via llvm-dev > <llvm-dev at lists.llvm.org> wrote: > > 1. Where does it come from? Can I do anything to make it not appear? > > It comes from something like: > > %ptr = alloca i8 > %var = alloca i8* > store i8* %ptr, i8** %var > > and in general it's not possible to eliminate the combination. >Aha, thanks.> > 2. If not, how do I change it so that the operand being stored would be > first loaded into a register, and that register would be used instead? > > While the store is being selected LLVM will just treat the value being > stored as a generic pointer-width integer unless you have written a > specific pattern for storing a FrameIndex somewhere.Actually, this is exactly my case. I have a pattern that looks like (store_stack IntRegs:$reg, FIOperand:$i) It worked for me when first operand was a register and now I stumbled upon two FrameIndicies. That's probably> what you want so no need to change anything. > > After that, LLVM will try to select the FrameIndex itself (which > you'll need to support anyway so that you can pass a pointer to a > local variable between functions). > > Generally this seems to be handled by XYZISelDAGToDAG.cpp, which > converts an ISD::FrameIndex into an appropriate arithmetic instruction > that can offset from SP. That gets lowered to actual known offsets > later on, in exactly the same way loads and stores are. > > It's probably done in C++ rather than TableGen because the operands of > these resulting instructions often look pretty weird (for example a > TargetFrameIndex instead of a register). That's mostly speculation > though, I haven't tried to write a bare frameindex pattern. > > Cheers. > > Tim. >On Mon, Jun 24, 2019 at 4:14 PM Krzysztof Parzyszek <kparzysz at quicinc.com> wrote:> FrameIndex values come from objects that are still allocated on the stack > at the time of the SDAG construction. In your case it seems that the > address and the value to store are both on the stack. You don’t need to do > anything in particular with it. If you have a selection pattern of form > “(store RegClassA:$Addr, RegClassB:$Val), (STORE $Addr, $Val)”, then it > will force loading both, Addr and Val into registers. >You mean, LLVM will automagically generate loads? This isn't happening for me. And what's "STORE"? Is it somehow different from "store"? I think someone has added a pattern to match frame index in patterns as> well (it didn’t use to be possible and you had to use ComplexPattern), so > your pattern can handle that directly too. > > > > -- > > Krzysztof Parzyszek kparzysz at quicinc.com LLVM compiler development > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190625/e17b955e/attachment.html>
Tim Northover via llvm-dev
2019-Jun-25 05:59 UTC
[llvm-dev] How to handle ISD::STORE when both operands are FrameIndex?
On Tue, 25 Jun 2019 at 06:26, Gleb Popov via llvm-dev <llvm-dev at lists.llvm.org> wrote:>> While the store is being selected LLVM will just treat the value being >> stored as a generic pointer-width integer unless you have written a >> specific pattern for storing a FrameIndex somewhere. > > Actually, this is exactly my case. I have a pattern that looks like > > (store_stack IntRegs:$reg, FIOperand:$i) > > It worked for me when first operand was a register and now I stumbled upon two FrameIndicies.That looks more like it's storing *to* a FrameIndex than storing a FrameIndex, but it actually shouldn't matter. The same sequence of events I described would happen except the selected bare FrameIndex would feed into the pointer operand of the store rather than the value operand. If you had both kinds of pattern (storing an FI and storing to an FI) and wanted one to have priority you can add a "let AddedComplexity 10" or similar to one of them so that LLVM favours it when both would apply.>> FrameIndex values come from objects that are still allocated on the stack at the time of the SDAG construction. In your case it seems that the address and the value to store are both on the stack. You don’t need to do anything in particular with it. If you have a selection pattern of form “(store RegClassA:$Addr, RegClassB:$Val), (STORE $Addr, $Val)”, then it will force loading both, Addr and Val into registers. > > You mean, LLVM will automagically generate loads? This isn't happening for me."Materializing" would probably have been a less ambiguous choice of words. I wouldn't expect a load instruction on most architectures.> And what's "STORE"? Is it somehow different from "store"?On most targets in LLVM the implemented instruction names are written in capital letters (mostly): ADDrm, MULrr, STRXrs. The STORE there was meant to represent a target-specific store instruction (like you'd get on the RHS of a Pat instantiation) without committing to any particular architecture. Could you describe what *is* happening for you, BTW? Maybe with an "llc -debug" log on a simple example. We might be able to give more specific advice with the actual error. Cheers. Tim.
Gleb Popov via llvm-dev
2019-Jun-26 06:27 UTC
[llvm-dev] How to handle ISD::STORE when both operands are FrameIndex?
On Tue, Jun 25, 2019 at 9:59 AM Tim Northover <t.p.northover at gmail.com> wrote:> On Tue, 25 Jun 2019 at 06:26, Gleb Popov via llvm-dev > <llvm-dev at lists.llvm.org> wrote: > >> While the store is being selected LLVM will just treat the value being > >> stored as a generic pointer-width integer unless you have written a > >> specific pattern for storing a FrameIndex somewhere. > > > > Actually, this is exactly my case. I have a pattern that looks like > > > > (store_stack IntRegs:$reg, FIOperand:$i) > > > > It worked for me when first operand was a register and now I stumbled > upon two FrameIndicies. > > That looks more like it's storing *to* a FrameIndex than storing a > FrameIndex, but it actually shouldn't matter. The same sequence of > events I described would happen except the selected bare FrameIndex > would feed into the pointer operand of the store rather than the value > operand. > > If you had both kinds of pattern (storing an FI and storing to an FI) > and wanted one to have priority you can add a "let AddedComplexity > 10" or similar to one of them so that LLVM favours it when both would > apply. > > >> FrameIndex values come from objects that are still allocated on the > stack at the time of the SDAG construction. In your case it seems that the > address and the value to store are both on the stack. You don’t need to do > anything in particular with it. If you have a selection pattern of form > “(store RegClassA:$Addr, RegClassB:$Val), (STORE $Addr, $Val)”, then it > will force loading both, Addr and Val into registers. > > > > You mean, LLVM will automagically generate loads? This isn't happening > for me. > > "Materializing" would probably have been a less ambiguous choice of > words. I wouldn't expect a load instruction on most architectures. > > > And what's "STORE"? Is it somehow different from "store"? > > On most targets in LLVM the implemented instruction names are written > in capital letters (mostly): ADDrm, MULrr, STRXrs. The STORE there was > meant to represent a target-specific store instruction (like you'd get > on the RHS of a Pat instantiation) without committing to any > particular architecture. > > Could you describe what *is* happening for you, BTW? Maybe with an > "llc -debug" log on a simple example. We might be able to give more > specific advice with the actual error. >Sigh. I'm completely confused and lost. Thanks for bearing with me. Here's my current definition: def AddrFI: ComplexPattern<i32, 1, "SelectAddrFI", [frameindex], []>; class StackAddress : CodePatPred<[{ return cast<MemSDNode>(N)->getAddressSpace() == 1; }]>; class StoreFrag<SDPatternOperator op> : PatFrag < (ops node:$value, node:$ptr), (op node:$value, node:$ptr)>;class StackStore <SDPatternOperator op> : StoreFrag <op>, StackAddress; def store_stack : StackStore<store>; def StoreStackF : InstRI<2, (outs), (ins IntRegs:$reg, i32imm:$i), "storestackf $reg, [$i]", [(store_stack i32:$reg, AddrFI:$i)]>; I'm puzzled why despite having "IntRegs:$reg" in ins list, it still matches FrameIndex: SEL: Starting selection on root node: t14: ch = store<(store 4 into %ir.p45, align 8, addrspace 1)> t10, FrameIndex:i32<2>, FrameIndex:i32<3>, undef:i32 ISEL: Starting pattern match Initial Opcode index to 4 Morphed node: t14: ch = StoreStackF<Mem:(store 4 into %ir.p45, align 8, addrspace 1)> FrameIndex:i32<2>, TargetFrameIndex:i32<3>, t10 ISEL: Match complete! ... ISEL: Starting selection on root node: t11: i32 = FrameIndex<2> ISEL: Starting pattern match Initial Opcode index to 0 Match failed at index 0 LLVM ERROR: Cannot select: t11: i32 = FrameIndex<2>> Cheers. > > Tim. >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190626/f2213f95/attachment.html>