This fixes pr88797 by avoiding path splitting when we've got a
candidate, but the PHI feeds a conditional in the join block.  ie:

  # iftmp.0_11 = PHI <1111(3), 1112(4)>
[ ... ]
  _14 = iftmp.0_11 > x_17;


These are more likely going to be if-conversion candidates and
if-conversion is generally more profitable than path splitting.

This doesn't feel terribly important to fix for gcc-9, so I'm just
installing on the trunk.  But backporting would be trivial and safe if
someone feels it's important enough to do so.

This has been bootstrapped and regression tested on a variety of native
targets, it's also been tested to a lesser degree on the various *-elf
targets.

Installing on the trunk momentarily.

jeff
        * gimple-ssa-split-paths (is_feasible_trace): Reject cases where the
        PHI feeds a conditional on the RHS of an assignment.

        * g++.dg/tree-ssa/pr88797.C: New test.

diff --git a/gcc/gimple-ssa-split-paths.c b/gcc/gimple-ssa-split-paths.c
index 33bbb66674b..5bf45eeac28 100644
--- a/gcc/gimple-ssa-split-paths.c
+++ b/gcc/gimple-ssa-split-paths.c
@@ -264,8 +264,12 @@ is_feasible_trace (basic_block bb)
          if (is_gimple_debug (stmt))
            continue;
          /* If there's a use in the joiner this might be a CSE/DCE
-            opportunity.  */
-         if (gimple_bb (stmt) == bb)
+            opportunity, but not if the use is in a conditional
+            which makes this a likely if-conversion candidate.  */
+         if (gimple_bb (stmt) == bb
+             && (!is_gimple_assign (stmt)
+                 || (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
+                     != tcc_comparison)))
            {
              found_useful_phi = true;
              break;
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr88797.C 
b/gcc/testsuite/g++.dg/tree-ssa/pr88797.C
new file mode 100644
index 00000000000..75391d6c049
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr88797.C
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-split-paths-details" } */
+
+
+void use(unsigned);
+bool f(unsigned x, unsigned y) {
+    return x < 1111 + (y <= 2222);
+}
+void test_f(unsigned x, unsigned y) {
+    for (unsigned i = 0; i < 3333; ++i)
+        use(f(x++, y++));
+}
+
+/* { dg-final { scan-tree-dump-not "Duplicating join block" "split-paths" } } 
*/
+/* { dg-final { scan-tree-dump-times "Block . is a join that does not expose" 
1 "split-paths" } } */
+

Reply via email to