On 10/07/2026 11:42, Kyrylo Tkachov wrote:


On 9 Jul 2026, at 14:36, Kyrylo Tkachov <[email protected]> wrote:

Hi Alfie,

On 9 Jul 2026, at 10:24, Alfie Richards <[email protected]> wrote:

On 06/07/2026 09:40, Kyrylo Tkachov wrote:
On 3 Jul 2026, at 13:56, Kyrylo Tkachov <[email protected]> wrote:



On 2 Jul 2026, at 10:56, Richard Biener <[email protected]> wrote:

On Thu, 2 Jul 2026, [email protected] wrote:

From: Kyrylo Tkachov <[email protected]>

pass_split_paths duplicates the join block of an IF-THEN-ELSE that feeds a
loop latch, splitting the two paths to the backedge.  It runs only at -O3.
In practice it interacts badly with later optimizations: it duplicates the
loop body before loads have been commoned and before if-conversion runs, so
it can block both loop unrolling (PR120892) and if-conversion of the
duplicated diamond, while its own heuristic already declines about half of
all candidate blocks, most often to avoid spoiling if-conversion.

Remove the pass and deprecate the -fsplit-paths option.  The option is kept
accepted for backward compatibility via the Ignore flag and now does nothing,
matching how other optimization options have been retired (for example
-ftree-lrs).  param_max_jump_thread_duplication_stmts is retained as it is
shared with the jump-threading passes.

Statistics from the pass on SPEC CPU 2026 (intrate + fprate, counted from the
split-paths dump):

                  candidates   splits   declined   to protect if-conversion
-O3                  122894    62050     60844           37166
-O3 -flto=auto        52423    21257     31166           21822

The pass splits about half of the blocks it considers and declines the rest,
most often to avoid spoiling if-conversion.  The duplication grows .text by
0.32% at -O3 and 0.24% at -O3 -flto=auto.

Andrea and Jeff indicated in PR120892 that removing -fsplit-paths may be
the way to go there.

-fsplit-paths also complicates the control-flow and defeats the
load-commoning necessary to get good if-conversion of the hot loop from
Snappy from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125557#c13 .

Bootstrapped and tested on aarch64-none-linux-gnu and x86_64-linux.

OK.

Please leave others a day or so to chime in.

Thanks, I’ll push next wee once the USA have had their holidays.
Kyrill
Pushed now as g:5c23bb074af23f00dd3fe1745b9dd99245fa4bba
Hi,

Just to note we see about a 3% regression on spec2006.intrate.462.libquantum 
from this change on Neoverse-V1.

I’m having a look. I don’t have access to a Neoverse V1 but I’ll try to 
reproduce it on the machines that I have access to and see if I can raise a GCC 
PR to record whatever missed optimisation this may be exposing so that we can 
decide if we want to implement it in some other way.


So I did reproduce the slowdown, but it looks like an unfortunate code 
alignment change. libquantum has some very hot paths but the split paths pass 
only triggered on cold paths/functions, but due to code layout the hot BBs got 
a different suboptimal alignment that caused the overall slowdown. So I don’t 
think we have anything split-paths-related to do here.
Alignment for big AArch64 CPUs is something that has given me headaches 
recently and I think we should be looking at things like stricter alignment on 
small hot loops and better function alignment for hot functions (ignoring skip 
in those cases), but those are separate discussions.
Thanks,
Kyrill
Hi Kyrill,

Our analysis showed a larger code generation difference.

Speicifcally in quantum_toffoli near the end of the loop we see the following change:

NEW:

//.L1
        cmp     w2, w1  
        b.le    404a40 <quantum_toffoli+0x174> // Out of loop

