From: Richard Guenther Date: Fri, 4 May 2012 11:30:35 +0000 (+0000) Subject: re PR tree-optimization/53168 (ICE in find_or_generate_expression, at tree-ssa-pre... X-Git-Tag: misc/gccgo-go1_1_2~3099 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=efe7068bc9c80858b6025e737eafb90b0a7882c5;p=thirdparty%2Fgcc.git re PR tree-optimization/53168 (ICE in find_or_generate_expression, at tree-ssa-pre.c:3053) 2012-05-04 Richard Guenther 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 63ec602a300a..72e3264c3459 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-05-04 Richard Guenther + + 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 * common.opt (flto-report): Do not mark as Optimization. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 581b8b87287c..e26d07258bb9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-05-04 Richard Guenther + + 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 * gcc.dg/lto/pr53214_0.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/torture/pr53168.c b/gcc/testsuite/gcc.dg/torture/pr53168.c new file mode 100644 index 000000000000..0b9a8dce6093 --- /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 000000000000..68a7a7f826ec --- /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 776a37cdcc6e..fcd7feeea1e6 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);