From: Richard Guenther Date: Mon, 17 Mar 2008 14:34:21 +0000 (+0000) Subject: re PR tree-optimization/19637 (Missed VRP and FRE opportunities in the presence of... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c4e5b5a8bf81daa9e21c17149a4943b96c8099b3;p=gcc.git re PR tree-optimization/19637 (Missed VRP and FRE opportunities in the presence of casts) 2008-03-17 Richard Guenther PR tree-optimization/19637 * fold-const.c (fold_unary): Remove restrictions of removing intermediate pointer-conversions (P2)(P1)P0. * tree-ssa-ccp.c (maybe_fold_stmt_addition): Recover from conversion to void pointer. (get_maxval_strlen): Handle addresses of the form &(*p)[0]. * g++.dg/tree-ssa/pr19637.C: New testcase. From-SVN: r133291 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fa2ed097f62..28309279b79 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2008-03-17 Richard Guenther + + PR tree-optimization/19637 + * fold-const.c (fold_unary): Remove restrictions of removing + intermediate pointer-conversions (P2)(P1)P0. + * tree-ssa-ccp.c (maybe_fold_stmt_addition): Recover from + conversion to void pointer. + (get_maxval_strlen): Handle addresses of the form &(*p)[0]. + 2008-03-16 James E. Wilson PR debug/31510 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 4dc4ad72e3c..3bfe52e0081 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -7784,9 +7784,7 @@ fold_unary (enum tree_code code, tree type, tree op0) - the initial type is a pointer type and the precisions of the intermediate and final types differ, or - the final type is a pointer type and the precisions of the - initial and intermediate types differ. - - the initial type is a pointer to an array and the final type - not. */ + initial and intermediate types differ. */ if (! inside_float && ! inter_float && ! final_float && ! inside_vec && ! inter_vec && ! final_vec && (inter_prec >= inside_prec || inter_prec >= final_prec) @@ -7798,10 +7796,7 @@ fold_unary (enum tree_code code, tree type, tree op0) && ! (inside_ptr && inter_prec != final_prec) && ! (final_ptr && inside_prec != inter_prec) && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type)) - && TYPE_MODE (type) == TYPE_MODE (inter_type)) - && ! (inside_ptr && final_ptr - && TREE_CODE (TREE_TYPE (inside_type)) == ARRAY_TYPE - && TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE)) + && TYPE_MODE (type) == TYPE_MODE (inter_type))) return fold_build1 (code, type, TREE_OPERAND (op0, 0)); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 10ead70ab01..9242eca671c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-03-17 Richard Guenther + + PR tree-optimization/19637 + * g++.dg/tree-ssa/pr19637.C: New testcase. + 2008-03-16 Paul Thomas PR fortran/35470 diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19637.C b/gcc/testsuite/g++.dg/tree-ssa/pr19637.C new file mode 100644 index 00000000000..2d1dcceba42 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr19637.C @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom1" } */ + +#include + +struct Foo { + Foo() { i[0] = 1; } + int i[2]; +}; + +int foo_char(void) +{ + int i[2]; + new (reinterpret_cast(i)) Foo(); + return reinterpret_cast(i)->i[0]; +} + +int foo_void(void) +{ + int i[2]; + new (reinterpret_cast(i)) Foo(); + return reinterpret_cast(i)->i[0]; +} + +int foo_void_offset(void) +{ + int i[2]; + new (reinterpret_cast(&i[0])) Foo(); + return reinterpret_cast(&i[0])->i[0]; +} + +/* { dg-final { scan-tree-dump-times "return 1;" 3 "dom1" } } */ +/* { dg-final { cleanup-tree-dump "dom1" } } */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index f087a8d8948..7e519264f7a 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -2105,6 +2105,12 @@ maybe_fold_stmt_addition (tree expr) } ptd_type = TREE_TYPE (ptr_type); + /* If we want a pointer to void, reconstruct the reference from the + array element type. A pointer to that can be trivially converted + to void *. This happens as we fold (void *)(ptr p+ off). */ + if (VOID_TYPE_P (ptd_type) + && TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE) + ptd_type = TREE_TYPE (TREE_TYPE (op0)); /* At which point we can try some of the same things as for indirects. */ t = maybe_fold_offset_to_array_ref (op0, op1, ptd_type, true); @@ -2292,6 +2298,17 @@ get_maxval_strlen (tree arg, tree *length, bitmap visited, int type) if (TREE_CODE (arg) == COND_EXPR) return get_maxval_strlen (COND_EXPR_THEN (arg), length, visited, type) && get_maxval_strlen (COND_EXPR_ELSE (arg), length, visited, type); + /* We can end up with &(*iftmp_1)[0] here as well, so handle it. */ + else if (TREE_CODE (arg) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (arg, 0)) == ARRAY_REF + && integer_zerop (TREE_OPERAND (TREE_OPERAND (arg, 0), 1))) + { + tree aop0 = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); + if (TREE_CODE (aop0) == INDIRECT_REF + && TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME) + return get_maxval_strlen (TREE_OPERAND (aop0, 0), + length, visited, type); + } if (type == 2) {