diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5f0788fa7e0..ac0fd785378 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2009-10-09 Richard Guenther + + PR tree-optimization/41634 + * tree-ssa-dom.c (remove_local_expressions_from_table): Assert + we remove the correct elements. + (optimize_stmt): Make sure to update stmt operands before + optimizing redundancies. + 2009-10-09 Andreas Krebbel * config/s390/s390.md ("prefetch"): Remove stcmh for prefetching. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 73596d735f2..64e65d731e8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-10-09 Richard Guenther + + PR tree-optimization/41634 + * gcc.c-torture/compile/pr41634.c: New testcase. + 2009-10-09 Uros Bizjak * gfortran.dg/block_2.f08: Cleanup "original" tree dump. diff --git a/gcc/testsuite/gcc.c-torture/compile/pr41634.c b/gcc/testsuite/gcc.c-torture/compile/pr41634.c new file mode 100644 index 00000000000..976e463e2ba --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr41634.c @@ -0,0 +1,19 @@ +extern int _xgetw(); +extern int foo(char*); + +void test_readmode( int ascii_mode ) +{ + static const char outbuffer[] + = "0,1,2,3,4,5,6,7,8,9\r\n\r\nA,B,C,D,E\r\nX,Y,Z"; + char buffer[2*512 +256]; + int i, j, ao; + unsigned int fp; + + foo(buffer); + + for (i=0, j=0; i<6; i++) { + if (ao==0 || outbuffer[fp-3+i] != '\r') + buffer[j++] = outbuffer[fp-3+i]; + } + _xgetw(); +} diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 4bad3ddaf48..1e2c8f23ce8 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -816,24 +816,25 @@ remove_local_expressions_from_table (void) /* Remove all the expressions made available in this block. */ while (VEC_length (expr_hash_elt_t, avail_exprs_stack) > 0) { - struct expr_hash_elt element; expr_hash_elt_t victim = VEC_pop (expr_hash_elt_t, avail_exprs_stack); + void **slot; if (victim == NULL) break; - element = *victim; - /* This must precede the actual removal from the hash table, as ELEMENT and the table entry may share a call argument vector which will be freed during removal. */ if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "<<<< "); - print_expr_hash_elt (dump_file, &element); + print_expr_hash_elt (dump_file, victim); } - htab_remove_elt_with_hash (avail_exprs, &element, element.hash); + slot = htab_find_slot_with_hash (avail_exprs, + victim, victim->hash, NO_INSERT); + gcc_assert (slot && *slot == (void *) victim); + htab_clear_slot (avail_exprs, slot); } } @@ -2137,8 +2138,6 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si) if (may_optimize_p) { - eliminate_redundant_computations (&si); - stmt = gsi_stmt (si); if (gimple_code (stmt) == GIMPLE_CALL) { /* Resolve __builtin_constant_p. If it hasn't been @@ -2153,6 +2152,10 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si) stmt = gsi_stmt (si); } } + + update_stmt_if_modified (stmt); + eliminate_redundant_computations (&si); + stmt = gsi_stmt (si); } /* Record any additional equivalences created by this statement. */ @@ -2188,7 +2191,7 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si) { tree val = NULL; - update_stmt (stmt); + update_stmt_if_modified (stmt); if (gimple_code (stmt) == GIMPLE_COND) val = fold_binary_loc (gimple_location (stmt),