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 index 00000000000..508ed853c29 --- /dev/null +++ b/toolchain/gcc/patches/4.7.0/000-upstream_uclibc_fix.patch @@ -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: duplicate of \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; ++} ++