Best way to get direct memory for intrinsics in tblgen?

What’s the best way to get direct memory accesses for intrinsics via tblgen?

We have some instructions represented as intrinsics. These instructions allow direct memory access, I’ve tried multiclasses but they won’t match. I’ve also tried "def : Pat<…> but it won’t recognize the complex pattern as a valid operand?


To be more specific:

We have some operators that we are currently implementing as intrinsics, for example things like: abs, min, max, etc…

for some code:

int a;

int food()
return abs(a);

the corresponding operator should look something like:

abs $a, r0

however, it looks like since intrinsics are handled as ‘calls’, we end up with something like:

mov $a, r0
abs r0, r0

Would it be better to make ‘abs’ an operator as opposed to an intrinsic, or is it possible in LLVM to support direct mem loads/stores via intrinsics?

I realize that we could resolve this with some peephole opts, I just want to know if there is a way in LLVM to get the ‘abs $a, r0’ match directly through tblgen?


I assume that what you mean by “operator” is called “machine instruction” in LLVM.
It seems from the snippet you show "abs r0, r0” that the intrinsic call is correctly turned into a native instruction and not a runtime call, so the intrinsic is somehow matched.

What pattern have you tried to match the sequence abs(load(x)) in tblgen?
If you try to grep for “load” in the X86 backend tblgen files you should find examples of pattern.

@Alex: Thanks. setOffset(0) eliminated any previous offsets, of course, so I added another param (int64_t Offset) and am adding that, this should preserve the orginial offset of the GA.

@Mehdi: This is what is slightly confusing. Yes, I have all direct mem ops currently working, for example ‘add’ (along with other native ‘llvm instructions’) can take an imm, reg or mem as any of it’s operands, either src or dst (obviously not imm for dst). For example ‘add, @a, r0, @b’ is working just fine currently, that is global a + reg = global b is currently supported. The only issue we are having is with intrinsics.


Let me be more specific, sorry. This is a pattern we have to match mmr:

set dstReg:$dstD, (OpNode (srcAType (load addr:$srcA)), (srcBType (load addr:$srcB))))

where dstReg is a RegisterClass, OpNode = SDPatternOperator, srcAType and srcBType = ValueType…

instructions like add, sub, shl, srl, sra, mul, div, etc… are matching this pattern just fine but when we make an intrinsic and try to match it, it will only match the all regs version.

It is confusing because it still matches (rather than making a call) but it seems that somewhere previously in the pipe the params are already setup in regs, so when it gets to matching, the regs have already been loaded.

I suppose we could extend the pattern to handle the load of regs also, yes? Maybe that’s what we need to look at?