[AArch64][GlobalISel] Select CSINC and CSINV for G_SELECT with constants
authorJessica Paquette <jpaquette@apple.com>
Tue, 3 Nov 2020 19:08:08 +0000 (11:08 -0800)
committerJessica Paquette <jpaquette@apple.com>
Thu, 12 Nov 2020 22:44:01 +0000 (14:44 -0800)
commitd0ba6c4002e455cc005ca3f4baca36f2d199582f
treecc2995d5e456926881963f4d74a466da1a20cb9c
parent410626c9b56a2844652dcff9ca23765a6918186f
[AArch64][GlobalISel] Select CSINC and CSINV for G_SELECT with constants

Select the following:

- G_SELECT cc, 0, 1 -> CSINC zreg, zreg, cc
- G_SELECT cc 0, -1 -> CSINV zreg, zreg cc
- G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc
- G_SELECT cc, -1, f -> CSINV f, zreg, inv_cc
- G_SELECT cc, t, 1 -> CSINC t, zreg, cc
- G_SELECT cc, t, -1 -> CSINC t, zreg, cc

(IR example: https://godbolt.org/z/YfPna9)

These correspond to a bunch of the AArch64csel patterns in AArch64InstrInfo.td.

Unfortunately, it doesn't seem like we can import patterns that use NZCV like
those ones do. E.g.

```
def : Pat<(AArch64csel GPR32:$tval, (i32 1), (i32 imm:$cc), NZCV),
          (CSINCWr GPR32:$tval, WZR, (i32 imm:$cc))>;
```

So we have to manually select these for now.

This replaces `selectSelectOpc` with an `emitSelect` function, which performs
these optimizations.

Differential Revision: https://reviews.llvm.org/D90701
llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
llvm/test/CodeGen/AArch64/GlobalISel/opt-fold-compare.mir
llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir