[all-commits] [llvm/llvm-project] a4516d: [AArch64] - Fold and and cmp into tst (#110347)

Jorge Botto via All-commits all-commits at lists.llvm.org
Thu Oct 3 09:56:22 PDT 2024


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: a4516da49f8bda1b99d21dae7e1caba772d7182c
      https://github.com/llvm/llvm-project/commit/a4516da49f8bda1b99d21dae7e1caba772d7182c
  Author: Jorge Botto <Jorge.botto.16 at ucl.ac.uk>
  Date:   2024-10-03 (Thu, 03 Oct 2024)

  Changed paths:
    M llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
    A llvm/test/CodeGen/AArch64/icmp-ult-eq-fold.ll
    M llvm/test/CodeGen/AArch64/signed-truncation-check.ll

  Log Message:
  -----------
  [AArch64] - Fold and and cmp into tst (#110347)

Fixes https://github.com/llvm/llvm-project/issues/102703.

https://godbolt.org/z/nfj8xsb1Y

The following pattern:

```
%2 = and i32 %0, 254
%3 = icmp eq i32 %2, 0
```
is optimised by instcombine into:

```%3 = icmp ult i32 %0, 2```

However, post instcombine leads to worse aarch64 than the unoptimised version.

Pre instcombine:
```
        tst     w0, #0xfe
        cset    w0, eq
        ret
```
Post instcombine:
```
        and     w8, w0, #0xff
        cmp     w8, #2
        cset    w0, lo
        ret
```


In the unoptimised version, SelectionDAG converts `SETCC (AND X 254) 0 EQ` into `CSEL 0 1 1 (ANDS X 254)`, which gets emitted as a `tst`.

In the optimised version, SelectionDAG converts `SETCC (AND X 255) 2 ULT` into `CSEL 0 1 2 (SUBS (AND X 255) 2)`, which gets emitted as an `and`/`cmp`.

This PR adds an optimisation to `AArch64ISelLowering`, converting `SETCC (AND X Y) Z ULT` into `SETCC (AND X (Y & ~(Z - 1))) 0 EQ` when `Z` is a power of two. This makes SelectionDAG/Codegen produce the same optimised code for both examples.



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list