tree-vn.c (expressions_equal_p): Do not check type equality or compatibility before...
authorRichard Guenther <rguenther@suse.de>
Thu, 17 Apr 2008 09:09:31 +0000 (09:09 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 17 Apr 2008 09:09:31 +0000 (09:09 +0000)
2008-04-17  Richard Guenther  <rguenther@suse.de>

* tree-vn.c (expressions_equal_p): Do not check type
equality or compatibility before calling operand_equal_p.
* fold-const.c (operand_equal_p): Check equivalence of
integer constants before bailing out due to signedness or
precision differences.
* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Ignore
spurious differences in type qualification.  Ignore types
for COMPONENT_REFs at all.

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

From-SVN: r134384

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

index 4efd1c0ecc2b0bfb9b653964da6c75fba166857b..4a3a4d0bd5303283b7053a63e682d988dceea98a 100644 (file)
@@ -1,3 +1,14 @@
+2008-04-17  Richard Guenther  <rguenther@suse.de>
+
+       * tree-vn.c (expressions_equal_p): Do not check type
+       equality or compatibility before calling operand_equal_p.
+       * fold-const.c (operand_equal_p): Check equivalence of
+       integer constants before bailing out due to signedness or
+       precision differences.
+       * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Ignore
+       spurious differences in type qualification.  Ignore types
+       for COMPONENT_REFs at all.
+
 2008-04-17  Christian Bruel  <christian.bruel@st.com>
 
        * config/sh/sh.c (expand_cbranchdi4): Use original operands for
index c1451789af0d19d2c1a001dfbe3f3964b5055dbf..4e467615dd12940a2db1a42e1af4dc421dc22882 100644 (file)
@@ -3026,6 +3026,11 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
   if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK)
     return 0;
 
+  /* Check equality of integer constants before bailing out due to
+     precision differences.  */
+  if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
+    return tree_int_cst_equal (arg0, arg1);
+
   /* If both types don't have the same signedness, then we can't consider
      them equal.  We must check this before the STRIP_NOPS calls
      because they may change the signedness of the arguments.  */
index 88c24ec7f3d7078a7aebc9b158a7cd4f4c6fa2b3..3723bcf7392aefae29d7b153bddb7b4fa33742f9 100644 (file)
@@ -1,3 +1,7 @@
+2008-04-17  Richard Guenther  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/ssa-fre-17.c: New testcase.
+
 2008-04-17  Christian Bruel  <christian.bruel@st.com>
 
        * gcc.dg/long-long-compare-1.c: New testcase. 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-17.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-17.c
new file mode 100644 (file)
index 0000000..aced649
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre-details -fno-tree-sra" } */
+
+struct Bar {
+  int dom;
+};
+struct Foo {
+  struct Bar doms[3];
+};
+
+int foo(int i, int j, int k)
+{
+  struct Foo f;
+
+  f.doms[0].dom = i;
+  f.doms[1].dom = j;
+  f.doms[2].dom = k;
+  return f.doms[0LL].dom;
+}
+
+/* { dg-final { scan-tree-dump "Replaced f.doms\\\[0\\\].dom with i_" "fre" } } */
+/* { dg-final { cleanup-tree-dump "fre" } } */
+
index 849eade1d210c3b3322daa9f304c4eecb44ca101..6fc0840150f8077fe19b2d335e8f21f9982a1b2a 100644 (file)
@@ -511,7 +511,8 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
       vn_reference_op_s temp;
 
       memset (&temp, 0, sizeof (temp));
-      temp.type = TREE_TYPE (ref);
+      /* We do not care for spurious type qualifications.  */
+      temp.type = TYPE_MAIN_VARIANT (TREE_TYPE (ref));
       temp.opcode = TREE_CODE (ref);
 
       switch (temp.opcode)
@@ -528,6 +529,10 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
          temp.op1 = TREE_OPERAND (ref, 2);
          break;
        case COMPONENT_REF:
+         /* The field decl is enough to unambiguously specify the field,
+            a matching type is not necessary and a mismatching type
+            is always a spurious difference.  */
+         temp.type = NULL_TREE;
          /* If this is a reference to a union member, record the union
             member size as operand.  Do so only if we are doing
             expression insertion (during FRE), as PRE currently gets
@@ -536,10 +541,7 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
              && TREE_CODE (DECL_CONTEXT (TREE_OPERAND (ref, 1))) == UNION_TYPE
              && integer_zerop (DECL_FIELD_OFFSET (TREE_OPERAND (ref, 1)))
              && integer_zerop (DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1))))
-           {
-             temp.type = NULL_TREE;
-             temp.op0 = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (ref, 1)));
-           }
+           temp.op0 = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (ref, 1)));
          else
            /* Record field as operand.  */
            temp.op0 = TREE_OPERAND (ref, 1);
index c09dfb762849e80429c083c1a42e1fa9df879f3b..40efea6f8f7222eb73dd062f05ef8eecd3baa46c 100644 (file)
@@ -83,8 +83,6 @@ expressions_equal_p (tree e1, tree e2)
 
     }
   else if (TREE_CODE (e1) == TREE_CODE (e2)
-          && (te1 == te2
-              || types_compatible_p (te1, te2))
           && operand_equal_p (e1, e2, OEP_PURE_SAME))
     return true;