aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2005-07-02 08:15:11 -0600
committerJeff Law <law@gcc.gnu.org>2005-07-02 08:15:11 -0600
commit2d0dab7f2bb2acbc9a9fffc7278be44c9a1dcd43 (patch)
treebc249b4ee590ce8d295fe4bb0175dcaab1069eb6
parentc85ce869e757158c55fd428befdb59ad5d537c1f (diff)
downloadgcc-2d0dab7f2bb2acbc9a9fffc7278be44c9a1dcd43.zip
gcc-2d0dab7f2bb2acbc9a9fffc7278be44c9a1dcd43.tar.gz
gcc-2d0dab7f2bb2acbc9a9fffc7278be44c9a1dcd43.tar.bz2
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr22051-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr22051-2.c25
-rw-r--r--gcc/tree-ssa-dom.c22
5 files changed, 82 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ca0762e7..6e5396a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2005-07-02 Jeff Law <law@redhat.com>
+
+ * 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 <joseph@codesourcery.com>
* c.opt, common.opt, config/bfin/bfin.opt, config/pa/pa.opt,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 65caac9..320f6ec 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-07-02 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/pr22051-1.c: New test.
+ * gcc.dg/tree-ssa/pr22051-2.c: New test.
+
2005-07-02 Joseph S. Myers <joseph@codesourcery.com>
* 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 0000000..4815be0
--- /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 0000000..aa4c00a
--- /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 86da07b..e341a68 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.