> On 10 Jul 2026, at 15:57, Alfie Richards <[email protected]> wrote: > > 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)
Thanks for this. Can you also share the options used? Kyrill > > 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)
