From: Jeff Law Date: Sat, 2 Jul 2005 14:15:11 +0000 (-0600) Subject: tree-ssa-dom.c (find_equivalent_equality_comparison): Do not a eliminate type convers... X-Git-Tag: misc/cutover-cvs2svn~2005 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2d0dab7f2bb2acbc9a9fffc7278be44c9a1dcd43;p=thirdparty%2Fgcc.git tree-ssa-dom.c (find_equivalent_equality_comparison): Do not a eliminate type conversion which feeds an equality comparison if... * tree-ssa-dom.c (find_equivalent_equality_comparison): Do not a eliminate type conversion which feeds an equality comparison if the original type or either operand in the comparison is a function pointer. * gcc.dg/tree-ssa/pr22051-1.c: New test. * gcc.dg/tree-ssa/pr22051-2.c: New test. From-SVN: r101534 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ca0762e7d45e..6e5396a04a26 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2005-07-02 Jeff Law + + * tree-ssa-dom.c (find_equivalent_equality_comparison): Do not + a eliminate type conversion which feeds an equality comparison + if the original type or either operand in the comparison is a + function pointer. + 2005-07-02 Joseph S. Myers * c.opt, common.opt, config/bfin/bfin.opt, config/pa/pa.opt, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 65caac9e4e16..320f6ecf10a1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-07-02 Jeff Law + + * gcc.dg/tree-ssa/pr22051-1.c: New test. + * gcc.dg/tree-ssa/pr22051-2.c: New test. + 2005-07-02 Joseph S. Myers * gcc.dg/format/gcc_diag-1.c: Update. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr22051-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr22051-1.c new file mode 100644 index 000000000000..4815be0ac9e1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr22051-1.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + +void *arf (); +int +foo() +{ + void *p = arf (); + + if ((void (*)(void))p != 0) + return 1; + else + return 2; +} + +/* The cast to a function pointer type must remain after all optimizations + are complete so that function pointer canonicalization works on those + targets which require it. */ +/* { dg-final { scan-tree-dump-times "if \\(\\(void \\(\\*<.*>\\) \\(void\\)\\) p" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr22051-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr22051-2.c new file mode 100644 index 000000000000..aa4c00aa682e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr22051-2.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized -w" } */ + + + + +void *arf (); +int +foo() +{ + void (*q)(void); + int r = q; + + if (r != 0) + return 1; + else + return 2; +} + +/* The cast to an int type must remain after all optimizations are complete + so that we do not try to canonicalize a function pointer for the + comparison when no such canonicalization is wanted. */ +/* { dg-final { scan-tree-dump-times "if \\(\\(int\\) q" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ + diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 86da07b437f3..e341a68242ae 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -1882,6 +1882,18 @@ find_equivalent_equality_comparison (tree cond) { tree def_rhs = TREE_OPERAND (def_stmt, 1); + + /* If either operand to the comparison is a pointer to + a function, then we can not apply this optimization + as some targets require function pointers to be + canonicalized and in this case this optimization would + eliminate a necessary canonicalization. */ + if ((POINTER_TYPE_P (TREE_TYPE (op0)) + && TREE_CODE (TREE_TYPE (TREE_TYPE (op0))) == FUNCTION_TYPE) + || (POINTER_TYPE_P (TREE_TYPE (op1)) + && TREE_CODE (TREE_TYPE (TREE_TYPE (op1))) == FUNCTION_TYPE)) + return NULL; + /* Now make sure the RHS of the MODIFY_EXPR is a typecast. */ if ((TREE_CODE (def_rhs) == NOP_EXPR || TREE_CODE (def_rhs) == CONVERT_EXPR) @@ -1895,6 +1907,16 @@ find_equivalent_equality_comparison (tree cond) > TYPE_PRECISION (TREE_TYPE (def_rhs))) return NULL; + /* If the inner type of the conversion is a pointer to + a function, then we can not apply this optimization + as some targets require function pointers to be + canonicalized. This optimization would result in + canonicalization of the pointer when it was not originally + needed/intended. */ + if (POINTER_TYPE_P (def_rhs_inner_type) + && TREE_CODE (TREE_TYPE (def_rhs_inner_type)) == FUNCTION_TYPE) + return NULL; + /* What we want to prove is that if we convert OP1 to the type of the object inside the NOP_EXPR that the result is still equivalent to SRC.