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

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

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

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

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

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
4014

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

4017

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
4014

Deferring this work for another day.

4017

Again, deferring this for now.

gberry added inline comments.Aug 26 2016, 10:39 AM
lib/Target/AArch64/AArch64ISelLowering.cpp
4051

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.