From: Richard Guenther Date: Wed, 20 Aug 2008 13:21:41 +0000 (+0000) Subject: tree-ssa-forwprop.c (forward_propagate_addr_expr_1): More properly handle conversion... X-Git-Tag: releases/gcc-4.4.0~3046 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4fedf870f576c5981624c815c140130c76821f0f;p=thirdparty%2Fgcc.git tree-ssa-forwprop.c (forward_propagate_addr_expr_1): More properly handle conversion/copy chains after tuplification. 2008-08-20 Richard Guenther * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): More properly handle conversion/copy chains after tuplification. * gcc.dg/tree-ssa/forwprop-9.c: Scan FRE dump as well. * gcc.dg/tree-ssa/forwprop-10.c: New testcase. From-SVN: r139288 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 55d7448e5084..af90a99ca22e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2008-08-20 Richard Guenther + + * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): More + properly handle conversion/copy chains after tuplification. + 2008-08-20 Richard Guenther * passes.c (init_optimization_passes): Move the second diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 42ec9c04b774..36c0c41d6b86 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-08-20 Richard Guenther + + * gcc.dg/tree-ssa/forwprop-9.c: Scan FRE dump as well. + * gcc.dg/tree-ssa/forwprop-10.c: New testcase. + 2008-08-20 Richard Guenther * gcc.dg/tree-ssa/20030530-2.c: Scan dom2 dump. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-10.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-10.c new file mode 100644 index 000000000000..0b865245a965 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-10.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-forwprop1" } */ + +int b; +unsigned a; + +static inline int *g(void) +{ + a = 1; + return (int*)&a; +} +void test2(void) +{ + b = *g(); +} + +/* The indirect load should be replaced by a load from a and a + conversion to int. */ + +/* { dg-final { scan-tree-dump "= a;" "forwprop1" } } */ +/* { dg-final { scan-tree-dump "= \\\(int\\\) " "forwprop1" } } */ +/* { dg-final { scan-tree-dump-not "= \\\*" "forwprop1" } } */ +/* { dg-final { cleanup-tree-dump "forwprop1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c index 70630d01a343..4469fe7312ed 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -fdump-tree-final_cleanup -W -Wall -fno-early-inlining" } */ - +/* { dg-options "-O1 -fdump-tree-final_cleanup -fdump-tree-fre -W -Wall -fno-early-inlining" } */ int b; unsigned a; @@ -13,6 +12,10 @@ void f(void) { b = *g(); } -/* We should have converted the assignments to two = 1. */ + +/* We should have converted the assignments to two = 1. FRE does this. */ + /* { dg-final { scan-tree-dump-times " = 1" 2 "final_cleanup"} } */ +/* { dg-final { scan-tree-dump-not " = a;" "fre"} } */ +/* { dg-final { cleanup-tree-dump "fre" } } */ /* { dg-final { cleanup-tree-dump "final_cleanup" } } */ diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 64eb2d8dcf6f..bf860d907587 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -689,15 +689,22 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, a conversion to def_rhs type separate, though. */ if (TREE_CODE (lhs) == SSA_NAME && ((rhs_code == SSA_NAME && rhs == name) - || CONVERT_EXPR_CODE_P (rhs_code)) - && useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs))) + || CONVERT_EXPR_CODE_P (rhs_code))) { - /* Only recurse if we don't deal with a single use. */ - if (!single_use_p) + /* Only recurse if we don't deal with a single use or we cannot + do the propagation to the current statement. In particular + we can end up with a conversion needed for a non-invariant + address which we cannot do in a single statement. */ + if (!single_use_p + || (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs)) + && !is_gimple_min_invariant (def_rhs))) return forward_propagate_addr_expr (lhs, def_rhs); gimple_assign_set_rhs1 (use_stmt, unshare_expr (def_rhs)); - gimple_assign_set_rhs_code (use_stmt, TREE_CODE (def_rhs)); + if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs))) + gimple_assign_set_rhs_code (use_stmt, TREE_CODE (def_rhs)); + else + gimple_assign_set_rhs_code (use_stmt, NOP_EXPR); return true; }