aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-02-05 16:54:39 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2013-02-05 16:54:39 +0100
commit11f1e3ab239b3a45b085ca5eb1327f1254fb6205 (patch)
tree899e8e666ecaed66a88bbdcc9ab214a36edc66dd /gcc
parent14ac6aa24e155affd1829600a5294a8f3cc115cd (diff)
downloadgcc-11f1e3ab239b3a45b085ca5eb1327f1254fb6205.zip
gcc-11f1e3ab239b3a45b085ca5eb1327f1254fb6205.tar.gz
gcc-11f1e3ab239b3a45b085ca5eb1327f1254fb6205.tar.bz2
re PR tree-optimization/56205 (stdarg pass confused by jump threading)
PR tree-optimization/56205 * tree-stdarg.c (check_all_va_list_escapes): Return true if there are any PHI nodes that set non-va_list_escape_vars SSA_NAME and some va_list_escape_vars SSA_NAME appears in some PHI argument. * gcc.dg/tree-ssa/stdarg-6.c: New test. * gcc.c-torture/execute/pr56205.c: New test. From-SVN: r195760
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr56205.c61
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/stdarg-6.c35
-rw-r--r--gcc/tree-stdarg.c31
5 files changed, 140 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 595dad4..a6ab680 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2013-02-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/56205
+ * tree-stdarg.c (check_all_va_list_escapes): Return true if
+ there are any PHI nodes that set non-va_list_escape_vars SSA_NAME
+ and some va_list_escape_vars SSA_NAME appears in some PHI argument.
+
2013-02-05 Richard Biener <rguenther@suse.de>
PR tree-optimization/53342
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a9d19c9..dc716f9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2013-02-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/56205
+ * gcc.dg/tree-ssa/stdarg-6.c: New test.
+ * gcc.c-torture/execute/pr56205.c: New test.
+
2013-02-05 Richard Biener <rguenther@suse.de>
PR tree-optimization/53342
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr56205.c b/gcc/testsuite/gcc.c-torture/execute/pr56205.c
new file mode 100644
index 0000000..bf39685
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr56205.c
@@ -0,0 +1,61 @@
+/* PR tree-optimization/56205 */
+
+#include <stdarg.h>
+
+int a, b;
+char c[128];
+
+__attribute__((noinline, noclone)) static void
+f1 (const char *fmt, ...)
+{
+ va_list ap;
+ asm volatile ("" : : : "memory");
+ if (__builtin_strcmp (fmt, "%s %d %s") != 0)
+ __builtin_abort ();
+ va_start (ap, fmt);
+ if (__builtin_strcmp (va_arg (ap, const char *), "foo") != 0
+ || va_arg (ap, int) != 1
+ || __builtin_strcmp (va_arg (ap, const char *), "bar") != 0)
+ __builtin_abort ();
+ va_end (ap);
+}
+
+__attribute__((noinline, noclone)) static void
+f2 (const char *fmt, va_list ap)
+{
+ asm volatile ("" : : : "memory");
+ if (__builtin_strcmp (fmt, "baz") != 0
+ || __builtin_strcmp (va_arg (ap, const char *), "foo") != 0
+ || va_arg (ap, double) != 12.0
+ || va_arg (ap, int) != 26)
+ __builtin_abort ();
+}
+
+static void
+f3 (int x, char const *y, va_list z)
+{
+ f1 ("%s %d %s", x ? "" : "foo", ++a, (y && *y) ? "bar" : "");
+ if (y && *y)
+ f2 (y, z);
+}
+
+__attribute__((noinline, noclone)) void
+f4 (int x, char const *y, ...)
+{
+ va_list z;
+ va_start (z, y);
+ if (!x && *c == '\0')
+ ++b;
+ f3 (x, y, z);
+ va_end (z);
+}
+
+int
+main ()
+{
+ asm volatile ("" : : : "memory");
+ f4 (0, "baz", "foo", 12.0, 26);
+ if (a != 1 || b != 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-6.c b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-6.c
new file mode 100644
index 0000000..c21dc17
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-6.c
@@ -0,0 +1,35 @@
+/* PR tree-optimization/56205 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-stdarg" } */
+
+#include <stdarg.h>
+
+int a, b;
+char c[128];
+
+static inline void
+foo (int x, char const *y, va_list z)
+{
+ __builtin_printf ("%s %d %s", x ? "" : "foo", ++a, (y && *y) ? "bar" : "");
+ if (y && *y)
+ __builtin_vprintf (y, z);
+}
+
+void
+bar (int x, char const *y, ...)
+{
+ va_list z;
+ va_start (z, y);
+ if (!x && *c == '\0')
+ ++b;
+ foo (x, y, z);
+ va_end (z);
+}
+
+/* { dg-final { scan-tree-dump "bar: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */
+/* { dg-final { scan-tree-dump "bar: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */
+/* { dg-final { scan-tree-dump "bar: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */
+/* { dg-final { scan-tree-dump "bar: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */
+/* { dg-final { scan-tree-dump "bar: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */
+/* { dg-final { scan-tree-dump "bar: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* } } } */
+/* { dg-final { scan-tree-dump "bar: va_list escapes 1, needs to save all GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index cd573a3..8ad9fc2 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -526,6 +526,37 @@ check_all_va_list_escapes (struct stdarg_info *si)
{
gimple_stmt_iterator i;
+ for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
+ {
+ tree lhs;
+ use_operand_p uop;
+ ssa_op_iter soi;
+ gimple phi = gsi_stmt (i);
+
+ lhs = PHI_RESULT (phi);
+ if (virtual_operand_p (lhs)
+ || bitmap_bit_p (si->va_list_escape_vars,
+ SSA_NAME_VERSION (lhs)))
+ continue;
+
+ FOR_EACH_PHI_ARG (uop, phi, soi, SSA_OP_USE)
+ {
+ tree rhs = USE_FROM_PTR (uop);
+ if (TREE_CODE (rhs) == SSA_NAME
+ && bitmap_bit_p (si->va_list_escape_vars,
+ SSA_NAME_VERSION (rhs)))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fputs ("va_list escapes in ", dump_file);
+ print_gimple_stmt (dump_file, phi, 0, dump_flags);
+ fputc ('\n', dump_file);
+ }
+ return true;
+ }
+ }
+ }
+
for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
gimple stmt = gsi_stmt (i);