From: Kyrylo Tkachov <[email protected]>

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]>
---
 gcc/genmatch.cc | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc
index 42a04436c57..1a89b7c13c2 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),"
-- 
2.50.1 (Apple Git-155)

Reply via email to