Hi gcc-patches mailing list,
Andrei Tirziu <[email protected]> has requested that the following 
forgejo pull request
be published on the mailing list.

Created on: 2026-01-20 16:35:05+00:00
Latest update: 2026-01-20 16:50:37+00:00
Changes: 18 changed files, 1765 additions, 74 deletions
Head revision: why/gcc ref idiom-match-upstream commit 
9a7d99f3f4bce96159e51510f5f4796c7620481a
Base revision: gcc/gcc-TEST ref master commit 
07df546fb904f68c346f600a7cd0df07706de217 r16-6593-g07df546fb904f6
Merge base: 07df546fb904f68c346f600a7cd0df07706de217
Full diff url: https://forge.sourceware.org/gcc/gcc-TEST/pulls/135.diff
Discussion:  https://forge.sourceware.org/gcc/gcc-TEST/pulls/135
Requested Reviewers:

This series of patches introduces a new SLP Pattern in the Vectorizer.
The "MATCH" pattern has a direct correspondence in the AArch64 SVE instructions 
(`match` and `nmatch`), thus allowing for optimizations of the initial code.


The MATCH pattern is either:
- OR-chain (for equality disjunctions): `(p0) || (p1) || ...`, leaves are 
`EQ_EXPR`.
- AND-chain (for inequality conjunctions): `(q0) && (q1) && ...`, leaves are 
`NE_EXPR`.


In addition to having an OR-chain / AND-chain structure, the leaves (also 
called "predicates") must be formed of a common variant and some invariants for 
the pattern to be recognized.


A simple example using an array (the variant), and 3 invariants (the variables 
`x`, `y`, `z`) would be:
`int count = 0;`
`for (int i = 0; i < n; i++)`
`{`
`  if (a[i] == x || a[i] == y || a[i] == z)`
`  {`
`    count++;`
`  }`
`}`


If such a pattern is identified, a replacement is created for it, such that the 
GIMPLE expression used by the if-statement, of the form
`exp = (a[i] == x || a[i] == y || a[i] == z)`
is rewritten as (the actual code is slightly different, but this exemplifies 
the main idea):
`exp = IFN_MATCH_EQ (a[i], x, y, z)`.


Since we are dealing with SLP nodes, a more accurate representation would be:
`exp = IFN_MATCH_EQ (a[i..i+N], inv)` where `a[i..i+N]` is a slice of the array 
(equivalent to having `N` iterations of the loop), and `inv = {x, y, z, x, y, 
z, ...}` where the invariants are organized in a cyclic way such that 
`inv.size() = N`.


The vectorizer then transforms this Internal Function to its conditional 
version, thus adding the loop mask to it: `exp = IFN_COND_MATCH_EQ (a[i..i+N], 
inv, mask, else)`.


With the help of a direct optab, and its implementation in the AArch64 backend, 
the vectorizer can transform this IFN into a `match` instruction in the final 
assembly output.


Changed files:
- A: gcc/testsuite/gcc.target/aarch64/sve2/match_char_small.c
- A: gcc/testsuite/gcc.target/aarch64/sve2/match_char_small_run.c
- A: gcc/testsuite/gcc.target/aarch64/sve2/match_short_int_large.c
- A: gcc/testsuite/gcc.target/aarch64/sve2/match_short_int_large_run.c
- A: gcc/testsuite/gcc.target/aarch64/sve2/match_short_int_medium.c
- A: gcc/testsuite/gcc.target/aarch64/sve2/match_short_int_medium_run.c
- A: gcc/testsuite/gcc.target/aarch64/sve2/match_short_int_small.c
- A: gcc/testsuite/gcc.target/aarch64/sve2/match_short_int_small_run.c
- A: gcc/testsuite/gcc.target/aarch64/sve2/nmatch_short_int_small.c
- A: gcc/testsuite/gcc.target/aarch64/sve2/nmatch_short_int_small_run.c
- M: gcc/config/aarch64/aarch64-sve2.md
- M: gcc/config/aarch64/iterators.md
- M: gcc/internal-fn.cc
- M: gcc/internal-fn.def
- M: gcc/internal-fn.h
- M: gcc/optabs.def
- M: gcc/tree-vect-slp-patterns.cc
- M: gcc/tree-vect-stmts.cc


Andrei Nichita Tirziu (7):
  [Vectorizer]: SLP MATCH Pattern: Add Internal Functions and Optabs
  [Vectorizer]: SLP MATCH Pattern: Identify pattern and build the new
    SLP nodes
  [Vectorizer][Aarch64]: SLP MATCH Pattern: Add implementation for match
    / nmatch SVE instructions
  [Vectorizer]: Improve vectorizable_call to support transformation from
    standard IFN to its conditional version
  [Vectorizer]: SLP MATCH Pattern: Enable pattern
  [Vectorizer]: SLP MATCH Pattern: Allow for more invariants
  [Vectorizer]: SLP MATCH Pattern: Add tests

 gcc/config/aarch64/aarch64-sve2.md            |  37 +
 gcc/config/aarch64/iterators.md               |   3 +
 gcc/internal-fn.cc                            |  33 +-
 gcc/internal-fn.def                           |  11 +
 gcc/internal-fn.h                             |  40 +
 gcc/optabs.def                                |   6 +
 .../aarch64/sve2/match_char_small.c           |  44 ++
 .../aarch64/sve2/match_char_small_run.c       |  39 +
 .../aarch64/sve2/match_short_int_large.c      |  60 ++
 .../aarch64/sve2/match_short_int_large_run.c  |  71 ++
 .../aarch64/sve2/match_short_int_medium.c     |  58 ++
 .../aarch64/sve2/match_short_int_medium_run.c |  69 ++
 .../aarch64/sve2/match_short_int_small.c      |  48 ++
 .../aarch64/sve2/match_short_int_small_run.c  |  53 ++
 .../aarch64/sve2/nmatch_short_int_small.c     |  55 ++
 .../aarch64/sve2/nmatch_short_int_small_run.c |  53 ++
 gcc/tree-vect-slp-patterns.cc                 | 709 +++++++++++++++++-
 gcc/tree-vect-stmts.cc                        | 448 +++++++++--
 18 files changed, 1764 insertions(+), 73 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve2/match_char_small.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve2/match_char_small_run.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve2/match_short_int_large.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve2/match_short_int_large_run.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve2/match_short_int_medium.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve2/match_short_int_medium_run.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve2/match_short_int_small.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve2/match_short_int_small_run.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve2/nmatch_short_int_small.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/sve2/nmatch_short_int_small_run.c

-- 
2.52.0

Reply via email to