aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2017-04-04 19:14:47 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2017-04-04 19:14:47 +0000
commitd84622d5d37e6312f3ebf16215fb80df9b18b439 (patch)
tree5b0e3a74776f991a8582b6f87c568a15f819c192
parente000adb99a2cbe03e98b79878c28f1ca6fe986ef (diff)
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@246693 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/generic-match-head.c1
-rw-r--r--gcc/genmatch.c13
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/torture/pr80297.C12
5 files changed, 36 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d537ac5099a..ac9ab8ad960 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,12 @@
2017-04-04 Jakub Jelinek <jakub@redhat.com>
+ Richard Biener <rguenther@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.
+
+2017-04-04 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/79390
* target.h (struct noce_if_info): Declare.
diff --git a/gcc/generic-match-head.c b/gcc/generic-match-head.c
index 1392d029f3e..04e0854fd75 100644
--- a/gcc/generic-match-head.c
+++ b/gcc/generic-match-head.c
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#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
diff --git a/gcc/genmatch.c b/gcc/genmatch.c
index 93d5b21d0be..5621aa05b59 100644
--- a/gcc/genmatch.c
+++ b/gcc/genmatch.c
@@ -2525,7 +2525,18 @@ capture::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
}
}
- 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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6d1ed2227b7..bdb1c01c6e6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2017-04-04 Jakub Jelinek <jakub@redhat.com>
+ PR c++/80297
+ * g++.dg/torture/pr80297.C: New test.
+
PR tree-optimization/79390
* gcc.target/i386/pr79390.c: New test.
* gcc.dg/ifcvt-4.c: Use -mtune-ctrl=^one_if_conv_insn for i?86/x86_64.
diff --git a/gcc/testsuite/g++.dg/torture/pr80297.C b/gcc/testsuite/g++.dg/torture/pr80297.C
new file mode 100644
index 00000000000..3b246e4b638
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr80297.C
@@ -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;
+}