From e08f02f0bbb9691358c576baeeec19d17b943408 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Thu, 1 Nov 2007 03:06:38 +0000 Subject: [PATCH] re PR tree-optimization/33961 (gcc 4.3 causes crash valid code to crash) PR tree-optimization/33961 * tree-ssa-phiopt.c (struct name_to_bb.store): New member. (name_to_bb_hash, name_to_bb_eq): Consider and check it. (add_or_mark_expr): New argument 'store', using it to search the hash table. (nt_init_block): Adjust calls to add_or_mark_expr. * gcc.dg/pr33961.c: New test. From-SVN: r129817 --- gcc/ChangeLog | 9 ++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/pr33961.c | 23 +++++++++++++++ gcc/tree-ssa-phiopt.c | 52 ++++++++++++++++++++++------------ 4 files changed, 71 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr33961.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ad2c78de0ca..6c7898647d2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2007-11-01 Michael Matz PR target/31507 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bd9eb7b1e7d..8332c432beb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-11-01 Michael Matz + + PR tree-optimization/33961 + * gcc.dg/pr33961.c: New test. + 2007-10-31 Paolo Carlini PR c++/33494 diff --git a/gcc/testsuite/gcc.dg/pr33961.c b/gcc/testsuite/gcc.dg/pr33961.c new file mode 100644 index 00000000000..43403ed30a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr33961.c @@ -0,0 +1,23 @@ +/* PR tree-optimization/33961 */ +/* { dg-do run } */ +/* { dg-options "-O2 -ftree-cselim" } */ + +void decode(char *d, int len); + +void decode(char *d, int len) { + int i = len - 1; + while(i >= 0) { + d[i]; + if(d[i] == 0) + d[i]=' '; + if(d[i] == 1) + d[i]='x'; + i--; + } +} + +int main(int argc, char **argv) +{ + decode("this bug is really weird", 24); + return 0; +} diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 6df8420c22f..e51bac6232c 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -1078,9 +1078,17 @@ abs_replacement (basic_block cond_bb, basic_block middle_bb, simply is a walk over all instructions in dominator order. When we see an INDIRECT_REF we determine if we've already seen a same ref anywhere up to the root of the dominator tree. If we do the - current access can't trap. If we don't see any dominator access + current access can't trap. If we don't see any dominating access the current access might trap, but might also make later accesses - non-trapping, so we remember it. */ + non-trapping, so we remember it. We need to be careful with loads + or stores, for instance a load might not trap, while a store would, + so if we see a dominating read access this doesn't mean that a later + write access would not trap. Hence we also need to differentiate the + type of access(es) seen. + + ??? We currently are very conservative and assume that a load might + trap even if a store doesn't (write-only memory). This probably is + overly conservative. */ /* A hash-table of SSA_NAMEs, and in which basic block an INDIRECT_REF through it was seen, which would constitute a no-trap region for @@ -1089,6 +1097,7 @@ struct name_to_bb { tree ssa_name; basic_block bb; + unsigned store : 1; }; /* The hash table for remembering what we've seen. */ @@ -1102,7 +1111,7 @@ static hashval_t name_to_bb_hash (const void *p) { tree n = ((struct name_to_bb *)p)->ssa_name; - return htab_hash_pointer (n); + return htab_hash_pointer (n) ^ ((struct name_to_bb *)p)->store; } /* The equality function of *P1 and *P2. SSA_NAMEs are shared, so @@ -1110,17 +1119,20 @@ name_to_bb_hash (const void *p) static int name_to_bb_eq (const void *p1, const void *p2) { - tree n1 = ((struct name_to_bb *)p1)->ssa_name; - tree n2 = ((struct name_to_bb *)p2)->ssa_name; + const struct name_to_bb *n1 = (const struct name_to_bb *)p1; + const struct name_to_bb *n2 = (const struct name_to_bb *)p2; - return n1 == n2; + return n1->ssa_name == n2->ssa_name && n1->store == n2->store; } /* We see a the expression EXP in basic block BB. If it's an interesting expression (an INDIRECT_REF through an SSA_NAME) possibly insert the - expression into the set NONTRAP or the hash table of seen expressions. */ + expression into the set NONTRAP or the hash table of seen expressions. + STORE is true if this expression is on the LHS, otherwise it's on + the RHS. */ static void -add_or_mark_expr (basic_block bb, tree exp, struct pointer_set_t *nontrap) +add_or_mark_expr (basic_block bb, tree exp, + struct pointer_set_t *nontrap, bool store) { if (INDIRECT_REF_P (exp) && TREE_CODE (TREE_OPERAND (exp, 0)) == SSA_NAME) @@ -1128,15 +1140,18 @@ add_or_mark_expr (basic_block bb, tree exp, struct pointer_set_t *nontrap) tree name = TREE_OPERAND (exp, 0); struct name_to_bb map; void **slot; + struct name_to_bb *n2bb; basic_block found_bb = 0; /* Try to find the last seen INDIRECT_REF through the same SSA_NAME, which can trap. */ map.ssa_name = name; map.bb = 0; + map.store = store; slot = htab_find_slot (seen_ssa_names, &map, INSERT); - if (*slot) - found_bb = ((struct name_to_bb *)*slot)->bb; + n2bb = (struct name_to_bb *) *slot; + if (n2bb) + found_bb = n2bb->bb; /* If we've found a trapping INDIRECT_REF, _and_ it dominates EXP (it's in a basic block on the path from us to the dominator root) @@ -1148,16 +1163,17 @@ add_or_mark_expr (basic_block bb, tree exp, struct pointer_set_t *nontrap) else { /* EXP might trap, so insert it into the hash table. */ - if (*slot) + if (n2bb) { - ((struct name_to_bb *)*slot)->bb = bb; + n2bb->bb = bb; } else { - struct name_to_bb *nmap = XNEW (struct name_to_bb); - nmap->ssa_name = name; - nmap->bb = bb; - *slot = nmap; + n2bb = XNEW (struct name_to_bb); + n2bb->ssa_name = name; + n2bb->bb = bb; + n2bb->store = store; + *slot = n2bb; } } } @@ -1180,8 +1196,8 @@ nt_init_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb) { tree lhs = GIMPLE_STMT_OPERAND (stmt, 0); tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); - add_or_mark_expr (bb, rhs, nontrap_set); - add_or_mark_expr (bb, lhs, nontrap_set); + add_or_mark_expr (bb, rhs, nontrap_set, false); + add_or_mark_expr (bb, lhs, nontrap_set, true); } } } -- 2.30.2