From 28fc44f389e4cf21f2d05312badde13b00ab25b6 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 20 Jan 2011 13:02:33 +0100 Subject: [PATCH] re PR tree-optimization/46130 (ICE: SIGSEGV in walk_stmt_load_store_addr_ops (gimple.c:4894) with -O2 -fno-tree-dce) PR tree-optimization/46130 * ipa-split.c (consider_split): If return_bb contains non-virtual PHIs other than for retval or if split_function would not adjust it, refuse to split. * gcc.dg/pr46130-1.c: New test. * gcc.dg/pr46130-2.c: New test. From-SVN: r169052 --- gcc/ChangeLog | 7 +++++++ gcc/ipa-split.c | 27 ++++++++++++++++++++++++--- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/pr46130-1.c | 23 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr46130-2.c | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr46130-1.c create mode 100644 gcc/testsuite/gcc.dg/pr46130-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff8645e61060..466579a1792e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-01-20 Jakub Jelinek + + PR tree-optimization/46130 + * ipa-split.c (consider_split): If return_bb contains non-virtual + PHIs other than for retval or if split_function would not adjust it, + refuse to split. + 2011-01-20 Richard Guenther PR tree-optimization/47167 diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index c72a36d67ee8..30060440fe27 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -411,9 +411,6 @@ consider_split (struct split_point *current, bitmap non_ssa_vars, " Refused: split part has non-ssa uses\n"); return; } - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Accepted!\n"); - /* See if retval used by return bb is computed by header or split part. When it is computed by split part, we need to produce return statement in the split part and add code to header to pass it around. @@ -451,6 +448,30 @@ consider_split (struct split_point *current, bitmap non_ssa_vars, else current->split_part_set_retval = true; + /* split_function fixes up at most one PHI non-virtual PHI node in return_bb, + for the return value. If there are other PHIs, give up. */ + if (return_bb != EXIT_BLOCK_PTR) + { + gimple_stmt_iterator psi; + + for (psi = gsi_start_phis (return_bb); !gsi_end_p (psi); gsi_next (&psi)) + if (is_gimple_reg (gimple_phi_result (gsi_stmt (psi))) + && !(retval + && current->split_part_set_retval + && TREE_CODE (retval) == SSA_NAME + && !DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)) + && SSA_NAME_DEF_STMT (retval) == gsi_stmt (psi))) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Refused: return bb has extra PHIs\n"); + return; + } + } + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Accepted!\n"); + /* At the moment chose split point with lowest frequency and that leaves out smallest size of header. In future we might re-consider this heuristics. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 07b41c8299ed..c4880506aec4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-01-20 Jakub Jelinek + + PR tree-optimization/46130 + * gcc.dg/pr46130-1.c: New test. + * gcc.dg/pr46130-2.c: New test. + 2011-01-19 Dodji Seketeli PR c++/47291 diff --git a/gcc/testsuite/gcc.dg/pr46130-1.c b/gcc/testsuite/gcc.dg/pr46130-1.c new file mode 100644 index 000000000000..a0a582d2784c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr46130-1.c @@ -0,0 +1,23 @@ +/* PR tree-optimization/46130 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-dce" } */ + +#include + +static void +foo (va_list ap) +{ + va_arg (ap, char *)[0]; +} + +void +bar (va_list ap) +{ + foo (ap); +} + +void +baz (va_list ap) +{ + foo (ap); +} diff --git a/gcc/testsuite/gcc.dg/pr46130-2.c b/gcc/testsuite/gcc.dg/pr46130-2.c new file mode 100644 index 000000000000..991e5dd18353 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr46130-2.c @@ -0,0 +1,32 @@ +/* PR tree-optimization/46130 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-dce" } */ + +extern int bar (int); + +static int foo (int x) +{ + int z, w; + if (x <= 1024) + { + z = 16; + w = 17; + } + else + { + bar (bar (bar (bar (bar (bar (bar (bar (bar (16))))))))); + if (x > 131072) + w = 19; + else + w = 21; + z = 32; + } + w = w + 121; + return z; +} + +int +baz (int x) +{ + return foo (x + 6) + foo (x + 15) + foo (x + 24); +}