re PR tree-optimization/49770 (wrong code with -fno-tree-forwprop)
authorRichard Guenther <rguenther@suse.de>
Thu, 21 Jul 2011 13:19:18 +0000 (13:19 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 21 Jul 2011 13:19:18 +0000 (13:19 +0000)
2011-07-21  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/49770
* tree-ssa-sccvn.c (valueize_refs_1): Return whether we
valueized any operand.  Renamed from ...
(valueize_refs): ... this.  New wrapper around valueize_refs_1.
(valueize_shared_reference_ops_from_ref): Return whether we
valueized any operand.
(vn_reference_lookup): Only when we valueized any operand
use the valueized reference for alias analysis.  Do not preserve
the original reference tree in this case.

* g++.dg/torture/pr49770.C: New testcase.

From-SVN: r176567

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr49770.C [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

index c0c820ddcaccb8738c9c05350a424cf687ae92eb..a6904e524ea771f3a56cdf2c1b159faea443adbb 100644 (file)
@@ -1,3 +1,15 @@
+2011-07-21  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/49770
+       * tree-ssa-sccvn.c (valueize_refs_1): Return whether we
+       valueized any operand.  Renamed from ...
+       (valueize_refs): ... this.  New wrapper around valueize_refs_1.
+       (valueize_shared_reference_ops_from_ref): Return whether we
+       valueized any operand.
+       (vn_reference_lookup): Only when we valueized any operand
+       use the valueized reference for alias analysis.  Do not preserve
+       the original reference tree in this case.
+
 2011-07-21  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.c (ix86_decompose_address): Reject all but
index 05ad509b33a3e6525fc5c7b9dff820d047978b5c..334730cc80abb8d2ec89a76166ce3005dbffe5d6 100644 (file)
@@ -1,3 +1,8 @@
+2011-07-21  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/49770
+       * g++.dg/torture/pr49770.C: New testcase.
+
 2011-07-21  Kai Tietz  <ktietz@redhat.com>
 
        * gcc.dg/tree-ssa/pr30978.c: adjusted.
diff --git a/gcc/testsuite/g++.dg/torture/pr49770.C b/gcc/testsuite/g++.dg/torture/pr49770.C
new file mode 100644 (file)
index 0000000..7eac9e0
--- /dev/null
@@ -0,0 +1,86 @@
+/* { dg-do run } */
+/* { dg-options "-std=c++0x -fno-tree-forwprop" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+template < typename > struct remove_reference;
+template < typename _Tp > struct remove_reference <_Tp & >
+{
+  typedef _Tp type;
+};
+template < typename _Tp > typename remove_reference < _Tp >::type &&
+move (_Tp && __t)
+{
+  return static_cast < typename remove_reference < _Tp >::type && >(__t);
+}
+
+template < typename _Tp > void
+stdswap (_Tp & __a, _Tp & __b)
+{
+  _Tp __tmp (__a);
+  __a = (__b);
+  __b = (__tmp);
+}
+
+struct _Deque_iterator
+{
+  int *_M_cur;
+  int *_M_first;
+  int *_M_last;
+  int **_M_node;
+};
+
+static inline int operatorMIN (_Deque_iterator & __x, _Deque_iterator & __y)
+{
+  return sizeof (int) * (__x._M_node - __y._M_node - 1)
+    + (__x._M_cur - __x._M_first) + (__y._M_last - __y._M_cur);
+}
+
+struct deque
+{
+  deque & operator = (deque && __x)
+  {
+    stdswap (_M_finish, __x._M_finish);
+    return *this;
+  }
+  size_t size ()
+  {
+    return operatorMIN (_M_finish, _M_start);
+  }
+
+deque ():
+  _M_map (), _M_map_size (), _M_start (), _M_finish ()
+  {
+    _M_start._M_last = _M_start._M_first + sizeof (int);
+  }
+
+  int **_M_map;
+  size_t _M_map_size;
+  _Deque_iterator _M_start;
+  _Deque_iterator _M_finish;
+};
+
+struct queue
+{
+  deque c;
+  size_t size ()
+  {
+    return c.size ();
+  }
+};
+
+void
+test01 ()
+{
+  queue a, b;
+  ++a.c._M_finish._M_cur;
+  b = move (a);
+  if (!b.size ())
+    __builtin_abort ();
+}
+
+main ()
+{
+  test01 ();
+}
+
index 125d0444f4a72f523d95beb37b3e63213a4db938..5f72f041290179524c473088280623ed7585554c 100644 (file)
@@ -1146,29 +1146,51 @@ fully_constant_vn_reference_p (vn_reference_t ref)
 
 /* Transform any SSA_NAME's in a vector of vn_reference_op_s
    structures into their value numbers.  This is done in-place, and
-   the vector passed in is returned.  */
+   the vector passed in is returned.  *VALUEIZED_ANYTHING will specify
+   whether any operands were valueized.  */
 
 static VEC (vn_reference_op_s, heap) *
-valueize_refs (VEC (vn_reference_op_s, heap) *orig)
+valueize_refs_1 (VEC (vn_reference_op_s, heap) *orig, bool *valueized_anything)
 {
   vn_reference_op_t vro;
   unsigned int i;
 
+  *valueized_anything = false;
+
   FOR_EACH_VEC_ELT (vn_reference_op_s, orig, i, vro)
     {
       if (vro->opcode == SSA_NAME
          || (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME))
        {
-         vro->op0 = SSA_VAL (vro->op0);
+         tree tem = SSA_VAL (vro->op0);
+         if (tem != vro->op0)
+           {
+             *valueized_anything = true;
+             vro->op0 = tem;
+           }
          /* If it transforms from an SSA_NAME to a constant, update
             the opcode.  */
          if (TREE_CODE (vro->op0) != SSA_NAME && vro->opcode == SSA_NAME)
            vro->opcode = TREE_CODE (vro->op0);
        }
       if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
-       vro->op1 = SSA_VAL (vro->op1);
+       {
+         tree tem = SSA_VAL (vro->op1);
+         if (tem != vro->op1)
+           {
+             *valueized_anything = true;
+             vro->op1 = tem;
+           }
+       }
       if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
-       vro->op2 = SSA_VAL (vro->op2);
+       {
+         tree tem = SSA_VAL (vro->op2);
+         if (tem != vro->op2)
+           {
+             *valueized_anything = true;
+             vro->op2 = tem;
+           }
+       }
       /* If it transforms from an SSA_NAME to an address, fold with
         a preceding indirect reference.  */
       if (i > 0
@@ -1203,20 +1225,29 @@ valueize_refs (VEC (vn_reference_op_s, heap) *orig)
   return orig;
 }
 
+static VEC (vn_reference_op_s, heap) *
+valueize_refs (VEC (vn_reference_op_s, heap) *orig)
+{
+  bool tem;
+  return valueize_refs_1 (orig, &tem);
+}
+
 static VEC(vn_reference_op_s, heap) *shared_lookup_references;
 
 /* Create a vector of vn_reference_op_s structures from REF, a
    REFERENCE_CLASS_P tree.  The vector is shared among all callers of
-   this function.  */
+   this function.  *VALUEIZED_ANYTHING will specify whether any
+   operands were valueized.  */
 
 static VEC(vn_reference_op_s, heap) *
-valueize_shared_reference_ops_from_ref (tree ref)
+valueize_shared_reference_ops_from_ref (tree ref, bool *valueized_anything)
 {
   if (!ref)
     return NULL;
   VEC_truncate (vn_reference_op_s, shared_lookup_references, 0);
   copy_reference_ops_from_ref (ref, &shared_lookup_references);
-  shared_lookup_references = valueize_refs (shared_lookup_references);
+  shared_lookup_references = valueize_refs_1 (shared_lookup_references,
+                                             valueized_anything);
   return shared_lookup_references;
 }
 
@@ -1694,12 +1725,14 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
   VEC (vn_reference_op_s, heap) *operands;
   struct vn_reference_s vr1;
   tree cst;
+  bool valuezied_anything;
 
   if (vnresult)
     *vnresult = NULL;
 
   vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
-  vr1.operands = operands = valueize_shared_reference_ops_from_ref (op);
+  vr1.operands = operands
+    = valueize_shared_reference_ops_from_ref (op, &valuezied_anything);
   vr1.type = TREE_TYPE (op);
   vr1.set = get_alias_set (op);
   vr1.hashcode = vn_reference_compute_hash (&vr1);
@@ -1711,12 +1744,12 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
     {
       vn_reference_t wvnresult;
       ao_ref r;
-      /* Make sure to use a valueized reference ...  */
-      if (!ao_ref_init_from_vn_reference (&r, vr1.set, vr1.type, vr1.operands))
+      /* Make sure to use a valueized reference if we valueized anything.
+         Otherwise preserve the full reference for advanced TBAA.  */
+      if (!valuezied_anything
+         || !ao_ref_init_from_vn_reference (&r, vr1.set, vr1.type,
+                                            vr1.operands))
        ao_ref_init (&r, op);
-      else
-       /* ... but also preserve a full reference tree for advanced TBAA.  */
-       r.ref = op;
       vn_walk_kind = kind;
       wvnresult =
        (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,