Undoing DAG Combiner patterns

Hi all,

It’s the first LLVM backend we do for our asynchronous DSP. So, I apologize if this is a trivial question!

The target-independent DAG combiner performs the following transformation:

sub n, c → add n, -c

For our target, negative constants are more costly to encode. What is the best place to revert to a sub instruction?

Kind regards,

– Martin

www.octasic.com

Hi all,

It's the first LLVM backend we do for our asynchronous DSP. So, I apologize if this is a trivial question!

The target-independent DAG combiner performs the following transformation:

sub n, c -> add n, -c

It looks to me like this transformation would happen during the
legalization phase. Is sub legal on your target? If not, you
can custom lower it e.g.:

setOperationAction(ISD::SUB, MVT::i32, Custom);

and then handle ISD::SUB in the TargetLowering::LowerOperation()
function.

-Tom

A better way to handle this is to a td pattern to match "add n, -c" to a subtraction. I believe several targets do something similar to this.

Evan

Thanks all,

I've found exactly what I was looking for in the ARM backend. My early attempt was missing the "AddedComplexity" setting.

// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
// The assume-no-carry-in form uses the negation of the input since add/sub
// assume opposite meanings of the carry flag (i.e., carry == !borrow).
// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
// details.
// The AddedComplexity preferences the first variant over the others since
// it can be shrunk to a 16-bit wide encoding, while the others cannot.
let AddedComplexity = 1 in
def : T2Pat<(add GPR:$src, imm1_255_neg:$imm),
            (t2SUBri GPR:$src, imm1_255_neg:$imm)>;
def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
            (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
            (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
def : T2Pat<(add GPR:$src, imm0_65535_neg:$imm),
            (t2SUBrr GPR:$src, (t2MOVi16 (imm_neg_XFORM imm:$imm)))>;

Regards,

-Martin