This is an archive of the discontinued LLVM Phabricator instance.

[AArch64] Avoid materializing constant values when generating csel instructions.
ClosedPublic

Authored by mcrosier on Aug 18 2016, 10:32 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

mcrosier updated this revision to Diff 68561.Aug 18 2016, 10:32 AM
mcrosier retitled this revision from to [AArch64] Reuse register with known value when generating csneg and csinv instructions..
mcrosier updated this object.
mcrosier added subscribers: llvm-commits, gberry, MatzeB, evandro.
efriedma added inline comments.Aug 18 2016, 11:51 AM
test/CodeGen/AArch64/arm64-csel.ll
241 ↗(On Diff #68561)

Currently, trunk generates the following for foo20:

cmp     w0, #1
orr     w8, wzr, #0x1
cneg    w0, w8, ne
ret

This is "w0 == 1 ? 1 : -1"

With your patch, we generate... this?

cmp     w0, #1
cneg    w0, w0, ne
ret

Unless I'm missing something, this is "w0 == 1 ? w0 : -w0", which is not the same thing.

mcrosier added inline comments.Aug 18 2016, 12:11 PM
test/CodeGen/AArch64/arm64-csel.ll
241 ↗(On Diff #68561)

Ah, yes.. For example, if w0 holds 5 the cneg would put -5 in w0, rather than -1.

mcrosier updated this revision to Diff 68597.Aug 18 2016, 1:08 PM
mcrosier retitled this revision from [AArch64] Reuse register with known value when generating csneg and csinv instructions. to [AArch64] Avoid materializing -1 values when generating csinv instructions..
mcrosier updated this object.

I've uploaded a new patch, which was my original solution to solving PR28965. My first patch tried to be more general, but obviously made an incorrect assumption.

efriedma added inline comments.Aug 18 2016, 6:15 PM
lib/Target/AArch64/AArch64ISelLowering.cpp
4001 ↗(On Diff #68597)

There are really two transformations going on here...

  1. You can avoid materializing -1 using CSINV on the zero register. (Similarly, you can avoid materializing 1 with CSINC on the zero register.)
  2. You can transform "a == C ? C : x" to "a == C ? a : x" to avoid materializing C.

We want to perform each of these transformations whether or not the other is possible.

mcrosier marked 2 inline comments as done.Aug 19 2016, 8:24 AM
mcrosier added inline comments.
lib/Target/AArch64/AArch64ISelLowering.cpp
4001 ↗(On Diff #68597)

I made the same realization last night.

I've been working on a new patch this morning. This general transform (#2) is applicable to CSEL, CSNEG, CSINV, etc. Transform #1 is specific to CSINV and is independent of tranform #2 as you've already pointed out.

I'll post a revised patch shortly.

mcrosier updated this revision to Diff 69006.Aug 23 2016, 9:15 AM
mcrosier retitled this revision from [AArch64] Avoid materializing -1 values when generating csinv instructions. to [AArch64] Avoid materializing constant values when generating csel/csinv/csinc instructions..

-Address Eli's comment.

mcrosier marked 2 inline comments as done.Aug 23 2016, 9:16 AM

Possibly interesting testcase: "x == 7 ? 7 : -1". Should generate cmp+csinv. Also, the related "x == 7 ? 7 : 1" should generate cmp+csinc.

lib/Target/AArch64/AArch64ISelLowering.cpp
4003 ↗(On Diff #69006)

Maybe you could just make this fall through to the general case, rather than explicitly selecting CSINV?

4015 ↗(On Diff #69006)

Maybe it makes sense to write something more like if ((TrueVal == SignExtend64(FalseVal + 1, ValueBits)) || (SignExtend64(TrueVal + 1, ValueBits) == FalseVal)) {. This also applies to your later code.

mcrosier updated this revision to Diff 69393.Aug 26 2016, 10:20 AM
mcrosier retitled this revision from [AArch64] Avoid materializing constant values when generating csel/csinv/csinc instructions. to [AArch64] Avoid materializing constant values when generating csel instructions..
mcrosier added a reviewer: efriedma.
mcrosier removed a subscriber: efriedma.

I found very few cases where the csinc/csinv optimizations actually hit, so I'm limiting this patch to just csel to simplify the logic/review.

mcrosier marked 2 inline comments as done.Aug 26 2016, 10:20 AM
mcrosier added inline comments.
lib/Target/AArch64/AArch64ISelLowering.cpp
4002 ↗(On Diff #69393)

Deferring this work for another day.

4005 ↗(On Diff #69393)

Again, deferring this for now.

gberry added inline comments.Aug 26 2016, 10:39 AM
lib/Target/AArch64/AArch64ISelLowering.cpp
4039 ↗(On Diff #69393)

typo "know" -> "known"

mcrosier updated this revision to Diff 69399.Aug 26 2016, 10:43 AM
mcrosier marked 3 inline comments as done.

Address Geoff's comment.

efriedma accepted this revision.Aug 26 2016, 11:01 AM
efriedma edited edge metadata.

LGTM.

This revision is now accepted and ready to land.Aug 26 2016, 11:01 AM
This revision was automatically updated to reflect the committed changes.