[llvm-dev] ARM Backend: Emit conditional move

Tim Northover via llvm-dev llvm-dev at lists.llvm.org
Mon Feb 13 07:42:42 PST 2017


Hi Robert,

On 13 February 2017 at 09:36, Robert Schilling via llvm-dev
<llvm-dev at lists.llvm.org> wrote:
> BuildMI(&MBB, DL, TII->get(ARM::CMPrr))
>         .addReg(MI.getOperand(1).getReg())
>         .addReg(MI.getOperand(2).getReg())
>         .addImm(ARMCC::EQ);

ARM comparisons don't need to know what kind of comparison they're
actually going to be used for. So that ARMCC::EQ is actually turning
this instruction from a "cmp ..." into a "cmpeq ..." (i.e. only
perform the comparison if a previous compare was "eq").

What you probably want (on trunk LLVM) for that last operand is
"add(predOps(ARMCC::AL))" where "AL" means always.

> BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVr),
>               MI.getOperand(0).getReg())
>           .addImm(ARMCC::EQ)
>           .addImm(1)
>           .addReg(0); // 's' bit

MOVr is a move between two registers, you want the "MOVi" (move
immediate) instruction instead. MOVi takes 3 operands relating to the
condition code (all after the immediate):

First, the options for whether this particular move should be
predicated (like the CMPrr) above. There are two of these operands,
first an ARMCC value, and then a register which should be 0 if you're
using ARMCC::AL and ARM::CPSR otherwise (this is used to track which
instructions actually use CPSR, and obviously an instruction that's
always executed doesn't). This is what the predOps does above.

Second, there's another register argument which is set based on
whether this instruction should *set* the CPSR flags register. Since
you don't want this, you should use 0 (== NoReg). In trunk you'd write
"add(condCodeOp())" for that.

Putting it all together I think this last one should be

BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVi),
              MI.getOperand(0).getReg())
          .addImm(1)
          .add(predOps(ARMCC::EQ)
          .add(condCodeOp());

It's worth noting that this'll only work in ARM mode. Thumb mode has a
completely different set of instructions in LLVM, usually starting
with "t" or "t2".

Hope this helps.

Tim.


More information about the llvm-dev mailing list