[LLVMdev] Backend port: Adding negative immediates

Richard Osborne richard at xmos.com
Mon Mar 25 01:34:14 PDT 2013

On 25 Mar 2013, at 00:16, Jan Tlatlik <jtlatlik at techfak.uni-bielefeld.de> wrote:

> Hi,
> I'm doing a backend port and I'm having trouble with adds that have
> negative immediates.
> My architecture only has instructions for subtracting and adding 8bit
> immediate values (they will be zero-extended, thus unsigned).
> Bigger immediates have to be moved in a register first.
> The problem is:
> Expressions like "b - 1" result in "add nsw i32 %b, -1" in LLVM IR.
> They cannot be matched to the 8bit unsigned immediate add during
> Instruction Selection and will eventually be moved in a register.
> It would be better to transform these adds with small negative
> immediates into subs during Target Lowering.

Instead of trying to handle this during target lowering you can add a pattern to your InstructionInfo.td that matches the add node with a negative immediate. In the XCore backend the SUB_2rus instruction takes an immediate in the range 0-11 and this is handled by the following pattern:

// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
def : Pat<(add GRRegs:$src1, immUsNeg:$src2),
          (SUB_2rus GRRegs:$src1, (neg_xform immUsNeg:$src2))>;

Where immUsNeg and neg_xform are defined as follows:

def immUsNeg : PatLeaf<(imm), [{
  return -((uint32_t)N->getZExtValue()) <= 11;

def neg_xform : SDNodeXForm<imm, [{
  // Transformation function: -imm
  uint32_t value = N->getZExtValue();
  return getI32Imm(-value);

More information about the llvm-dev mailing list