//.L2
        ldr     x0, [x19, #16]
        add     x0, x0, w1, uxtw #4
        add     x1, x1, #0x1
        ldr     x3, [x0, #8]
        bics    xzr, x5, x3
        b.ne    404a0c <quantum_toffoli+0x140>  // b.any // .L1
//.L3
        eor     x3, x4, x3
        str     x3, [x0, #8]
        ldr     w2, [x19, #4]
        cmp     w2, w1  b.gt    404a14 <quantum_toffoli+0x148> // .L2



OLD:

//.L1
        add     x3, x5, w0, uxtw #4
        ldr     x1, [x3, #8]
        bics    xzr, x19, x1
        b.eq    404a9c <quantum_toffoli+0x17c>  // b.none // Out of loop
//.L2
        add     x0, x0, #0x1
        cmp     w2, w0
        b.gt    404a68 <quantum_toffoli+0x148> // .L1

(Roughly, comments are my own)

We think this is the primary change causing this regression due to the extra load in the loop?

(credit to Tamar for most of the analysis here)

KR,
Alfie


Thanks,
Kyrill


Thanks,
Alfie


Thanks,
Richard.

gcc/ChangeLog:

PR tree-optimization/120892
* gimple-ssa-split-paths.cc: Remove.
* passes.def (pass_split_paths): Remove.
* tree-pass.h (make_pass_split_paths): Remove.
* Makefile.in (OBJS): Remove gimple-ssa-split-paths.o.
* timevar.def (TV_SPLIT_PATHS): Remove.
* opts.cc (default_options_table): Remove the OPT_LEVELS_3_PLUS entry
for OPT_fsplit_paths.
* common.opt (fsplit-paths): Make it a deprecated no-op using Ignore.
* doc/invoke.texi (-fsplit-paths): Document as deprecated and remove it
from the option summary and the -O3 list.

gcc/testsuite/ChangeLog:

PR tree-optimization/120892
* gcc.dg/tree-ssa/split-path-1.c: Move to...
* gcc.c-torture/execute/split-path-1.c: ...here.  Adjust to a plain
compile and run test without the split-paths dump scan.
* gcc.dg/tree-ssa/split-path-2.c: Move to...
* gcc.c-torture/compile/split-path-2.c: ...here.  Adjust to a
compile-only test without the split-paths dump scan.
* gcc.dg/tree-ssa/split-path-3.c: Move to...
* gcc.c-torture/compile/split-path-3.c: ...here.  Likewise.
* gcc.dg/tree-ssa/split-path-4.c: Move to...
* gcc.c-torture/compile/split-path-4.c: ...here.  Likewise.
* gcc.dg/tree-ssa/split-path-5.c: Move to...
* gcc.c-torture/compile/split-path-5.c: ...here.  Likewise.
* gcc.dg/tree-ssa/split-path-6.c: Move to...
* gcc.c-torture/compile/split-path-6.c: ...here.  Likewise.
* gcc.dg/tree-ssa/split-path-7.c: Move to...
* gcc.c-torture/compile/split-path-7.c: ...here.  Likewise.
* gcc.dg/tree-ssa/split-path-8.c: Move to...
* gcc.c-torture/compile/split-path-8.c: ...here.  Likewise.
* gcc.dg/tree-ssa/split-path-9.c: Move to...
* gcc.c-torture/compile/split-path-9.c: ...here.  Likewise.
* gcc.dg/tree-ssa/split-path-10.c: Move to...
* gcc.c-torture/compile/split-path-10.c: ...here.  Likewise.
* gcc.dg/tree-ssa/split-path-11.c: Move to...
* gcc.c-torture/compile/split-path-11.c: ...here.  Likewise.
* gcc.dg/tree-ssa/split-path-12.c: Move to...
* gcc.c-torture/compile/split-path-12.c: ...here.  Likewise.
* gcc.dg/tree-ssa/split-path-13.c: Move to...
* gcc.c-torture/compile/split-path-13.c: ...here.  Likewise.
* gcc.dg/tree-ssa/pr69270.c: Move to...
* gcc.c-torture/compile/pr69270.c: ...here.  Likewise.
* g++.dg/tree-ssa/pr88797.C: Move to...
* g++.dg/torture/pr88797.C: ...here.  Adjust to a compile-only test.
* gcc.target/i386/pr106450.c: Remove -fsplit-paths from dg-options.

Signed-off-by: Kyrylo Tkachov <[email protected]>
---
gcc/Makefile.in                               |   1 -
gcc/common.opt                                |   4 +-
gcc/doc/invoke.texi                           |   8 +-
gcc/gimple-ssa-split-paths.cc                 | 545 ------------------
gcc/opts.cc                                   |   1 -
gcc/passes.def                                |   1 -
gcc/testsuite/g++.dg/torture/pr88797.C        |  13 +
gcc/testsuite/g++.dg/tree-ssa/pr88797.C       |  16 -
.../compile}/pr69270.c                        |   7 -
.../compile}/split-path-10.c                  |   3 -
.../compile}/split-path-11.c                  |   3 -
.../compile}/split-path-12.c                  |   3 -
.../compile}/split-path-13.c                  |   3 -
.../gcc.c-torture/compile/split-path-2.c      |  18 +
.../compile}/split-path-3.c                   |   3 -
.../compile}/split-path-4.c                   |   3 -
.../compile}/split-path-5.c                   |   3 -
.../compile}/split-path-6.c                   |   3 -
.../compile}/split-path-7.c                   |   3 -
.../gcc.c-torture/compile/split-path-8.c      |  11 +
.../gcc.c-torture/compile/split-path-9.c      |  14 +
.../execute}/split-path-1.c                   |   3 -
gcc/testsuite/gcc.dg/tree-ssa/split-path-2.c  |  21 -
gcc/testsuite/gcc.dg/tree-ssa/split-path-8.c  |  14 -
gcc/testsuite/gcc.dg/tree-ssa/split-path-9.c  |  17 -
gcc/testsuite/gcc.target/i386/pr106450.c      |   2 +-
gcc/timevar.def                               |   1 -
gcc/tree-pass.h                               |   1 -
28 files changed, 62 insertions(+), 663 deletions(-)
delete mode 100644 gcc/gimple-ssa-split-paths.cc
create mode 100644 gcc/testsuite/g++.dg/torture/pr88797.C
delete mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr88797.C
rename gcc/testsuite/{gcc.dg/tree-ssa => gcc.c-torture/compile}/pr69270.c (57%)
rename gcc/testsuite/{gcc.dg/tree-ssa => gcc.c-torture/compile}/split-path-10.c 
(81%)
rename gcc/testsuite/{gcc.dg/tree-ssa => gcc.c-torture/compile}/split-path-11.c 
(55%)
rename gcc/testsuite/{gcc.dg/tree-ssa => gcc.c-torture/compile}/split-path-12.c 
(70%)
rename gcc/testsuite/{gcc.dg/tree-ssa => gcc.c-torture/compile}/split-path-13.c 
(62%)
create mode 100644 gcc/testsuite/gcc.c-torture/compile/split-path-2.c
rename gcc/testsuite/{gcc.dg/tree-ssa => gcc.c-torture/compile}/split-path-3.c 
(93%)
rename gcc/testsuite/{gcc.dg/tree-ssa => gcc.c-torture/compile}/split-path-4.c 
(62%)
rename gcc/testsuite/{gcc.dg/tree-ssa => gcc.c-torture/compile}/split-path-5.c 
(84%)
rename gcc/testsuite/{gcc.dg/tree-ssa => gcc.c-torture/compile}/split-path-6.c 
(82%)
rename gcc/testsuite/{gcc.dg/tree-ssa => gcc.c-torture/compile}/split-path-7.c 
(87%)
create mode 100644 gcc/testsuite/gcc.c-torture/compile/split-path-8.c
create mode 100644 gcc/testsuite/gcc.c-torture/compile/split-path-9.c
rename gcc/testsuite/{gcc.dg/tree-ssa => gcc.c-torture/execute}/split-path-1.c 
(83%)
delete mode 100644 gcc/testsuite/gcc.dg/tree-ssa/split-path-2.c
delete mode 100644 gcc/testsuite/gcc.dg/tree-ssa/split-path-8.c
delete mode 100644 gcc/testsuite/gcc.dg/tree-ssa/split-path-9.c

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 536e2faaaf8..06e711094ef 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1542,7 +1542,6 @@ OBJS = \
gimple-ssa-isolate-paths.o \
gimple-ssa-nonnull-compare.o \
gimple-ssa-sccopy.o \
- gimple-ssa-split-paths.o \
gimple-ssa-store-merging.o \
gimple-ssa-strength-reduction.o \
gimple-ssa-sprintf.o \
diff --git a/gcc/common.opt b/gcc/common.opt
index 218dddf5dfe..0055578ccf6 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -3388,8 +3388,8 @@ Common Var(flag_tree_vrp) Init(0) Optimization
Perform Value Range Propagation on trees.

