This makes sure we simplify an expression before giving up because the caller only expects a singleton result. Otherwise patterns like
(match_and_simplify (plus @0 integer_zerop) @0) (match_and_simplify (plus (plus @0 INTEGER_CST_P@1) INTEGER_CST_P@2) (plus @0 (plus @1 @2))) that expect to constant-fold (plus @1 @2) and the resulting (plus @0 0) for (a + 1) + -1 won't match when called with !seq (as for example SCCVN does). Bootstrapped and tested on x86_64-unknown-linux-gnu and applied. Richard. 2014-03-13 Richard Biener <rguent...@suse.de> * genmatch.c (expr::gen_gimple_transform): Make sure to try simplifying a transform pattern even when seq is NULL as seq may not be needed. Index: gcc/genmatch.c =================================================================== --- gcc/genmatch.c (revision 208478) +++ gcc/genmatch.c (working copy) @@ -332,20 +332,32 @@ void expr::gen_gimple_transform (FILE *f, const char *label) { fprintf (f, "({\n"); - fprintf (f, " if (!seq) "); - gen_gimple_match_fail (f, label); - fprintf (f, " tree ops[%d];\n", ops.length ()); + fprintf (f, " tree ops[%d], res;\n", ops.length ()); for (unsigned i = 0; i < ops.length (); ++i) { - fprintf (f, " ops[%u] = ", i); + fprintf (f, " ops[%u] = ", i); ops[i]->gen_gimple_transform (f, label); fprintf (f, ";\n"); } - fprintf (f, " gimple_build (seq, UNKNOWN_LOCATION, %s, TREE_TYPE (ops[0])", + /* ??? Have another helper that is like gimple_build but may + fail if seq == NULL. */ + fprintf (f, " if (!seq)\n" + " {\n" + " res = gimple_match_and_simplify (%s, TREE_TYPE (ops[0])", operation->op->id); for (unsigned i = 0; i < ops.length (); ++i) fprintf (f, ", ops[%u]", i); + fprintf (f, ", seq, valueize);\n"); + fprintf (f, " if (!res) "); + gen_gimple_match_fail (f, label); + fprintf (f, " }\n"); + fprintf (f, " else\n"); + fprintf (f, " res = gimple_build (seq, UNKNOWN_LOCATION, %s, " + "TREE_TYPE (ops[0])", operation->op->id); + for (unsigned i = 0; i < ops.length (); ++i) + fprintf (f, ", ops[%u]", i); fprintf (f, ", valueize);\n"); + fprintf (f, " res;\n"); fprintf (f, "})"); }