This is an archive of the discontinued LLVM Phabricator instance.

ARM: use "add" instead of "orr" for code size
ClosedPublic

Authored by t.p.northover on Jun 14 2018, 6:34 AM.

Details

Summary

The implementation here is a bit nasty, but the basic idea is that Thumb has more 16-bit encodings available for ADD than it does for ORR. Combine that with LLVM's (slightly perverse) desire to convert adds to ors as the canonical form and we end up with unnecessary bloat on Thumb targets.

So this patch tries to undo that canonicalization where possible. The implementation is not pretty, but I'm not sure there's a better way.

Diff Detail

Repository
rL LLVM

Event Timeline

t.p.northover created this revision.Jun 14 2018, 6:34 AM
efriedma added inline comments.
llvm/lib/Target/ARM/ARMInstrThumb.td
1017

T1Pat?

Are you intentionally avoiding transforming x|256?

t.p.northover added inline comments.Jun 15 2018, 2:32 AM
llvm/lib/Target/ARM/ARMInstrThumb.td
1017

T1Pat?

That seems to require "IsThumb1Only", which I don't want.

Are you intentionally avoiding transforming x|256?

Yes. That would result in a MOV/ADD pair (with restricted register classes). With this patch we get ORR.W with an immediate, which is probably better all round.

It's a bit of a heuristic, and not optimal when both ADD and ORR require a separate immediate. But by that point the only benefit is whether the destination register is tied so I decided to draw the line before that point in my initial patch.

efriedma added inline comments.Jun 15 2018, 11:17 AM
llvm/lib/Target/ARM/ARMInstrThumb.td
1017

That seems to require "IsThumb1Only", which I don't want.

I think it's appropriate.

The way ISel for Thumb2 works is that we never select Thumb1 instructions, which have restrictive register allocation requirements (most instructions only take tGPR). Thumb2SizeReduce runs after register allocation and shrinks the instructions which are equivalent to a Thumb instruction. (This sometimes leads to bad register allocation decisions because the register allocator isn't aware of size reduction, but that's orthogonal to this patch.)

So in Thumb2 mode, you want five patterns, selecting the following five instructions: t2ADDri, t2ADDri12, t2SUBri, t2SUBri12, and t2ADDrr. And you don't want any patterns to select tADDi3, tADDi8, tSUBi8, or tADDrr.

t.p.northover added inline comments.Jun 18 2018, 3:16 AM
llvm/lib/Target/ARM/ARMInstrThumb.td
1017

OK, I'm convinced by your arguments on the Thumb1 side, I hadn't quite realised that was how it worked. But I don't think t2 side is quite right.

For a start, you generally can't map an OR to a SUB (maybe an XOR, but that's getting pretty convoluted). Also, I don't think the t2ADDri12 is needed: any squashable immediate would already be covered by t2ADDri.

t2ADDrr is probably what I had forgotten and led me to my Thumb1 mistake. I'll upload a new patch implementing those bits.

Switched to T1Pat on Thumb-1 side and added t2ADDrr pattern.

efriedma added inline comments.Jun 18 2018, 12:20 PM
llvm/lib/Target/ARM/ARMInstrThumb.td
1017

you generally can't map an OR to a SUB

t2SUBri is just an ISD::ADD with a negated immediate.

any squashable immediate would already be covered by t2ADDri

Sure, but you still save an instruction over the alternative (movw+orrs).

1018

Maybe allow immediates not in the range 0-255 here? Or you could just allow any operand, and depend on pattern precedence to avoid matching this when one of the immediate forms would match instead.

Also, I'd like to see some test coverage for the immediate patterns.

t.p.northover added inline comments.Jun 19 2018, 4:28 AM
llvm/lib/Target/ARM/ARMInstrThumb.td
1017

t2SUBri is just an ISD::ADD with a negated immediate.

OK, but that negation makes it a pretty unlikely combination.

Sure, but you still save an instruction over the alternative (movw+orrs).

Oh, go on then.

1018

Ah yes, a holdover from when that was covering Thumb-2 I think (I wanted to still allow ORR (imm) and ORN (imm)).

Added t2ADDi12 and tests for the immediate cases.

efriedma accepted this revision.Jun 19 2018, 12:16 PM

LGTM

llvm/lib/Target/ARM/ARMInstrThumb2.td
2606

I guess you could specifically try to check that it isn't t2_so_imm, t2_so_imm_not, or imm0_4095, but probably not worth bothering.

This revision is now accepted and ready to land.Jun 19 2018, 12:16 PM
efriedma closed this revision.Sep 11 2018, 6:46 PM

This was merged in r335119.