fsplit-paths
-Common Var(flag_split_paths) Init(0) Optimization
-Split paths leading to loop backedges.
+Common Ignore
+Does nothing.  Preserved for backward compatibility.

funconstrained-commons
Common Var(flag_unconstrained_commons) Optimization
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 8da5f03ccbd..932def96d8f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -676,7 +676,7 @@ Objective-C and Objective-C++ Dialects}.
-fsemantic-interposition  -fshrink-wrap  -fshrink-wrap-separate
-fsignaling-nans
-fsingle-precision-constant  -fsplit-ivs-in-unroller  -fsplit-loops
--fspeculatively-call-stored-functions  -fsplit-paths
+-fspeculatively-call-stored-functions
-fsplit-wide-types  -fsplit-wide-types-early  -fssa-backprop  -fssa-phiopt
-fstdarg-opt  -fstore-merging  -fstrict-aliasing -fipa-strict-aliasing
-fthread-jumps  -ftracer  -ftree-bit-ccp
@@ -13619,7 +13619,6 @@ by @option{-O2} and also turns on the following 
optimization flags:
-fpeel-loops
-fpredictive-commoning
-fsplit-loops
--fsplit-paths
-ftree-loop-distribution
-ftree-partial-pre
-funswitch-loops
@@ -15462,9 +15461,8 @@ enabled.
@opindex fsplit-paths
@opindex fno-split-paths
@item -fsplit-paths
-Split paths leading to loop backedges.  This can improve dead code
-elimination and common subexpression elimination.  This is enabled by
-default at @option{-O3} and above.
+This option is deprecated and does nothing.  It is accepted only for
+backward compatibility.

