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),"
