toolchain/gcc: gcc-4.7.0 upstream patch fixing uClibc problems
authorJo-Philipp Wich <jow@openwrt.org>
Thu, 12 Apr 2012 07:48:02 +0000 (07:48 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Thu, 12 Apr 2012 07:48:02 +0000 (07:48 +0000)
SVN-Revision: 31255

toolchain/gcc/patches/4.7.0/000-upstream_uclibc_fix.patch [new file with mode: 0644]

diff --git a/toolchain/gcc/patches/4.7.0/000-upstream_uclibc_fix.patch b/toolchain/gcc/patches/4.7.0/000-upstream_uclibc_fix.patch
new file mode 100644 (file)
index 0000000..508ed85
--- /dev/null
@@ -0,0 +1,241 @@
+--- a/gcc/tree-ssa-tail-merge.c (revision 185028)
++++ b/gcc/tree-ssa-tail-merge.c (working copy)
+@@ -1033,7 +1033,7 @@ set_cluster (basic_block bb1, basic_bloc
+    gimple_bb (s2) are members of SAME_SUCC.  */
+ static bool
+-gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
++gimple_equal_p (same_succ same_succ, gimple s1, gimple s2, bool *gvn_used)
+ {
+   unsigned int i;
+   tree lhs1, lhs2;
+@@ -1069,7 +1069,10 @@ gimple_equal_p (same_succ same_succ, gim
+         if (operand_equal_p (t1, t2, 0))
+           continue;
+         if (gvn_uses_equal (t1, t2))
+-          continue;
++          {
++            *gvn_used = true;
++            continue;
++          }
+         equal = false;
+         break;
+       }
+@@ -1083,12 +1086,16 @@ gimple_equal_p (same_succ same_succ, gim
+       if (lhs1 == NULL_TREE || lhs2 == NULL_TREE)
+       return false;
+       if (TREE_CODE (lhs1) == SSA_NAME && TREE_CODE (lhs2) == SSA_NAME)
+-      return vn_valueize (lhs1) == vn_valueize (lhs2);
++      {
++        *gvn_used = true;
++        return vn_valueize (lhs1) == vn_valueize (lhs2);
++      }
+       return operand_equal_p (lhs1, lhs2, 0);
+     case GIMPLE_ASSIGN:
+       lhs1 = gimple_get_lhs (s1);
+       lhs2 = gimple_get_lhs (s2);
++      *gvn_used = true;
+       return (TREE_CODE (lhs1) == SSA_NAME
+             && TREE_CODE (lhs2) == SSA_NAME
+             && vn_valueize (lhs1) == vn_valueize (lhs2));
+@@ -1096,15 +1103,23 @@ gimple_equal_p (same_succ same_succ, gim
+     case GIMPLE_COND:
+       t1 = gimple_cond_lhs (s1);
+       t2 = gimple_cond_lhs (s2);
+-      if (!operand_equal_p (t1, t2, 0)
+-        && !gvn_uses_equal (t1, t2))
+-      return false;
++      if (!operand_equal_p (t1, t2, 0))
++      {
++        if (gvn_uses_equal (t1, t2))
++          *gvn_used = true;
++        else
++          return false;
++      }
+       t1 = gimple_cond_rhs (s1);
+       t2 = gimple_cond_rhs (s2);
+-      if (!operand_equal_p (t1, t2, 0)
+-        && !gvn_uses_equal (t1, t2))
+-      return false;
++      if (!operand_equal_p (t1, t2, 0))
++      {
++        if (gvn_uses_equal (t1, t2))
++          *gvn_used = true;
++        else
++          return false;
++      }
+       code1 = gimple_expr_code (s1);
+       code2 = gimple_expr_code (s2);
+@@ -1126,18 +1141,25 @@ gimple_equal_p (same_succ same_succ, gim
+ /* Let GSI skip backwards over local defs.  */
+ static void
+-gsi_advance_bw_nondebug_nonlocal (gimple_stmt_iterator *gsi)
++gsi_advance_bw_nondebug_nonlocal (gimple_stmt_iterator *gsi, tree *vuse)
+ {
+   gimple stmt;
++  tree lvuse;
+   while (true)
+     {
+       if (gsi_end_p (*gsi))
+       return;
+       stmt = gsi_stmt (*gsi);
++
++      lvuse = gimple_vuse (stmt);
++      if (lvuse != NULL_TREE)
++      *vuse = lvuse;
++
+       if (!(is_gimple_assign (stmt) && local_def (gimple_get_lhs (stmt))
+           && !gimple_has_side_effects (stmt)))
+       return;
++
+       gsi_prev_nondebug (gsi);
+     }
+ }
+@@ -1146,28 +1168,34 @@ gsi_advance_bw_nondebug_nonlocal (gimple
+    clusters them.  */
+ static void
+-find_duplicate (same_succ same_succ, basic_block bb1, basic_block bb2)
++find_duplicate (same_succ same_succ, basic_block bb1, basic_block bb2,
++              bool gvn_used)
+ {
+   gimple_stmt_iterator gsi1 = gsi_last_nondebug_bb (bb1);
+   gimple_stmt_iterator gsi2 = gsi_last_nondebug_bb (bb2);
++  tree vuse1 = NULL_TREE, vuse2 = NULL_TREE;
+-  gsi_advance_bw_nondebug_nonlocal (&gsi1);
+-  gsi_advance_bw_nondebug_nonlocal (&gsi2);
++  gsi_advance_bw_nondebug_nonlocal (&gsi1, &vuse1);
++  gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2);
+   while (!gsi_end_p (gsi1) && !gsi_end_p (gsi2))
+     {
+-      if (!gimple_equal_p (same_succ, gsi_stmt (gsi1), gsi_stmt (gsi2)))
++      if (!gimple_equal_p (same_succ, gsi_stmt (gsi1), gsi_stmt (gsi2),
++                         &gvn_used))
+       return;
+       gsi_prev_nondebug (&gsi1);
+       gsi_prev_nondebug (&gsi2);
+-      gsi_advance_bw_nondebug_nonlocal (&gsi1);
+-      gsi_advance_bw_nondebug_nonlocal (&gsi2);
++      gsi_advance_bw_nondebug_nonlocal (&gsi1, &vuse1);
++      gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2);
+     }
+   if (!(gsi_end_p (gsi1) && gsi_end_p (gsi2)))
+     return;
++  if (gvn_used && vuse1 != vuse2)
++    return;
++
+   if (dump_file)
+     fprintf (dump_file, "find_duplicates: <bb %d> duplicate of <bb %d>\n",
+            bb1->index, bb2->index);
+@@ -1179,7 +1207,7 @@ find_duplicate (same_succ same_succ, bas
+    E2 are equal.  */
+ static bool
+-same_phi_alternatives_1 (basic_block dest, edge e1, edge e2)
++same_phi_alternatives_1 (basic_block dest, edge e1, edge e2, bool *gvn_used)
+ {
+   int n1 = e1->dest_idx, n2 = e2->dest_idx;
+   gimple_stmt_iterator gsi;
+@@ -1197,7 +1225,10 @@ same_phi_alternatives_1 (basic_block des
+       if (operand_equal_for_phi_arg_p (val1, val2))
+         continue;
+       if (gvn_uses_equal (val1, val2))
+-      continue;
++      {
++        *gvn_used = true;
++        continue;
++      }
+       return false;
+     }
+@@ -1209,7 +1240,8 @@ same_phi_alternatives_1 (basic_block des
+    phi alternatives for BB1 and BB2 are equal.  */
+ static bool
+-same_phi_alternatives (same_succ same_succ, basic_block bb1, basic_block bb2)
++same_phi_alternatives (same_succ same_succ, basic_block bb1, basic_block bb2,
++                     bool *gvn_used)
+ {
+   unsigned int s;
+   bitmap_iterator bs;
+@@ -1227,7 +1259,7 @@ same_phi_alternatives (same_succ same_su
+       /* For all phis in bb, the phi alternatives for e1 and e2 need to have
+        the same value.  */
+-      if (!same_phi_alternatives_1 (succ, e1, e2))
++      if (!same_phi_alternatives_1 (succ, e1, e2, gvn_used))
+       return false;
+     }
+@@ -1301,6 +1333,7 @@ find_clusters_1 (same_succ same_succ)
+   bitmap_iterator bi, bj;
+   int nr_comparisons;
+   int max_comparisons = PARAM_VALUE (PARAM_MAX_TAIL_MERGE_COMPARISONS);
++  bool gvn_used;
+   EXECUTE_IF_SET_IN_BITMAP (same_succ->bbs, 0, i, bi)
+     {
+@@ -1333,10 +1366,11 @@ find_clusters_1 (same_succ same_succ)
+         if (!deps_ok_for_redirect (bb1, bb2))
+           continue;
+-        if (!(same_phi_alternatives (same_succ, bb1, bb2)))
++        gvn_used = false;
++        if (!(same_phi_alternatives (same_succ, bb1, bb2, &gvn_used)))
+           continue;
+-        find_duplicate (same_succ, bb1, bb2);
++        find_duplicate (same_succ, bb1, bb2, gvn_used);
+         }
+     }
+ }
+Index: gcc/testsuite/gcc.dg/pr52734.c
+===================================================================
+--- /dev/null (new file)
++++ gcc/testsuite/gcc.dg/pr52734.c (revision 0)
+@@ -0,0 +1,35 @@
++/* { dg-do run } */
++/* { dg-options "-O2" } */
++
++int bbb = 0;
++
++int __attribute__((noinline,noclone)) aaa(void)
++{
++    ++bbb;
++    return 0;
++}
++
++int __attribute__((noinline,noclone)) ccc(void)
++{
++  int ddd;
++  /* bbb == 0 */
++  if (aaa())
++    return bbb;
++
++  /* bbb == 1 */
++  ddd = bbb;
++  /* bbb == ddd == 1 */
++  if (aaa ())
++    return 0;
++  /* bbb == 2, ddd == 1 */
++
++  return ddd;
++}
++
++int main(void)
++{
++    if (ccc() != 1)
++      __builtin_abort();
++    return 0;
++}
++