@opindex fsplit-ivs-in-unroller
@opindex fno-split-ivs-in-unroller
diff --git a/gcc/gimple-ssa-split-paths.cc b/gcc/gimple-ssa-split-paths.cc
deleted file mode 100644
index 171a581e8f8..00000000000
--- a/gcc/gimple-ssa-split-paths.cc
+++ /dev/null
@@ -1,545 +0,0 @@
-/* Support routines for Splitting Paths to loop backedges
-   Copyright (C) 2015-2026 Free Software Foundation, Inc.
-   Contributed by Ajit Kumar Agarwal <[email protected]>.
-
- This file is part of GCC.
-
- GCC is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "backend.h"
-#include "tree.h"
-#include "gimple.h"
-#include "tree-pass.h"
-#include "tree-cfg.h"
-#include "cfganal.h"
-#include "cfgloop.h"
-#include "gimple-iterator.h"
-#include "tracer.h"
-#include "predict.h"
-#include "gimple-ssa.h"
-#include "tree-phinodes.h"
-#include "ssa-iterators.h"
-#include "fold-const.h"
-#include "cfghooks.h"
-
-/* Given LATCH, the latch block in a loop, see if the shape of the
-   path reaching LATCH is suitable for being split by duplication.
-   If so, return the block that will be duplicated into its predecessor
-   paths.  Else return NULL.  */
-
-static basic_block
-find_block_to_duplicate_for_splitting_paths (basic_block latch)
-{
-  /* We should have simple latches at this point.  So the latch should
-     have a single successor.  This implies the predecessor of the latch
-     likely has the loop exit.  And it's that predecessor we're most
-     interested in. To keep things simple, we're going to require that
-     the latch have a single predecessor too.  */
-  if (single_succ_p (latch) && single_pred_p (latch))
-    {
-      basic_block bb = get_immediate_dominator (CDI_DOMINATORS, latch);
-      gcc_assert (single_pred_edge (latch)->src == bb);
-
-      /* If BB has been marked as not to be duplicated, then honor that
-  request.  */
-      if (ignore_bb_p (bb))
- return NULL;
-
-      gimple *last = gsi_stmt (gsi_last_nondebug_bb (bb));
-      /* The immediate dominator of the latch must end in a conditional.  */
-      if (!last || gimple_code (last) != GIMPLE_COND)
- return NULL;
-
-      /* We're hoping that BB is a join point for an IF-THEN-ELSE diamond
-  region.  Verify that it is.
-
-  First, verify that BB has two predecessors (each arm of the
-  IF-THEN-ELSE) and two successors (the latch and exit) and that
-  all edges are normal.  */
-      if (EDGE_COUNT (bb->preds) == 2
-   && !(EDGE_PRED (bb, 0)->flags & EDGE_COMPLEX)
-   && !(EDGE_PRED (bb, 1)->flags & EDGE_COMPLEX)
-   && EDGE_COUNT (bb->succs) == 2
-   && !(EDGE_SUCC (bb, 0)->flags & EDGE_COMPLEX)
-   && !(EDGE_SUCC (bb, 1)->flags & EDGE_COMPLEX))
- {
-   /* Now verify that BB's immediate dominator ends in a
-      conditional as well.  */
-   basic_block bb_idom = get_immediate_dominator (CDI_DOMINATORS, bb);
-   gimple *last = gsi_stmt (gsi_last_nondebug_bb (bb_idom));
-   if (!last || gimple_code (last) != GIMPLE_COND)
-     return NULL;
-
-   /* And that BB's immediate dominator's successors are the
-      predecessors of BB or BB itself.  */
-   if (!(EDGE_PRED (bb, 0)->src == bb_idom
- || find_edge (bb_idom, EDGE_PRED (bb, 0)->src))
-       || !(EDGE_PRED (bb, 1)->src == bb_idom
-    || find_edge (bb_idom, EDGE_PRED (bb, 1)->src)))
-     return NULL;
-
-   /* And that the predecessors of BB each have a single successor
-      or are BB's immediate domiator itself.  */
-   if (!(EDGE_PRED (bb, 0)->src == bb_idom
- || single_succ_p (EDGE_PRED (bb, 0)->src))
-       || !(EDGE_PRED (bb, 1)->src == bb_idom
-    || single_succ_p (EDGE_PRED (bb, 1)->src)))
-     return NULL;
-
-   /* So at this point we have a simple diamond for an IF-THEN-ELSE
-      construct starting at BB_IDOM, with a join point at BB.  BB
-      pass control outside the loop or to the loop latch.
-
-      We're going to want to create two duplicates of BB, one for
-      each successor of BB_IDOM.  */
-   return bb;
- }
-    }
-  return NULL;
-}
-
-/* Return the number of non-debug statements in a block.  */
-static unsigned int
-count_stmts_in_block (basic_block bb)
-{
-  gimple_stmt_iterator gsi;
-  unsigned int num_stmts = 0;
-
-  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-    {
-      gimple *stmt = gsi_stmt (gsi);
-      if (!is_gimple_debug (stmt))
- num_stmts++;
-    }
-  return num_stmts;
-}
-
-/* Return TRUE if CODE represents a tree code that is not likely to
-   be easily if-convertible because it likely expands into multiple
-   insns, FALSE otherwise.  */
-static bool
-poor_ifcvt_candidate_code (enum tree_code code)
-{
-  return (code == MIN_EXPR
-   || code == MAX_EXPR
-   || code == ABS_EXPR
-   || code == COND_EXPR);
-}
-
-/* Return TRUE if PRED of BB is an poor ifcvt candidate. */
-static bool
-poor_ifcvt_pred (basic_block pred, basic_block bb)
-{
-  /* If the edge count of the pred is not 1, then
-     this is the predecessor from the if rather
-     than middle one. */
-  if (EDGE_COUNT (pred->succs) != 1)
-    return false;
-
-  /* Empty middle bb are never a poor ifcvt candidate. */
-  if (empty_block_p (pred))
-    return false;
-  /* If BB's predecessors are single statement blocks where
-     the output of that statement feed the same PHI in BB,
-     it an ifcvt candidate. */
-  gimple *stmt = last_and_only_stmt (pred);
-  if (!stmt || gimple_code (stmt) != GIMPLE_ASSIGN)
-    return true;
-
-  /* If the statement could trap, then this is a poor ifcvt candidate. */
-  if (gimple_could_trap_p (stmt))
-    return true;
-
-  tree_code code = gimple_assign_rhs_code (stmt);
-  if (poor_ifcvt_candidate_code (code))
-    return true;
-  tree lhs = gimple_assign_lhs (stmt);
-  gimple_stmt_iterator gsi;
-  for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-    {
-      gimple *phi = gsi_stmt (gsi);
-      if (gimple_phi_arg_def (phi, 0) == lhs
-   || gimple_phi_arg_def (phi, 1) == lhs)
- return false;
-    }
-  return true;
-}
-
-/* Return TRUE if BB is a reasonable block to duplicate by examining
-   its size, false otherwise.  BB will always be a loop latch block.
-
-   Things to consider:
-
-     We do not want to spoil if-conversion if at all possible.
-
-     Most of the benefit seems to be from eliminating the unconditional
-     jump rather than CSE/DCE opportunities.  So favor duplicating
-     small latches.  A latch with just a conditional branch is ideal.
-
-     CSE/DCE opportunities crop up when statements from the predecessors
-     feed statements in the latch and allow statements in the latch to
-     simplify.  */
-
-static bool
-is_feasible_trace (basic_block bb)
-{
-  basic_block pred1 = EDGE_PRED (bb, 0)->src;
-  basic_block pred2 = EDGE_PRED (bb, 1)->src;
-  int num_stmts_in_join = count_stmts_in_block (bb);
-  int num_stmts_in_pred1
-    = EDGE_COUNT (pred1->succs) == 1 ? count_stmts_in_block (pred1) : 0;
-  int num_stmts_in_pred2
-    = EDGE_COUNT (pred2->succs) == 1 ? count_stmts_in_block (pred2) : 0;
-
-  /* Upper Hard limit on the number statements to copy.  */
-  if (num_stmts_in_join
-      >= param_max_jump_thread_duplication_stmts)
-    {
-      if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
-  "Duplicating block %d would duplicate "
-  "too many statements: %d >= %d\n",
-  bb->index, num_stmts_in_join,
-  param_max_jump_thread_duplication_stmts);
-      return false;
-    }
-
-  /* This is meant to catch cases that are likely opportunities for
-     if-conversion.  */
-  if (num_stmts_in_pred1 <= 1 && num_stmts_in_pred2 <= 1)
-    {
-      int num_phis = 0;
-      /* The max number of PHIs that should be considered for an ifcvt
-  candidate.  */
-      const int max_num_phis = 3;
-      for (gphi_iterator si = gsi_start_phis (bb); ! gsi_end_p (si);
-   gsi_next (&si))
- {
-   num_phis++;
-   if (num_phis > max_num_phis)
-     break;
- }
-      if (num_phis <= max_num_phis
-   && !poor_ifcvt_pred (pred1, bb)
-   && !poor_ifcvt_pred (pred2, bb))
- {
-   if (dump_file && (dump_flags & TDF_DETAILS))
-     fprintf (dump_file,
-      "Block %d appears to be a join point for "
-      "if-convertible bbs.\n",
-      bb->index);
-   return false;
- }
-    }
-
-  /* If the joiner has no PHIs with useful uses there is zero chance
-     of CSE/DCE/jump-threading possibilities exposed by duplicating it.  */
-  bool found_useful_phi = false;
-  for (gphi_iterator si = gsi_start_phis (bb); ! gsi_end_p (si);
-       gsi_next (&si))
-    {
-      gphi *phi = si.phi ();
-      use_operand_p use_p;
-      imm_use_iterator iter;
-      FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
- {
-   gimple *stmt = USE_STMT (use_p);
-   if (is_gimple_debug (stmt))
-     continue;
-   /* If there's a use in the joiner this might be a CSE/DCE
-      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;
-     }
-   /* If the use is on a loop header PHI and on one path the
-      value is unchanged this might expose a jump threading
-      opportunity.  */
-   if (gimple_code (stmt) == GIMPLE_PHI
-       && gimple_bb (stmt) == bb->loop_father->header
-       /* But for memory the PHI alone isn't good enough.  */
-       && ! virtual_operand_p (gimple_phi_result (stmt)))
-     {
-       bool found_unchanged_path = false;
-       for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
- if (gimple_phi_arg_def (phi, i) == gimple_phi_result (stmt))
-   {
-     found_unchanged_path = true;
-     break;
-   }
-       /* If we found an unchanged path this can only be a threading
-          opportunity if we have uses of the loop header PHI result
-  in a stmt dominating the merge block.  Otherwise the
-  splitting may prevent if-conversion.  */
-       if (found_unchanged_path)
- {
-   use_operand_p use2_p;
-   imm_use_iterator iter2;
-   FOR_EACH_IMM_USE_FAST (use2_p, iter2, gimple_phi_result (stmt))
-     {
-       gimple *use_stmt = USE_STMT (use2_p);
-       if (is_gimple_debug (use_stmt))
- continue;
-       basic_block use_bb = gimple_bb (use_stmt);
-       if (use_bb != bb
-   && dominated_by_p (CDI_DOMINATORS, bb, use_bb))
- {
-   if (gcond *cond = dyn_cast <gcond *> (use_stmt))
-     if (gimple_cond_code (cond) == EQ_EXPR
- || gimple_cond_code (cond) == NE_EXPR)
-       found_useful_phi = true;
-   break;
- }
-     }
- }
-       if (found_useful_phi)
- break;
-     }
- }
-      if (found_useful_phi)
- break;
-    }
-  /* There is one exception namely a controlling condition we can propagate
-     an equivalence from to the joiner.  */
-  bool found_cprop_opportunity = false;
-  basic_block dom = get_immediate_dominator (CDI_DOMINATORS, bb);
-  gcond *cond = as_a <gcond *> (*gsi_last_bb (dom));
-  if (gimple_cond_code (cond) == EQ_EXPR
-      || gimple_cond_code (cond) == NE_EXPR)
-    for (unsigned i = 0; i < 2; ++i)
-      {
- tree op = gimple_op (cond, i);
- if (TREE_CODE (op) == SSA_NAME)
-   {
-     use_operand_p use_p;
-     imm_use_iterator iter;
-     FOR_EACH_IMM_USE_FAST (use_p, iter, op)
-       {
- if (is_gimple_debug (USE_STMT (use_p)))
-   continue;
- if (gimple_bb (USE_STMT (use_p)) == bb)
-   {
-     found_cprop_opportunity = true;
-     break;
-   }
-       }
-   }
- if (found_cprop_opportunity)
-   break;
-      }
-
-  if (! found_useful_phi && ! found_cprop_opportunity)
-    {
-      if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
-  "Block %d is a join that does not expose CSE/DCE/jump-thread "
-  "opportunities when duplicated.\n",
-  bb->index);
-      return false;
-    }
-
-  /* We may want something here which looks at dataflow and tries
-     to guess if duplication of BB is likely to result in simplification
-     of instructions in BB in either the original or the duplicate.  */
-  return true;
-}
-
-/* If the immediate dominator of the latch of the loop is
-   block with conditional branch, then the loop latch  is
-   duplicated to its predecessors path preserving the SSA
-   semantics.
-
-   CFG before transformation.
-
-              2
-              |
-              |
-        +---->3
-        |    / \
-        |   /   \
-        |  4     5
-        |   \   /
-        |    \ /
-        |     6
-        |    / \
-        |   /   \
-        |  8     7
-        |  |     |
-        ---+     E
-
-
-
-    Block 8 is the latch.  We're going to make copies of block 6 (9 & 10)
-    and wire things up so they look like this:
-
-              2
-              |
-              |
-        +---->3
-        |    / \
-        |   /   \
-        |  4     5
-        |  |     |
-        |  |     |
-        |  9    10
-        |  |\   /|
-        |  | \ / |
-        |  |  7  |
-        |  |  |  |
-        |  |  E  |
-        |  |     |
-        |   \   /
-        |    \ /
-        +-----8
-
-
-    Blocks 9 and 10 will get merged into blocks 4 & 5 respectively which
-    enables CSE, DCE and other optimizations to occur on a larger block
-    of code.   */
-
-static bool
-split_paths ()
-{
-  bool changed = false;
-
-  loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
-  initialize_original_copy_tables ();
-  calculate_dominance_info (CDI_DOMINATORS);
-
-  for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
-    {
-      /* Only split paths if we are optimizing this loop for speed.  */
-      if (!optimize_loop_for_speed_p (loop))
- continue;
-
-      /* See if there is a block that we can duplicate to split the
-  path to the loop latch.  */
-      basic_block bb
- = find_block_to_duplicate_for_splitting_paths (loop->latch);
-
-      /* BB is the merge point for an IF-THEN-ELSE we want to transform.
-
-  Essentially we want to create a duplicate of bb and redirect the
-  first predecessor of BB to the duplicate (leaving the second
-  predecessor as is.  This will split the path leading to the latch
-  re-using BB to avoid useless copying.  */
-      if (bb && is_feasible_trace (bb))
- {
-   if (dump_file && (dump_flags & TDF_DETAILS))
-     fprintf (dump_file,
-      "Duplicating join block %d into predecessor paths\n",
-      bb->index);
-   basic_block pred0 = EDGE_PRED (bb, 0)->src;
-   if (EDGE_COUNT (pred0->succs) != 1)
-     pred0 = EDGE_PRED (bb, 1)->src;
-   transform_duplicate (pred0, bb);
-   changed = true;
-
-   /* If BB has an outgoing edge marked as IRREDUCIBLE, then
-      duplicating BB may result in an irreducible region turning
-      into a natural loop.
-
-      Long term we might want to hook this into the block
-      duplication code, but as we've seen with similar changes
-      for edge removal, that can be somewhat risky.  */
-   if (EDGE_SUCC (bb, 0)->flags & EDGE_IRREDUCIBLE_LOOP
-       || EDGE_SUCC (bb, 1)->flags & EDGE_IRREDUCIBLE_LOOP)
-     {
-       if (dump_file && (dump_flags & TDF_DETAILS))
-   fprintf (dump_file,
-    "Join block %d has EDGE_IRREDUCIBLE_LOOP set.  "
-    "Scheduling loop fixups.\n",
-    bb->index);
-       loops_state_set (LOOPS_NEED_FIXUP);
-     }
- }
-    }
-
-  loop_optimizer_finalize ();
-  free_original_copy_tables ();
-  return changed;
-}
-
-/* Main entry point for splitting paths.  Returns TODO_cleanup_cfg if any
-   paths where split, otherwise return zero.  */
-
-static unsigned int
-execute_split_paths ()
-{
-  /* If we don't have at least 2 real blocks and backedges in the
-     CFG, then there's no point in trying to perform path splitting.  */
-  if (n_basic_blocks_for_fn (cfun) <= NUM_FIXED_BLOCKS + 1
-      || !mark_dfs_back_edges ())
-    return 0;
-
-  bool changed = split_paths();
-  if (changed)
-    free_dominance_info (CDI_DOMINATORS);
-
-  return changed ? TODO_cleanup_cfg : 0;
-}
-
-static bool
-gate_split_paths ()
-{
-  return flag_split_paths;
-}
-
-namespace {
-
-const pass_data pass_data_split_paths =
-{
-  GIMPLE_PASS, /* type */
-  "split-paths", /* name */
-  OPTGROUP_NONE, /* optinfo_flags */
-  TV_SPLIT_PATHS, /* tv_id */
-  PROP_ssa, /* properties_required */
-  0, /* properties_provided */
-  0, /* properties_destroyed */
-  0, /* todo_flags_start */
-  TODO_update_ssa, /* todo_flags_finish */
-};
-
-class pass_split_paths : public gimple_opt_pass
-{
-   public:
-    pass_split_paths (gcc::context *ctxt)
-      : gimple_opt_pass (pass_data_split_paths, ctxt)
-    {}
-   /* opt_pass methods: */
-  opt_pass * clone () final override { return new pass_split_paths (m_ctxt); }
-  bool gate (function *) final override { return gate_split_paths (); }
-  unsigned int execute (function *) final override
-  {
-    return execute_split_paths ();
-  }
-
-}; // class pass_split_paths
-
-} // anon namespace
-
-gimple_opt_pass *
-make_pass_split_paths (gcc::context *ctxt)
-{
-  return new pass_split_paths (ctxt);
-}
diff --git a/gcc/opts.cc b/gcc/opts.cc
index 342517528e8..5522f41f906 100644
--- a/gcc/opts.cc
+++ b/gcc/opts.cc
@@ -707,7 +707,6 @@ static const struct default_options default_options_table[] 
=
   { OPT_LEVELS_3_PLUS, OPT_fpeel_loops, NULL, 1 },
   { OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
   { OPT_LEVELS_3_PLUS, OPT_fsplit_loops, NULL, 1 },
-    { OPT_LEVELS_3_PLUS, OPT_fsplit_paths, NULL, 1 },
   { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribution, NULL, 1 },
   { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
   { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
diff --git a/gcc/passes.def b/gcc/passes.def
index 1fc867fae51..9095c134f49 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -351,7 +351,6 @@ along with GCC; see the file COPYING3.  If not see
     NEXT_PASS (pass_cse_reciprocals);
     NEXT_PASS (pass_reassoc, false /* early_p */);
     NEXT_PASS (pass_strength_reduction);
-      NEXT_PASS (pass_split_paths);
     NEXT_PASS (pass_tracer);
     NEXT_PASS (pass_fre, false /* may_iterate */);
     /* After late FRE we rewrite no longer addressed locals into SSA
diff --git a/gcc/testsuite/g++.dg/torture/pr88797.C 
b/gcc/testsuite/g++.dg/torture/pr88797.C
new file mode 100644
index 00000000000..3dd00fcb7a9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr88797.C
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+
+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++));
+}
+
+
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr88797.C 
b/gcc/testsuite/g++.dg/tree-ssa/pr88797.C
deleted file mode 100644
index 541ae8e71e1..00000000000
--- a/gcc/testsuite/g++.dg/tree-ssa/pr88797.C
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { 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 "appears to be a join point for if-convertible 
bbs." 1 "split-paths" } } */
-
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr69270.c 
b/gcc/testsuite/gcc.c-torture/compile/pr69270.c
similarity index 57%
rename from gcc/testsuite/gcc.dg/tree-ssa/pr69270.c
rename to gcc/testsuite/gcc.c-torture/compile/pr69270.c
index b08ec9d6ddb..daed456ec60 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr69270.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr69270.c
@@ -1,17 +1,10 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fdump-tree-dom3-details" } */

/* There should be two references to bufferstep that turn into
  constants.  */
-/* { dg-final { scan-tree-dump-times "Replaced .bufferstep_\[0-9\]+. with constant .0." 
1 "dom3"} } */
-/* { dg-final { scan-tree-dump-times "Replaced .bufferstep_\[0-9\]+. with constant .1." 
1 "dom3"} } */

/* And some assignments ought to fold down to constants.  */
-/* { dg-final { scan-tree-dump-times "Folded to: (?:bufferstep)?_\[0-9\]+ = 1;" 1 
"dom3"} } */
-/* { dg-final { scan-tree-dump-times "Folded to: (?:bufferstep)?_\[0-9\]+ = 0;" 1 
"dom3"} } */

/* The XOR operations should have been optimized to constants.  */
-/* { dg-final { scan-tree-dump-not "bit_xor" "dom3"} } */


extern int *stepsizeTable;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-10.c 
b/gcc/testsuite/gcc.c-torture/compile/split-path-10.c
similarity index 81%
rename from gcc/testsuite/gcc.dg/tree-ssa/split-path-10.c
rename to gcc/testsuite/gcc.c-torture/compile/split-path-10.c
index ed208795488..336b11893b6 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-10.c
+++ b/gcc/testsuite/gcc.c-torture/compile/split-path-10.c
@@ -1,6 +1,4 @@
/* PR tree-optimization/79389  */
-/* { dg-do compile } */
-/* { dg-options "-O3 -fdump-tree-split-paths-details" } */

typedef struct
{
@@ -46,4 +44,3 @@ double MonteCarlo_integrate(int Num_samples)
return ((double) under_curve / Num_samples) * 4.0;
}

-/* { dg-final { scan-tree-dump-times "Duplicating join block" 0 "split-paths" 
} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-11.c 
b/gcc/testsuite/gcc.c-torture/compile/split-path-11.c
similarity index 55%
rename from gcc/testsuite/gcc.dg/tree-ssa/split-path-11.c
rename to gcc/testsuite/gcc.c-torture/compile/split-path-11.c
index fa33367feaa..44b8b059481 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-11.c
+++ b/gcc/testsuite/gcc.c-torture/compile/split-path-11.c
@@ -1,5 +1,3 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-vectorize -fsplit-paths 
-fdump-tree-split-paths-details -w" } */

void foo(unsigned long long *M)
{
@@ -11,4 +9,3 @@ void foo(unsigned long long *M)
   }
}

-/* { dg-final { scan-tree-dump-times "join point for if-convertible" 1 
"split-paths" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-12.c 
b/gcc/testsuite/gcc.c-torture/compile/split-path-12.c
similarity index 70%
rename from gcc/testsuite/gcc.dg/tree-ssa/split-path-12.c
rename to gcc/testsuite/gcc.c-torture/compile/split-path-12.c
index da00f795ef0..dc9da4e90ef 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-12.c
+++ b/gcc/testsuite/gcc.c-torture/compile/split-path-12.c
@@ -1,5 +1,3 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details " } */

double
foo(double *d1, double *d2, double *d3, int num, double *ip)
@@ -18,4 +16,3 @@ foo(double *d1, double *d2, double *d3, int num, double *ip)

/* Split-paths shouldn't do anything here, if there's a diamond it would
  be if-convertible.  */
-/* { dg-final { scan-tree-dump-not "Duplicating join block" "split-paths" } } 
*/
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-13.c 
b/gcc/testsuite/gcc.c-torture/compile/split-path-13.c
similarity index 62%
rename from gcc/testsuite/gcc.dg/tree-ssa/split-path-13.c
rename to gcc/testsuite/gcc.c-torture/compile/split-path-13.c
index d24e23bc59d..554ae4d8f39 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-13.c
+++ b/gcc/testsuite/gcc.c-torture/compile/split-path-13.c
@@ -1,5 +1,3 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details " } */
/* PR tree-optimization/112402 */
/* This is similar to split-path-2.c but instead of the add
  being inside both sides, we have a constant. */
@@ -22,5 +20,4 @@ foo(signed char *p, int n)
return s;
}

-/* { dg-final { scan-tree-dump "appears to be a join point for if-convertible" 
"split-paths" } } */

diff --git a/gcc/testsuite/gcc.c-torture/compile/split-path-2.c 
b/gcc/testsuite/gcc.c-torture/compile/split-path-2.c
new file mode 100644
index 00000000000..9418c9488d4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/split-path-2.c
@@ -0,0 +1,18 @@
+
+int
+foo(signed char *p, int n)
+{
+  int s = 0;
+  int i;
+
+  for (i = 0; i < n; i++) {
+    if (p[i] >= 0)
+      s++;
+    else
+      s--;
+  }
+
+  return s;
+}
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-3.c 
b/gcc/testsuite/gcc.c-torture/compile/split-path-3.c
similarity index 93%
rename from gcc/testsuite/gcc.dg/tree-ssa/split-path-3.c
rename to gcc/testsuite/gcc.c-torture/compile/split-path-3.c
index f6a29f628a2..9ea9fb2fed1 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-3.c
+++ b/gcc/testsuite/gcc.c-torture/compile/split-path-3.c
@@ -1,5 +1,3 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details -w" } */

typedef struct bitmap_head_def *bitmap;
extern void vec_assert_fail (const char *, const char *, const char *file_,
@@ -94,4 +92,3 @@ compute_idf (bitmap_head * dfs)
(VEC_int_heap_free (&work_stack));
}

-/* { dg-final { scan-tree-dump-not "Duplicating join block" "split-paths" } } 
*/
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-4.c 
b/gcc/testsuite/gcc.c-torture/compile/split-path-4.c
similarity index 62%
rename from gcc/testsuite/gcc.dg/tree-ssa/split-path-4.c
rename to gcc/testsuite/gcc.c-torture/compile/split-path-4.c
index cbee6fce4b7..6705f9e8426 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-4.c
+++ b/gcc/testsuite/gcc.c-torture/compile/split-path-4.c
@@ -1,5 +1,3 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details -w 
-fdisable-tree-thread1 -fdisable-tree-thread2" } */

/* Note: Threader causes the infinite loop in val & 1 sooner.  */

@@ -25,5 +23,4 @@ powi_cost (long n)
   }
}

