From 9fd9ccf7150c486685430557b5c1865f464201ab Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 16 Apr 2013 15:32:26 +0000 Subject: [PATCH] re PR tree-optimization/56756 (ICE: verify_ssa failed (definition in block n follows the use !)) 2013-04-16 Richard Biener PR tree-optimization/56756 * tree-ssa-loop-im.c (struct first_mem_ref_loc_1): New functor. (first_mem_ref_loc): New. (execute_sm): Place the load temporarily before a previous access instead of in the latch edge to ensure its SSA dependencies are defined at points dominating the load. * gcc.dg/torture/pr56756.c: New testcase. From-SVN: r198001 --- gcc/ChangeLog | 9 ++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/torture/pr56756.c | 28 ++++++++++++++++++ gcc/tree-ssa-loop-im.c | 40 ++++++++++++++++++++++---- 4 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr56756.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3d7e60b21383..60f941e5f929 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2013-04-16 Richard Biener + + PR tree-optimization/56756 + * tree-ssa-loop-im.c (struct first_mem_ref_loc_1): New functor. + (first_mem_ref_loc): New. + (execute_sm): Place the load temporarily before a previous + access instead of in the latch edge to ensure its SSA dependencies + are defined at points dominating the load. + 2013-04-16 Steven Bosscher * cfgrtl.c (cfg_layout_merge_blocks): Revert r184005, implement diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index deb85a7e36bd..b3adc0ee2e2e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-04-16 Richard Biener + + PR tree-optimization/56756 + * gcc.dg/torture/pr56756.c: New testcase. + 2013-04-16 Tobias Burnus PR fortran/56969 diff --git a/gcc/testsuite/gcc.dg/torture/pr56756.c b/gcc/testsuite/gcc.dg/torture/pr56756.c new file mode 100644 index 000000000000..470014d26607 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr56756.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ + +int a, *b; + +void f(void) +{ + if(a) + { + int k; + + for(a = 0; a < 1; a++) + { + int **q; + f(); + + for(; **q; ++**q) + lbl: + if(a) + { + a = 0; + goto lbl; + } + + b = &k; + } + } + goto lbl; +} diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 085789165a2e..188af0012a7f 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -1718,6 +1718,32 @@ rewrite_mem_refs (struct loop *loop, mem_ref_p ref, tree tmp_var) for_all_locs_in_loop (loop, ref, rewrite_mem_ref_loc (tmp_var)); } +/* Stores the first reference location in LOCP. */ + +struct first_mem_ref_loc_1 +{ + first_mem_ref_loc_1 (mem_ref_loc_p *locp_) : locp (locp_) {} + bool operator()(mem_ref_loc_p loc); + mem_ref_loc_p *locp; +}; + +bool +first_mem_ref_loc_1::operator()(mem_ref_loc_p loc) +{ + *locp = loc; + return true; +} + +/* Returns the first reference location to REF in LOOP. */ + +static mem_ref_loc_p +first_mem_ref_loc (struct loop *loop, mem_ref_p ref) +{ + mem_ref_loc_p locp = NULL; + for_all_locs_in_loop (loop, ref, first_mem_ref_loc_1 (&locp)); + return locp; +} + /* The name and the length of the currently generated variable for lsm. */ #define MAX_LSM_NAME_LENGTH 40 @@ -2022,9 +2048,10 @@ execute_sm (struct loop *loop, vec exits, mem_ref_p ref) unsigned i; gimple load; struct fmt_data fmt_data; - edge ex, latch_edge; + edge ex; struct lim_aux_data *lim_data; bool multi_threaded_model_p = false; + gimple_stmt_iterator gsi; if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -2049,9 +2076,10 @@ execute_sm (struct loop *loop, vec exits, mem_ref_p ref) rewrite_mem_refs (loop, ref, tmp_var); - /* Emit the load code into the latch, so that we are sure it will - be processed after all dependencies. */ - latch_edge = loop_latch_edge (loop); + /* Emit the load code on a random exit edge or into the latch if + the loop does not exit, so that we are sure it will be processed + by move_computations after all dependencies. */ + gsi = gsi_for_stmt (first_mem_ref_loc (loop, ref)->stmt); /* FIXME/TODO: For the multi-threaded variant, we could avoid this load altogether, since the store is predicated by a flag. We @@ -2060,7 +2088,7 @@ execute_sm (struct loop *loop, vec exits, mem_ref_p ref) lim_data = init_lim_data (load); lim_data->max_loop = loop; lim_data->tgt_loop = loop; - gsi_insert_on_edge (latch_edge, load); + gsi_insert_before (&gsi, load, GSI_SAME_STMT); if (multi_threaded_model_p) { @@ -2068,7 +2096,7 @@ execute_sm (struct loop *loop, vec exits, mem_ref_p ref) lim_data = init_lim_data (load); lim_data->max_loop = loop; lim_data->tgt_loop = loop; - gsi_insert_on_edge (latch_edge, load); + gsi_insert_before (&gsi, load, GSI_SAME_STMT); } /* Sink the store to every exit from the loop. */ -- 2.43.5