OSDN Git Service

2004-04-26 Richard Guenther <rguenth@gcc.gnu.org>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Apr 2005 16:35:31 +0000 (16:35 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Apr 2005 16:35:31 +0000 (16:35 +0000)
PR tree-optimization/17598
* fold-const.c (fold_binary): Fold comparisons of addresses
of COMPONENT_REFs which reference the same field to
comparisons of the addresses of the base objects.

* gcc.dg/tree-ssa/pr17598.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@98775 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr17598.c [new file with mode: 0644]

index 07c96a5..2d57e1f 100644 (file)
@@ -1,3 +1,10 @@
+2004-04-26  Richard Guenther  <rguenth@gcc.gnu.org>
+
+       PR tree-optimization/17598
+       * fold-const.c (fold_binary): Fold comparisons of addresses
+       of COMPONENT_REFs which reference the same field to
+       comparisons of the addresses of the base objects.
+
 2005-04-26  Julian Brown  <julian@codesourcery.com>
 
        * config/arm/arm.c (arm_return_in_msb): New function.
index 416d89e..9de988c 100644 (file)
@@ -9708,6 +9708,39 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
            return t1;
        }
 
+      /* Fold a comparison of the address of COMPONENT_REFs with the same
+         type and component to a comparison of the address of the base
+        object.  In short, &x->a OP &y->a to x OP y and
+         &x->a OP &y.a to x OP &y  */
+      if (TREE_CODE (arg0) == ADDR_EXPR
+         && TREE_CODE (TREE_OPERAND (arg0, 0)) == COMPONENT_REF
+         && TREE_CODE (arg1) == ADDR_EXPR
+         && TREE_CODE (TREE_OPERAND (arg1, 0)) == COMPONENT_REF)
+        {
+         tree cref0 = TREE_OPERAND (arg0, 0);
+         tree cref1 = TREE_OPERAND (arg1, 0);
+         if (TREE_OPERAND (cref0, 1) == TREE_OPERAND (cref1, 1))
+           {
+             tree op0 = TREE_OPERAND (cref0, 0);
+             tree op1 = TREE_OPERAND (cref1, 0);
+             if (TREE_CODE (op0) == INDIRECT_REF)
+               op0 = TREE_OPERAND (op0, 0);
+             else
+               {
+                 tree ptype = build_pointer_type (TREE_TYPE (op0));
+                 op0 = build1 (ADDR_EXPR, ptype, op0);
+               }
+             if (TREE_CODE (op1) == INDIRECT_REF)
+               op1 = TREE_OPERAND (op1, 0);
+             else
+               {
+                 tree ptype = build_pointer_type (TREE_TYPE (op1));
+                 op1 = build1 (ADDR_EXPR, ptype, op1);
+               }
+             return fold_build2 (code, type, op0, op1);
+           }
+       }
+
       /* If this is a comparison of complex values and either or both sides
         are a COMPLEX_EXPR or COMPLEX_CST, it is best to split up the
         comparisons and join them with a TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR.
index 5efc74b..17d9542 100644 (file)
@@ -1,3 +1,8 @@
+2004-04-26  Richard Guenther  <rguenth@gcc.gnu.org>
+
+       PR tree-optimization/17598
+       * gcc.dg/tree-ssa/pr17598.c: New testcase.
+
 2005-04-25  Mike Stump  <mrs@apple.com>
 
        * objc.dg/fix-and-continue-1.m: Add.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr17598.c b/gcc/testsuite/gcc.dg/tree-ssa/pr17598.c
new file mode 100644 (file)
index 0000000..9313623
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-generic" } */
+
+struct f
+{
+  int i;
+  int j;
+};
+
+struct g
+{
+  int i;
+  struct f j;
+  struct f *k;
+};
+
+int foo(struct f *x, struct f *y)
+{
+  return &x->j == &y->j; /* x == y */
+}
+
+struct f y;
+int bar(struct f *x)
+{
+  return &x->j == &y.j; /* x == &y */
+}
+
+struct g yy;
+int foobar(struct g *x)
+{
+  return &x->j.i == &yy.j.i; /* x == &yy */
+}
+int foobar2(struct g *x)
+{
+  return &x->k->i == &yy.k->i; /* x->k == yy.k */
+}
+
+/* { dg-final { scan-tree-dump-times "x == y" 1 "generic" } } */
+/* { dg-final { scan-tree-dump-times "x == &y" 2 "generic" } } */
+/* { dg-final { scan-tree-dump "x->k" "generic" } } */
+/* { dg-final { scan-tree-dump "yy.k" "generic" } } */
+/* { dg-final { cleanup-tree-dump "generic" } } */