> -----Original Message-----
> From: Richard Biener <[email protected]>
> Sent: 06 July 2026 14:49
> To: Tamar Christina <[email protected]>
> Cc: [email protected]; nd <[email protected]>
> Subject: Re: [patch 2/2]middle-end: add gimple-isel-match.pd
> 
> On Mon, 6 Jul 2026, Tamar Christina wrote:
> 
> > This commits adds gimple-isel-match.pd which is a match.pd version that
> only
> > applies it's rewriting rules at gimple-isel time.  The normal match.pd rules
> > are also later applied.
> >
> > The file is currently empty, but I have some patches to add vector
> comparisons
> > matching to this and I noticed a few cases already in isel that can be
> > simplified using the match.pd machinery.
> >
> > Bootstrapped Regtested on aarch64-none-linux-gnu,
> > arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
> > -m32, -m64 and no issues.
> >
> > Ok for master?
> >
> > Thanks,
> > Tamar
> >
> > gcc/ChangeLog:
> >
> >     * Makefile.in: Add entries for gimple-isel-match.pd
> >     * gimple-isel.cc (gimple_isel_simplify): Forward declare.
> >     (gimple_isel_match_stmt): New.
> >     (pass_gimple_isel::execute): Call it.
> >     * gimple-isel-match.pd: New file.
> >
> > ---
> > diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> > index
> 536e2faaaf882d412bdb5bba649f184e672f2be5..f13972b9a5a01efefa5ae9
> 8d1eaab7138bf2c9f2 100644
> > --- a/gcc/Makefile.in
> > +++ b/gcc/Makefile.in
> > @@ -228,6 +228,10 @@ GIMPLE_MATCH_PD_SEQ_O = $(patsubst %,
> gimple-match-%.o, $(MATCH_SPLITS_SEQ))
> >  GENERIC_MATCH_PD_SEQ_SRC = $(patsubst %, generic-match-%.cc,
> $(MATCH_SPLITS_SEQ))
> >  GENERIC_MATCH_PD_SEQ_O = $(patsubst %, generic-match-%.o,
> $(MATCH_SPLITS_SEQ))
> >
> > +# The number of splits to be made for the gimple-isel-match.pd files.
> > +GIMPLE_ISEL_MATCH_PD_SEQ_SRC = $(patsubst %, gimple-isel-match-
> %.cc, $(MATCH_SPLITS_SEQ))
> > +GIMPLE_ISEL_MATCH_PD_SEQ_O = $(patsubst %, gimple-isel-match-%.o,
> $(MATCH_SPLITS_SEQ))
> > +
> >  # The number of splits to be made for the insn-emit files.
> >  NUM_INSNEMIT_SPLITS = @DEFAULT_INSNEMIT_PARTITIONS@
> >  INSNEMIT_SPLITS_SEQ = $(wordlist
> 1,$(NUM_INSNEMIT_SPLITS),$(one_to_9999))
> > @@ -1401,6 +1405,7 @@ ANALYZER_OBJS = \
> >  # the last objects to finish building.
> >  OBJS = \
> >     $(GIMPLE_MATCH_PD_SEQ_O) \
> > +   $(GIMPLE_ISEL_MATCH_PD_SEQ_O) \
> >     gimple-match-exports.o \
> >     $(GENERIC_MATCH_PD_SEQ_O) \
> >     insn-attrtab.o \
> > @@ -1988,7 +1993,8 @@ MOSTLYCLEANFILES = insn-flags.h insn-config.h
> insn-codes.h \
> >   insn-attr.h insn-attr-common.h insn-attrtab.cc insn-dfatab.cc \
> >   insn-latencytab.cc insn-opinit.cc insn-opinit.h insn-preds.cc insn-
> constants.h \
> >   tm-preds.h tm-constrs.h checksum-options
> $(GIMPLE_MATCH_PD_SEQ_SRC) \
> > - $(GENERIC_MATCH_PD_SEQ_SRC) gimple-match-auto.h generic-match-
> auto.h \
> > + $(GIMPLE_ISEL_MATCH_PD_SEQ_SRC) $(GENERIC_MATCH_PD_SEQ_SRC)
> \
> > + gimple-match-auto.h generic-match-auto.h \
> >   tree-check.h min-insn-modes.cc insn-modes.cc insn-modes.h insn-modes-
> inline.h \
> >   genrtl.h gt-*.h gtype-*.h gtype-desc.cc gtyp-input.list \
> >   case-cfn-macros.h cfn-operators.pd \
> > @@ -2763,6 +2769,7 @@ $(common_out_object_file):
> $(common_out_file)
> >    insn-extract.cc insn-output.cc \
> >    insn-peep.cc insn-attr.h insn-attr-common.h insn-attrtab.cc \
> >    insn-dfatab.cc insn-latencytab.cc insn-preds.cc \
> > +  $(GIMPLE_ISEL_MATCH_PD_SEQ_SRC) \
> >    $(GIMPLE_MATCH_PD_SEQ_SRC) $(GENERIC_MATCH_PD_SEQ_SRC) \
> >    gimple-match-auto.h generic-match-auto.h insn-target-def.h
> >
> > @@ -3078,6 +3085,23 @@ s-generic-match:
> build/genmatch$(build_exeext) \
> >                                             generic-match-auto.h
> >     $(STAMP) s-generic-match
> >
> > +# Add gimple-isel-match.pd
> > +$(GIMPLE_ISEL_MATCH_PD_SEQ_SRC): s-gimple-isel-match gimple-match-
> head.cc; @true
> > +gimple-isel-match-auto.h: s-gimple-isel-match; @true
> > +
> > +s-gimple-isel-match: build/genmatch$(build_exeext) \
> > +       $(srcdir)/gimple-isel-match.pd cfn-operators.pd
> > +   $(RUN_GEN) build/genmatch$(build_exeext) --gimple \
> > +       --header=tmp-gimple-isel-match-auto.h \
> > +       --include=gimple-isel-match-auto.h --namespace=isel \
> > +       $(srcdir)/gimple-isel-match.pd $(patsubst %, tmp-%,
> $(GIMPLE_ISEL_MATCH_PD_SEQ_SRC))
> > +   $(foreach id, $(MATCH_SPLITS_SEQ), \
> > +     $(SHELL) $(srcdir)/../move-if-change tmp-gimple-isel-match-$(id).cc
> \
> > +       gimple-isel-match-$(id).cc;)
> > +   $(SHELL) $(srcdir)/../move-if-change tmp-gimple-isel-match-auto.h \
> > +                                           gimple-isel-match-auto.h
> > +   $(STAMP) s-gimple-isel-match
> > +
> >  GTFILES = $(CPPLIB_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
> >    $(host_xm_file_list) \
> >    $(OPTIONS_H_EXTRA) \
> > @@ -3217,6 +3241,7 @@ generated_files = config.h tm.h $(TM_P_H)
> $(TM_D_H) $(TM_JIT_H) $(TM_H) \
> >         $(ALL_GTFILES_H) gtype-desc.cc gtype-desc.h version.h \
> >         options.h target-hooks-def.h insn-opinit.h \
> >         common/common-target-hooks-def.h pass-instances.def \
> > +       $(GIMPLE_ISEL_MATCH_PD_SEQ_SRC) \
> >         $(GIMPLE_MATCH_PD_SEQ_SRC) $(GENERIC_MATCH_PD_SEQ_SRC) \
> >         gimple-match-auto.h generic-match-auto.h \
> >         c-family/c-target-hooks-def.h d/d-target-hooks-def.h \
> > diff --git a/gcc/gimple-isel-match.pd b/gcc/gimple-isel-match.pd
> > new file mode 100644
> > index
> 0000000000000000000000000000000000000000..9e2a2044ba58663890
> 67cfff529b064d1885ea36
> > --- /dev/null
> > +++ b/gcc/gimple-isel-match.pd
> > @@ -0,0 +1,46 @@
> > +/* Match-and-simplify patterns for GIMPLE folding during instruction
> selection.
> > +   This file is consumed by genmatch which produces gimple-isel-match.cc.
> > +
> > +   Copyright (C) 2026 Free Software Foundation, Inc.
> > +
> > +This file is part of GCC.
> > +
> > +GCC is free software; you can redistribute it and/or modify it under
> > +the terms of the GNU General Public License as published by the Free
> > +Software Foundation; either version 3, or (at your option) any later
> > +version.
> > +
> > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> > +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> > +for more details.
> > +
> > +You should have received a copy of the GNU General Public License
> > +along with GCC; see the file COPYING3.  If not see
> > +<http://www.gnu.org/licenses/>.  */
> > +
> > +
> > +/* Generic tree predicates we inherit.  */
> > +(define_predicates
> > +   integer_onep integer_zerop integer_all_onesp integer_minus_onep
> > +   integer_each_onep integer_truep integer_nonzerop
> > +   real_zerop real_onep real_minus_onep
> > +   zerop
> > +   initializer_each_zero_or_onep
> > +   CONSTANT_CLASS_P
> > +   poly_int_tree_p
> > +   tree_expr_nonnegative_p
> > +   tree_expr_nonzero_p
> > +   integer_valued_real_p
> > +   integer_pow2p
> > +   uniform_integer_cst_p
> > +   HONOR_NANS
> > +   uniform_vector_p
> > +   expand_vec_cmp_expr_p
> > +   bitmask_inv_cst_vector_p)
> > +
> > +/* Operator lists.  */
> > +(define_operator_list tcc_comparison
> > +  lt   le   eq ne ge   gt   unordered ordered   unlt unle ungt unge uneq 
> > ltgt)
> > +
> > +#include "cfn-operators.pd"
> > diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
> > index
> b193e27b183e1a83d73369b629c81ea0d7db43cd..b834c05d65eab82b06e
> 6b0be00b73d50384a734e 100644
> > --- a/gcc/gimple-isel.cc
> > +++ b/gcc/gimple-isel.cc
> > @@ -40,6 +40,39 @@ along with GCC; see the file COPYING3.  If not see
> >  #include "gimple-fold.h"
> >  #include "internal-fn.h"
> >  #include "fold-const.h"
> > +#include "gimple-match.h"
> > +
> > +extern bool gimple_isel_simplify (gimple_match_op *, gimple_seq *,
> > +                             tree (*) (tree));
> > +
> > +/* Try to apply the instruction-selection-specific match.pd rules to *GSI. 
> >  */
> > +
> > +static bool
> > +gimple_isel_match_stmt (gimple_stmt_iterator *gsi)
> > +{
> 
> So that's basically fold_stmt (), right?  Why not provide an
> overload for that specifying the simplifier?
> 
> Did you consider a gimple_match_op::set_simplifier () and tracking
> the simplifier there?

Hmm interesting suggestion. Let me try that.

Thanks,
Tamar
> 
> > +  gimple *stmt = gsi_stmt (*gsi);
> > +  if (!gimple_has_lhs (stmt))
> > +    return false;
> > +
> > +  gimple_seq seq = NULL;
> > +  gimple_match_op res_op;
> > +  if (!gimple_simplify (stmt, &res_op, &seq, NULL, NULL,
> > +                   gimple_isel_simplify))
> > +    {
> > +      gimple_seq_discard (seq);
> > +      return false;
> > +    }
> > +
> > +  tree lhs = gimple_get_lhs (stmt);
> > +  if (!maybe_push_res_to_seq (&res_op, &seq, lhs))
> > +    {
> > +      gimple_seq_discard (seq);
> > +      return false;
> > +    }
> > +
> > +  gsi_replace_with_seq_vops (gsi, seq);
> > +  return true;
> > +}
> >
> >  /* Expand all ARRAY_REF(VIEW_CONVERT_EXPR) gimple assignments into
> calls to
> >     internal function based on vector type of selected expansion.
> > @@ -1360,6 +1393,9 @@ pass_gimple_isel::execute (struct function *fun)
> >       /* Give the target first try at replacing the instruction.  */
> >       cfg_changed |= targetm.instruction_selection (fun, &gsi);
> >
> > +     /* Apply gimple-isel-match.pd patterns.  */
> > +     gimple_isel_match_stmt (&gsi);
> > +
> >       /* Pre-expand VEC_COND_EXPRs to .VCOND* internal function
> >          calls mapping to supported optabs.  */
> >       gimple *g = gimple_expand_vec_cond_expr (&gsi);
> > @@ -1400,4 +1436,3 @@ make_pass_gimple_isel (gcc::context *ctxt)
> >  {
> >    return new pass_gimple_isel (ctxt);
> >  }
> > -
> >
> >
> >
> 
> --
> Richard Biener <[email protected]>
> SUSE Software Solutions Germany GmbH,
> Frankenstrasse 146, 90461 Nuernberg, Germany;
> GF: Jochen Jaser, Andrew McDonald; (HRB 36809, AG Nuernberg)

Reply via email to