[llvm-dev] Add a custom intrinsic to the ARM backend

Tim Northover via llvm-dev llvm-dev at lists.llvm.org
Fri Feb 10 09:21:11 PST 2017


Hi Max,

On 10 February 2017 at 07:10, Max Muster via llvm-dev
<llvm-dev at lists.llvm.org> wrote:
> AFAIK, BuildMI() expects another parameter for the destination but how to
> retrieve that from the pseudo instruction?

If you've got a MachineInstr that looks like this when dumped:

%R0<def> = FOO_CMP %R1, %R2

Then the registers are just the operands of the MachineInstr labelled
from left to right. So the "return" register, the def is operand 0.

> In the future, the implementation of this instruction will get more complex
> and requires a temporary register for computation. How can I allocate a
> register at that stage of compiling?

You've got a couple of options there.

You could pick a random, fixed, register and tell LLVM that FOO_CMP
clobbers that one by (e.g. putting "let Defs = [R0]" in the
instruction definition. Then LLVM will make sure R0 isn't live across
that instruction, but of course that might lead to poorer code
generation.

The better way to do it would be to add an explicit extra out operand
to your instruction. Then after selection your instruction would look
something like:

  %vreg0<def>, %vreg1<def,dead> = FOO_CMP ...

and you'd eventually check operand 1 for the register you've been
allocated to use temporarily.

An example of this is AArch64's CMP_SWAP instructions in
AArch64InstrAtomics.td. The "@earlyclobber" is important, otherwise
LLVM might make one of the inputs the same as the scratch register,
and you probably don't want that.

One other slight wrinkle is that you'll have to write your pattern
separately, rather than as part of the instruction definition,
otherwise TableGen complains that $scratch isn't defined.

Hope this helps.

Tim.


More information about the llvm-dev mailing list