-/* { dg-final { scan-tree-dump-times "Duplicating join block" 1 "split-paths" 
} } */

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-5.c 
b/gcc/testsuite/gcc.c-torture/compile/split-path-5.c
similarity index 84%
rename from gcc/testsuite/gcc.dg/tree-ssa/split-path-5.c
rename to gcc/testsuite/gcc.c-torture/compile/split-path-5.c
index 2f5e7edcfa8..aff1f038195 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-5.c
+++ b/gcc/testsuite/gcc.c-torture/compile/split-path-5.c
@@ -1,5 +1,3 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details -w" } */

const extern signed char *__ctype_ptr__;
typedef unsigned char uchar;
@@ -41,4 +39,3 @@ bmhi_init (const signed char *pattern)
   }
}

-/* { dg-final { scan-tree-dump-times "join point for if-convertible" 1 
"split-paths" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c 
b/gcc/testsuite/gcc.c-torture/compile/split-path-6.c
similarity index 82%
rename from gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c
rename to gcc/testsuite/gcc.c-torture/compile/split-path-6.c
index e2b0a9571f0..9c32c813b60 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c
+++ b/gcc/testsuite/gcc.c-torture/compile/split-path-6.c
@@ -1,5 +1,3 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fno-ssa-phiopt 
-fdump-tree-split-paths-details -fno-finite-loops -fno-tree-dominator-opts -fno-tree-vrp 
-w" } */

