Only match BMI (BLSR, BLSI, BLSMSK) if the add/sub op is single use
authorNoah Goldstein <goldstein.w.n@gmail.com>
Mon, 6 Feb 2023 18:05:10 +0000 (12:05 -0600)
committerNoah Goldstein <goldstein.w.n@gmail.com>
Mon, 6 Feb 2023 20:09:17 +0000 (14:09 -0600)
commit725b72c1fa608c886a1a5dbb75df23a05e91d5e8
treef525080f1fb1d26f27f0a2bccc295fb9d1e367ed
parent3857d9decc4db2a0f14fd7cb7cd69be55f12cc4a
Only match BMI (BLSR, BLSI, BLSMSK) if the add/sub op is single use

If the add/sub is not single use, it will need to be materialized
later, in which case using the BMI instruction is a de-optimization in
terms of code-size and throughput.

i.e:
```
// Good
leal -1(%rdi), %eax
andl %eax, %eax
xorl %eax, %esi
...
```
```
// Unecessary BMI (lower throughput, larger code size)
leal -1(%rdi), %eax
blsr %edi, %eax
xorl %eax, %esi
...
```

Note, this may cause more `mov` instructions to be emitted sometimes
because BMI instructions only have 1 src and write-only to dst.  A
better approach may be to only avoid BMI for (and/xor X, (add/sub
0/-1, X)) if this is the last use of X but NOT the last use of
(add/sub 0/-1, X).

Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D141180
llvm/lib/Target/X86/X86InstrInfo.td
llvm/test/CodeGen/X86/GlobalISel/select-blsi.mir
llvm/test/CodeGen/X86/GlobalISel/select-blsr.mir
llvm/test/CodeGen/X86/bmi-out-of-order.ll