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(N)->getAddressSpace() == 1;
}]>;
class StoreFrag : PatFrag <
(ops node:$value, node:$ptr), (op node:$value, node:$ptr)
;
class StackStore : StoreFrag , StackAddress;
def store_stack : StackStore;
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>