struct __sFILE
{
@@ -75,4 +73,3 @@ lookharder (char *string)
   }
}

-/* { dg-final { scan-tree-dump-times "Duplicating join block" 2 "split-paths" 
} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c 
b/gcc/testsuite/gcc.c-torture/compile/split-path-7.c
similarity index 87%
rename from gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c
rename to gcc/testsuite/gcc.c-torture/compile/split-path-7.c
index 35634ab3bd8..33d04b4ff7d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c
+++ b/gcc/testsuite/gcc.c-torture/compile/split-path-7.c
@@ -1,5 +1,3 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fno-ssa-phiopt -fno-tree-sink 
-fdump-tree-split-paths-details -w" } */


struct _reent
@@ -91,4 +89,3 @@ linit ()
}
   }
}
-/* { dg-final { scan-tree-dump-times "Duplicating join block" 0 "split-paths" 
} } */
diff --git a/gcc/testsuite/gcc.c-torture/compile/split-path-8.c 
b/gcc/testsuite/gcc.c-torture/compile/split-path-8.c
new file mode 100644
index 00000000000..cccbf0ca0a3
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/split-path-8.c
@@ -0,0 +1,11 @@
+/* PR77283 */
+
+void
+foo (double *x, double *a, double *b, long n, double limit)
+{
+  long i;
+  for (i=0; i < n; i++)
+    if (a[i] < limit)
+      x[i] = b[i];
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/split-path-9.c 
b/gcc/testsuite/gcc.c-torture/compile/split-path-9.c
new file mode 100644
index 00000000000..4eacad2978a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/split-path-9.c
@@ -0,0 +1,14 @@
+/* PR77366 */
+
+void
+foo(unsigned int size, unsigned int *state)
+{
+  unsigned int i;
+
+  for(i = 0; i < size; i++)
+    {
+      if(state[i] & 1)
+ state[i] ^= 1;
+    }
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c 
b/gcc/testsuite/gcc.c-torture/execute/split-path-1.c
similarity index 83%
rename from gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c
rename to gcc/testsuite/gcc.c-torture/execute/split-path-1.c
index b670dee8d10..e0ca386b4ea 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/split-path-1.c
@@ -1,6 +1,4 @@
-/* { dg-do run } */
/* Note both PHI-OPT and the loop if conversion pass converts the inner if to 
be branchless using min/max. */
-/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details --param 
max-jump-thread-duplication-stmts=20 -fno-ssa-phiopt -fno-tree-loop-if-convert" } */

#include <stdio.h>
#include <stdlib.h>
@@ -67,4 +65,3 @@ main()
return 0;
}

-/* { dg-final { scan-tree-dump "Duplicating join block" "split-paths" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/split-path-2.c
deleted file mode 100644
index 61697a35e56..00000000000
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-2.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details " } */
-
-int
-foo(signed char *p, int n)
-{
-  int s = 0;
-  int i;
-
-  for (i = 0; i < n; i++) {
-    if (p[i] >= 0)
-      s++;
-    else
-      s--;
-  }
-
-  return s;
-}
-
-/* { dg-final { scan-tree-dump "appears to be a join point for if-convertible" 
"split-paths" } } */
-
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-8.c 
b/gcc/testsuite/gcc.dg/tree-ssa/split-path-8.c
deleted file mode 100644
index fb54f5dc512..00000000000
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-8.c
+++ /dev/null
@@ -1,14 +0,0 @@
-/* PR77283 */
-/* { dg-do compile } */
-/* { dg-options "-O3 -fdump-tree-split-paths-details" } */
-
-void
-foo (double *x, double *a, double *b, long n, double limit)
-{
-  long i;
-  for (i=0; i < n; i++)
-    if (a[i] < limit)
-      x[i] = b[i];
-}
-
-/* { dg-final { scan-tree-dump-times "Duplicating join block" 0 "split-paths" 
} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-9.c 
b/gcc/testsuite/gcc.dg/tree-ssa/split-path-9.c
deleted file mode 100644
index 8be0cd01201..00000000000
--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-9.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* PR77366 */
-/* { dg-do compile } */
-/* { dg-options "-O3 -fdump-tree-split-paths-details" } */
-
-void
-foo(unsigned int size, unsigned int *state)
-{
-  unsigned int i;
-
-  for(i = 0; i < size; i++)
-    {
-      if(state[i] & 1)
- state[i] ^= 1;
-    }
-}
-
-/* { dg-final { scan-tree-dump-times "Duplicating join block" 0 "split-paths" 
} } */
diff --git a/gcc/testsuite/gcc.target/i386/pr106450.c 
b/gcc/testsuite/gcc.target/i386/pr106450.c
index d16231f6abd..009e3eb8c74 100644
--- a/gcc/testsuite/gcc.target/i386/pr106450.c
+++ b/gcc/testsuite/gcc.target/i386/pr106450.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target int128 } } */
-/* { dg-options "-O2 -fsplit-paths" } */
+/* { dg-options "-O2" } */

