diff options
author | Richard Guenther <rguenther@suse.de> | 2012-05-04 11:30:35 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-05-04 11:30:35 +0000 |
commit | efe7068bc9c80858b6025e737eafb90b0a7882c5 (patch) | |
tree | 7d21863fba308e651133dda59a0cb35c8c4490e7 /gcc | |
parent | 1d67dde88392a5271855bf4d8420764e4e3f451a (diff) | |
download | gcc-efe7068bc9c80858b6025e737eafb90b0a7882c5.zip gcc-efe7068bc9c80858b6025e737eafb90b0a7882c5.tar.gz gcc-efe7068bc9c80858b6025e737eafb90b0a7882c5.tar.bz2 |
re PR tree-optimization/53168 (ICE in find_or_generate_expression, at tree-ssa-pre.c:3053)
2012-05-04 Richard Guenther <rguenther@suse.de>
PR tree-optimization/53168
* tree-ssa-pre.c (phi_translate_1): Only handle type-punned
memory reads when the result is a constant we can pun.
* gcc.dg/torture/pr53168.c: New testcase.
* gcc.dg/tree-ssa/ssa-pre-30.c: Likewise.
From-SVN: r187153
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr53168.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c | 27 | ||||
-rw-r--r-- | gcc/tree-ssa-pre.c | 78 |
5 files changed, 89 insertions, 56 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 63ec602..72e3264 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2012-05-04 Richard Guenther <rguenther@suse.de> + PR tree-optimization/53168 + * tree-ssa-pre.c (phi_translate_1): Only handle type-punned + memory reads when the result is a constant we can pun. + +2012-05-04 Richard Guenther <rguenther@suse.de> + * common.opt (flto-report): Do not mark as Optimization. 2012-05-04 Eric Botcazou <ebotcazou@adacore.com> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 581b8b8..e26d072 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2012-05-04 Richard Guenther <rguenther@suse.de> + PR tree-optimization/53168 + * gcc.dg/torture/pr53168.c: New testcase. + * gcc.dg/tree-ssa/ssa-pre-30.c: Likewise. + +2012-05-04 Richard Guenther <rguenther@suse.de> + * gcc.dg/lto/pr53214_0.c: New testcase. 2012-05-04 Eric Botcazou <ebotcazou@adacore.com> diff --git a/gcc/testsuite/gcc.dg/torture/pr53168.c b/gcc/testsuite/gcc.dg/torture/pr53168.c new file mode 100644 index 0000000..0b9a8dc --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr53168.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ + +int a, b, c; +unsigned *d; +int e[1]; +void fn1 (); +int fn2 (); +int +fn3 () +{ + int *f = &a; + if (fn2 ()) + { + for (; c; c++) + { + e[a] && (b = 0); + fn1 (); + if (e[a]) + return 0; + } + for (; c <= 0; c++) + for (;;) + ; + } + else + e[0] = 0 != (d = f); + return *d; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c new file mode 100644 index 0000000..68a7a7f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-pre-details" } */ + +int f; +int g; +unsigned int +foo (int b, int x) +{ + if (b) + x = *(int *)&f; + g = x; + return *(unsigned int*)&f; +} +float +bar (int b, int x) +{ + if (b) + x = *(int *)&f; + g = x; + return *(float *)&f; +} + +/* We should see the partial redundant loads of f even though they + are using different types (of the same size). */ + +/* { dg-final { scan-tree-dump-times "Replaced MEM" 2 "pre" } } */ +/* { dg-final { cleanup-tree-dump "pre" } } */ diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 776a37c..fcd7fee 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -1659,7 +1659,6 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, { unsigned int new_val_id; pre_expr constant; - bool converted = false; tree result = vn_reference_lookup_pieces (newvuse, ref->set, ref->type, @@ -1668,12 +1667,29 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, if (result) VEC_free (vn_reference_op_s, heap, newoperands); - if (result - && !useless_type_conversion_p (ref->type, TREE_TYPE (result))) + /* We can always insert constants, so if we have a partial + redundant constant load of another type try to translate it + to a constant of appropriate type. */ + if (result && is_gimple_min_invariant (result)) { - result = fold_build1 (VIEW_CONVERT_EXPR, ref->type, result); - converted = true; + tree tem = result; + if (!useless_type_conversion_p (ref->type, TREE_TYPE (result))) + { + tem = fold_unary (VIEW_CONVERT_EXPR, ref->type, result); + if (tem && !is_gimple_min_invariant (tem)) + tem = NULL_TREE; + } + if (tem) + return get_or_alloc_expr_for_constant (tem); } + + /* If we'd have to convert things we would need to validate + if we can insert the translated expression. So fail + here for now - we cannot insert an alias with a different + type in the VN tables either, as that would assert. */ + if (result + && !useless_type_conversion_p (ref->type, TREE_TYPE (result))) + return NULL; else if (!result && newref && !useless_type_conversion_p (ref->type, newref->type)) { @@ -1681,61 +1697,11 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, return NULL; } - if (result && is_gimple_min_invariant (result)) - { - gcc_assert (!newoperands); - return get_or_alloc_expr_for_constant (result); - } - expr = (pre_expr) pool_alloc (pre_expr_pool); expr->kind = REFERENCE; expr->id = 0; - if (converted) - { - vn_nary_op_t nary; - tree nresult; - - gcc_assert (CONVERT_EXPR_P (result) - || TREE_CODE (result) == VIEW_CONVERT_EXPR); - - nresult = vn_nary_op_lookup_pieces (1, TREE_CODE (result), - TREE_TYPE (result), - &TREE_OPERAND (result, 0), - &nary); - if (nresult && is_gimple_min_invariant (nresult)) - return get_or_alloc_expr_for_constant (nresult); - - expr->kind = NARY; - if (nary) - { - PRE_EXPR_NARY (expr) = nary; - constant = fully_constant_expression (expr); - if (constant != expr) - return constant; - - new_val_id = nary->value_id; - get_or_alloc_expression_id (expr); - } - else - { - new_val_id = get_next_value_id (); - VEC_safe_grow_cleared (bitmap_set_t, heap, - value_expressions, - get_max_value_id() + 1); - nary = vn_nary_op_insert_pieces (1, TREE_CODE (result), - TREE_TYPE (result), - &TREE_OPERAND (result, 0), - NULL_TREE, - new_val_id); - PRE_EXPR_NARY (expr) = nary; - constant = fully_constant_expression (expr); - if (constant != expr) - return constant; - get_or_alloc_expression_id (expr); - } - } - else if (newref) + if (newref) { PRE_EXPR_REFERENCE (expr) = newref; constant = fully_constant_expression (expr); |