Hi! While generic tree sharing is usually harmless, because we unshare everything before gimplification, on the following testcase a match.pd pattern that uses @1 twice introduces tree sharing during the C gimplification langhook, so after everything has been unshared.
The following patch fixes it by unsharing uses of captures except for the last use. Bootstrapped/regtested on x86_64-linux and i686-linux, acked by Richard in the PR, committed to trunk. 2017-04-04 Jakub Jelinek <ja...@redhat.com> Richard Biener <rguent...@suse.de> PR c++/80297 * genmatch.c (capture::gen_transform): For GENERIC unshare_expr captures used multiple times, except for the last use. * generic-match-head.c: Include gimplify.h. * g++.dg/torture/pr80297.C: New test. --- gcc/genmatch.c.jj 2017-03-19 11:57:19.000000000 +0100 +++ gcc/genmatch.c 2017-04-04 13:23:15.053251358 +0200 @@ -2525,7 +2525,18 @@ capture::gen_transform (FILE *f, int ind } } - fprintf_indent (f, indent, "%s = captures[%u];\n", dest, where); + /* If in GENERIC some capture is used multiple times, unshare it except + when emitting the last use. */ + if (!gimple + && cinfo->info.exists () + && cinfo->info[cinfo->info[where].same_as].result_use_count > 1) + { + fprintf_indent (f, indent, "%s = unshare_expr (captures[%u]);\n", + dest, where); + cinfo->info[cinfo->info[where].same_as].result_use_count--; + } + else + fprintf_indent (f, indent, "%s = captures[%u];\n", dest, where); /* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal with substituting a capture of that. */ --- gcc/generic-match-head.c.jj 2017-01-01 12:45:38.000000000 +0100 +++ gcc/generic-match-head.c 2017-04-04 13:18:38.437884559 +0200 @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. #include "builtins.h" #include "dumpfile.h" #include "case-cfn-macros.h" +#include "gimplify.h" /* Routine to determine if the types T1 and T2 are effectively --- gcc/testsuite/g++.dg/torture/pr80297.C.jj 2017-04-04 13:47:45.254048537 +0200 +++ gcc/testsuite/g++.dg/torture/pr80297.C 2017-04-04 13:47:29.000000000 +0200 @@ -0,0 +1,12 @@ +// PR c++/80297 +// { dg-do compile } + +extern const unsigned long int b; +extern const long long int c; + +int +foo () +{ + int a = 809 >> -(b & !c) + b - (long long)(b & !c); + return a; +} Jakub