__int128 n;

diff --git a/gcc/timevar.def b/gcc/timevar.def
index 588d987ec35..c7020997609 100644
--- a/gcc/timevar.def
+++ b/gcc/timevar.def
@@ -287,7 +287,6 @@ DEFTIMEVAR (TV_GCSE_AFTER_RELOAD     , "load CSE after 
reload")
DEFTIMEVAR (TV_REE      , "ree")
DEFTIMEVAR (TV_THREAD_PROLOGUE_AND_EPILOGUE, "thread pro- & epilogue")
DEFTIMEVAR (TV_IFCVT2      , "if-conversion 2")
-DEFTIMEVAR (TV_SPLIT_PATHS      , "split paths")
DEFTIMEVAR (TV_COMBINE_STACK_ADJUST  , "combine stack adjustments")
DEFTIMEVAR (TV_PEEPHOLE2             , "peephole 2")
DEFTIMEVAR (TV_RENAME_REGISTERS      , "rename registers")
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index b3c97658a8f..a3b35e009e0 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -404,7 +404,6 @@ extern gimple_opt_pass *make_pass_ch (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_ch_vect (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_sccopy (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_ccp (gcc::context *ctxt);
-extern gimple_opt_pass *make_pass_split_paths (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_build_ssa (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_build_alias (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_build_ealias (gcc::context *ctxt);


--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald; (HRB 36809, AG Nuernberg)




Reply via email to