https://gcc.gnu.org/g:93ea772554bde9264855704d9050bf065d018781

commit r17-4932-g93ea772554bde9264855704d9050bf065d018781
Author: Kyrylo Tkachov <[email protected]>
Date:   Fri Oct 2 14:03:30 2026 +0200

    genmatch: Try later patterns when a transform needs a sequence
    
    When a GIMPLE transform substitutes a capture that matched a COND_EXPR
    condition anywhere other than a COND_EXPR condition, the generated code
    builds the comparison as a statement of its own, and gives up if there is no
    sequence to build it in.  It gives up with "return false", which leaves the
    whole function.  For a transform that genmatch emits inline in a matcher,
    that skips every later pattern as well.  For a transform that several
    decision-tree leaves share, which genmatch moves into a function of its own,
    it skips only that pattern.
    
    Jump to the failure label of the pattern instead, as the other transform
    failures already do, so that matching goes on with the next pattern:
    
      _o2[0] = captures[0];
      if (COMPARISON_CLASS_P (_o2[0]))
        {
          if (!seq) return false;               <- before
          if (!seq) goto next_after_fail1364;   <- after
          _o2[0] = gimple_build (seq, TREE_CODE (_o2[0]), ...);
        }
    
    In the generated GIMPLE code 27 lines change and no others.  Three of them
    are in functions that hold a single transform, where the two forms are
    equivalent.  The GENERIC code does not change.  With several output files
    some functions land in a different file, because the changed lines are
    longer and genmatch fills the shortest file first.
    
    Bootstrapped and regression tested on aarch64-linux-gnu.
    Ok for trunk?
    Thanks,
    Kyrill
    
    gcc/ChangeLog:
    
            * genmatch.cc (capture::gen_transform): Jump to the failure label
            rather than return when a comparison needs a sequence and there is
            none.
    
    Signed-off-by: Kyrylo Tkachov <[email protected]>

Diff:
---
 gcc/genmatch.cc | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc
index 42a04436c57e..1a89b7c13c2f 100644
--- a/gcc/genmatch.cc
+++ b/gcc/genmatch.cc
@@ -3864,11 +3864,12 @@ capture::gen_transform (FILE *f, int indent, const char 
*dest, bool gimple,
       /* If substituting elsewhere we might need to decompose it.  */
       else if (cond_handling == 2)
        {
-         /* ???  Returning false here will also not allow any other patterns
-            to match unless this generator was split out.  */
+         /* Without a sequence the comparison cannot be built, so give up on
+            this pattern and go on to the next one.  */
+         gcc_assert (fail_label);
          fprintf_indent (f, indent, "if (COMPARISON_CLASS_P (%s))\n", dest);
          fprintf_indent (f, indent, "  {\n");
-         fprintf_indent (f, indent, "    if (!seq) return false;\n");
+         fprintf_indent (f, indent, "    if (!seq) goto %s;\n", fail_label);
          fprintf_indent (f, indent, "    %s = gimple_build (seq,"
                          " TREE_CODE (%s),"
                          " TREE_TYPE (%s), TREE_OPERAND (%s, 0),"

Reply via email to