200-gcc-pr52734.patch 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. Index: gcc/tree-ssa-tail-merge.c
  2. ===================================================================
  3. --- a/gcc/tree-ssa-tail-merge.c (revision 185028)
  4. +++ b/gcc/tree-ssa-tail-merge.c (working copy)
  5. @@ -1123,18 +1123,31 @@ gimple_equal_p (same_succ same_succ, gim
  6. }
  7. }
  8. -/* Let GSI skip backwards over local defs. */
  9. +/* Let GSI skip backwards over local defs. Return the earliest vuse in VUSE.
  10. + Return true in VUSE_ESCAPED if the vuse influenced a SSA_OP_DEF of one of the
  11. + processed statements. */
  12. static void
  13. -gsi_advance_bw_nondebug_nonlocal (gimple_stmt_iterator *gsi)
  14. +gsi_advance_bw_nondebug_nonlocal (gimple_stmt_iterator *gsi, tree *vuse,
  15. + bool *vuse_escaped)
  16. {
  17. gimple stmt;
  18. + tree lvuse;
  19. while (true)
  20. {
  21. if (gsi_end_p (*gsi))
  22. return;
  23. stmt = gsi_stmt (*gsi);
  24. +
  25. + lvuse = gimple_vuse (stmt);
  26. + if (lvuse != NULL_TREE)
  27. + {
  28. + *vuse = lvuse;
  29. + if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_DEF))
  30. + *vuse_escaped = true;
  31. + }
  32. +
  33. if (!(is_gimple_assign (stmt) && local_def (gimple_get_lhs (stmt))
  34. && !gimple_has_side_effects (stmt)))
  35. return;
  36. @@ -1150,9 +1163,11 @@ find_duplicate (same_succ same_succ, bas
  37. {
  38. gimple_stmt_iterator gsi1 = gsi_last_nondebug_bb (bb1);
  39. gimple_stmt_iterator gsi2 = gsi_last_nondebug_bb (bb2);
  40. + tree vuse1 = NULL_TREE, vuse2 = NULL_TREE;
  41. + bool vuse_escaped = false;
  42. - gsi_advance_bw_nondebug_nonlocal (&gsi1);
  43. - gsi_advance_bw_nondebug_nonlocal (&gsi2);
  44. + gsi_advance_bw_nondebug_nonlocal (&gsi1, &vuse1, &vuse_escaped);
  45. + gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2, &vuse_escaped);
  46. while (!gsi_end_p (gsi1) && !gsi_end_p (gsi2))
  47. {
  48. @@ -1161,13 +1176,20 @@ find_duplicate (same_succ same_succ, bas
  49. gsi_prev_nondebug (&gsi1);
  50. gsi_prev_nondebug (&gsi2);
  51. - gsi_advance_bw_nondebug_nonlocal (&gsi1);
  52. - gsi_advance_bw_nondebug_nonlocal (&gsi2);
  53. + gsi_advance_bw_nondebug_nonlocal (&gsi1, &vuse1, &vuse_escaped);
  54. + gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2, &vuse_escaped);
  55. }
  56. if (!(gsi_end_p (gsi1) && gsi_end_p (gsi2)))
  57. return;
  58. + /* If the incoming vuses are not the same, and the vuse escaped into an
  59. + SSA_OP_DEF, then merging the 2 blocks will change the value of the def,
  60. + which potentially means the semantics of one of the blocks will be changed.
  61. + TODO: make this check more precise. */
  62. + if (vuse_escaped && vuse1 != vuse2)
  63. + return;
  64. +
  65. if (dump_file)
  66. fprintf (dump_file, "find_duplicates: <bb %d> duplicate of <bb %d>\n",
  67. bb1->index, bb2->index);
  68. Index: gcc/testsuite/gcc.dg/pr52734.c
  69. ===================================================================
  70. --- a/dev/null (new file)
  71. +++ b/gcc/testsuite/gcc.dg/pr52734.c (revision 0)
  72. @@ -0,0 +1,35 @@
  73. +/* { dg-do run } */
  74. +/* { dg-options "-O2" } */
  75. +
  76. +int bbb = 0;
  77. +
  78. +int __attribute__((noinline,noclone)) aaa(void)
  79. +{
  80. + ++bbb;
  81. + return 0;
  82. +}
  83. +
  84. +int __attribute__((noinline,noclone)) ccc(void)
  85. +{
  86. + int ddd;
  87. + /* bbb == 0 */
  88. + if (aaa())
  89. + return bbb;
  90. +
  91. + /* bbb == 1 */
  92. + ddd = bbb;
  93. + /* bbb == ddd == 1 */
  94. + if (aaa ())
  95. + return 0;
  96. + /* bbb == 2, ddd == 1 */
  97. +
  98. + return ddd;
  99. +}
  100. +
  101. +int main(void)
  102. +{
  103. + if (ccc() != 1)
  104. + __builtin_abort();
  105. + return 0;
  106. +}
  107. +