On Thu, 16 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 at the end of the pass as normal. > > 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. > (pass_gimple_isel::execute): Call it. > * gimple-isel-match.pd: New file. > > --- > diff --git a/gcc/Makefile.in b/gcc/Makefile.in > index > fa46ada4980ff8fcbdba696f46e81f59b83dc4b4..09fd733c0b80b5c36546f0c54b6a12cc127003fc > 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)) > +
I think we can avoid splitting this for now? > # 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 \ > @@ -1987,7 +1992,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 \ > @@ -2762,6 +2768,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 > > @@ -3077,6 +3084,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) \ > @@ -3216,6 +3240,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..9e2a2044ba5866389067cfff529b064d1885ea36 > --- /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" We probably want to create a shared header we can include in both match.pd and here to avoid maintaining this in two places? > diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc > index > b193e27b183e1a83d73369b629c81ea0d7db43cd..4348bd53103865c81a9e4c6f2ea434c7ef94f183 > 100644 > --- a/gcc/gimple-isel.cc > +++ b/gcc/gimple-isel.cc > @@ -40,6 +40,10 @@ 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)); > > /* Expand all ARRAY_REF(VIEW_CONVERT_EXPR) gimple assignments into calls to > internal function based on vector type of selected expansion. > @@ -1360,6 +1364,15 @@ 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. */ > + bool stmt_changed = fold_stmt (&gsi, gimple_isel_simplify); But fold_stmt does a lot more than just apply *.pd patterns, why not split out the relevant part, gimple_seq seq = NULL; gimple_match_op res_op; if (gimple_simplify (stmt, &res_op, inplace ? NULL : &seq, valueize, valueize) && replace_stmt_with_simplification (gsi, &res_op, &seq, inplace, dce_worklist)) changed = true; else gimple_seq_discard (seq); to a helper and use only that? > + if (stmt_changed && !gsi_end_p (gsi)) I never seen gsi_end_p on a fold result. It's supposed to be GIMPLE_NOP if "removed". > + { > + update_stmt (gsi_stmt (gsi)); > + if (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND) Do like forwprop: if (gcond *cond = dyn_cast <gcond *> (stmt)) if (gimple_cond_true_p (cond) || gimple_cond_false_p (cond)) cfg_changed = true; > + cfg_changed = true; > + } > + > /* Pre-expand VEC_COND_EXPRs to .VCOND* internal function > calls mapping to supported optabs. */ > gimple *g = gimple_expand_vec_cond_expr (&gsi); > @@ -1400,4 +1413,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, Abhinav Puri; (HRB 36809, AG Nuernberg)
