The following removes the ability to enable stand-alone loop if-conversion
or to disable loop if-conversion even though vectorization runs. This
was hardly useful before and testing and coverage of this mode is
basically non-existent. Instead phiopt and cselimg are the general
if-conversion vehicles.
This will allow to more tightly integrate vectorizer loop if-conversion
with loop vectorization.
I have likely left some dead code removal on the plate and will followup
with that if there's consensus on this.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
There's a few more testcases using -ftree-loop-if-convert, I have
left those untouched (but no more target specific testcases).
Any comments?
Thanks,
Richard.
* common.opt (ftree-loop-if-convert): Mark as ignored.
* doc/invoke.texi (ftree-loop-if-convert): Remove.
* tree-ssa-phiopt.cc (cond_if_else_store_replacement):
Do not check !flag_tree_loop_if_convert.
* tree-if-conv.cc (pass_if_conversion::gate): Only
run when loop vectorization is enabled on any loop.
(pass_if_conversion::execute): Adjust.
(tree_if_conversion): Likewise. Simplify as we now
always version.
* gcc.dg/vect/bb-slp-pattern-2.c: Adjust.
* gcc.target/i386/pr45685.c: Likewise.
---
gcc/common.opt | 4 +-
gcc/doc/invoke.texi | 12 +---
gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c | 4 +-
gcc/testsuite/gcc.target/i386/pr45685.c | 4 +-
gcc/tree-if-conv.cc | 65 ++++++++------------
gcc/tree-ssa-phiopt.cc | 3 +-
6 files changed, 33 insertions(+), 59 deletions(-)
diff --git a/gcc/common.opt b/gcc/common.opt
index c5590f76ebb..bda225ffff1 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2038,8 +2038,8 @@ EnumValue
Enum(stack_reuse_level) String(none) Value(SR_NONE)
ftree-loop-if-convert
-Common Var(flag_tree_loop_if_convert) Init(-1) Optimization
-Convert conditional jumps in innermost loops to branchless equivalents.
+Common Ignore
+Does nothing. Preserved for backward compatibility.
ftree-loop-if-convert-stores
Common Ignore
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e119e149fb1..e281cc1e66e 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -683,8 +683,7 @@ Objective-C and Objective-C++ Dialects}.
-fthread-jumps -ftracer -ftree-bit-ccp
-ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-coalesce-vars
-ftree-copy-prop -ftree-cselim -ftree-dce -ftree-dominator-opts
--ftree-dse -ftree-forwprop -ftree-fre -fcode-hoisting
--ftree-loop-if-convert -ftree-loop-im
+-ftree-dse -ftree-forwprop -ftree-fre -fcode-hoisting -ftree-loop-im
-ftree-phiprop -ftree-loop-distribution -ftree-loop-distribute-patterns
-ftree-loop-ivcanon -ftree-loop-linear -ftree-loop-optimize
-ftree-loop-vectorize
@@ -15228,15 +15227,6 @@ limit the ability to debug an optimized program
compiled with
prevents SSA coalescing of user variables. This option is enabled by
default if optimization is enabled, and it does very little otherwise.
-@opindex ftree-loop-if-convert
-@opindex fno-tree-loop-if-convert
-@item -ftree-loop-if-convert
-Attempt to transform conditional jumps in the innermost loops to
-branch-less equivalents. The intent is to remove control-flow from
-the innermost loops in order to improve the ability of the
-vectorization pass to handle these loops. This is enabled by default
-if vectorization is enabled.
-
@opindex ftree-loop-distribution
@opindex fno-tree-loop-distribution
@item -ftree-loop-distribution
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
b/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
index 05fde3a7feb..5f5009b0427 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
@@ -1,5 +1,5 @@
/* { dg-require-effective-target vect_condition } */
-/* { dg-additional-options "-fno-tree-vectorize -ftree-slp-vectorize
-ftree-loop-if-convert" } */
+/* { dg-additional-options "-fno-tree-vectorize -ftree-slp-vectorize" } */
#include "tree-vect.h"
@@ -50,4 +50,4 @@ int main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp1" {
target { vect_element_align && vect_pack_trunc } } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp1" { xfail
{ vect_element_align && vect_pack_trunc } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr45685.c
b/gcc/testsuite/gcc.target/i386/pr45685.c
index 135fe823fcf..50fd1f4786f 100644
--- a/gcc/testsuite/gcc.target/i386/pr45685.c
+++ b/gcc/testsuite/gcc.target/i386/pr45685.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { ! ia32 } } } */
-/* { dg-options "-O3 -mno-sse4 -ftree-loop-if-convert" } */
+/* { dg-options "-O3 -mno-sse4" } */
typedef unsigned long long int uint64_t;
typedef long long int int64_t;
@@ -36,4 +36,4 @@ int summation_helper_2(int64_t* products, uint64_t count)
return s;
}
-/* { dg-final { scan-assembler-times "cmov" 6 } } */
+/* { dg-final { scan-assembler-times "cmov" 6 { xfail *-*-* } } } */
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index 5d8abfb52b5..23b4e4cd63a 100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -4084,7 +4084,7 @@ tree_if_conversion (class loop *loop, vec<gimple *>
*preds)
bitmap exit_bbs;
edge pe;
auto_vec<data_reference_p, 10> refs;
- bool loop_versioned;
+ class loop *vloop, *nloop;
again:
rloop = NULL;
@@ -4094,7 +4094,6 @@ tree_if_conversion (class loop *loop, vec<gimple *>
*preds)
need_to_predicate = false;
need_to_rewrite_undefined = false;
any_complicated_phi = false;
- loop_versioned = false;
/* Apply more aggressive if-conversion when loop or its outer loop were
marked with simd pragma. When that's the case, we try to if-convert
@@ -4147,8 +4146,7 @@ tree_if_conversion (class loop *loop, vec<gimple *>
*preds)
}
}
- if ((flag_tree_loop_vectorize || loop->force_vectorize)
- && !loop->dont_vectorize)
+ if (!loop->dont_vectorize)
need_to_lower_bitfields = bitfields_to_lower_p (loop, reads_to_lower,
writes_to_lower);
@@ -4158,28 +4156,21 @@ tree_if_conversion (class loop *loop, vec<gimple *>
*preds)
/* The edge to insert invariant stmts on. */
pe = loop_preheader_edge (loop);
- /* Since we have no cost model, always version loops unless the user
- specified -ftree-loop-if-convert or unless versioning is required.
+ /* Since we have no cost model, always version loops.
Either version this loop, or if the pattern is right for outer-loop
vectorization, version the outer loop. In the latter case we will
still if-convert the original inner loop. */
- if (need_to_lower_bitfields
- || need_to_predicate
- || any_complicated_phi
- || flag_tree_loop_if_convert != 1)
- {
- class loop *vloop
- = (versionable_outer_loop_p (loop_outer (loop))
+ vloop = (versionable_outer_loop_p (loop_outer (loop))
? loop_outer (loop) : loop);
- class loop *nloop = version_loop_for_if_conversion (vloop, preds);
- if (nloop == NULL)
- goto cleanup;
- if (vloop != loop)
- {
- /* If versionable_outer_loop_p decided to version the
- outer loop, version also the inner loop of the non-vectorized
- loop copy. So we transform:
- loop1
+ nloop = version_loop_for_if_conversion (vloop, preds);
+ if (nloop == NULL)
+ goto cleanup;
+ if (vloop != loop)
+ {
+ /* If versionable_outer_loop_p decided to version the
+ outer loop, version also the inner loop of the non-vectorized
+ loop copy. So we transform:
+ loop1
loop2
into:
if (LOOP_VECTORIZED (1, 3))
@@ -4193,18 +4184,15 @@ tree_if_conversion (class loop *loop, vec<gimple *>
*preds)
loop4 (copy of loop2)
else
loop5 (copy of loop4) */
- gcc_assert (nloop->inner && nloop->inner->next == NULL);
- rloop = nloop->inner;
- }
- else
- /* If we versioned loop then make sure to insert invariant
- stmts before the .LOOP_VECTORIZED check since the vectorizer
- will re-use that for things like runtime alias versioning
- whose condition can end up using those invariants. */
- pe = single_pred_edge (gimple_bb (preds->last ()));
-
- loop_versioned = true;
+ gcc_assert (nloop->inner && nloop->inner->next == NULL);
+ rloop = nloop->inner;
}
+ else
+ /* If we versioned loop then make sure to insert invariant
+ stmts before the .LOOP_VECTORIZED check since the vectorizer
+ will re-use that for things like runtime alias versioning
+ whose condition can end up using those invariants. */
+ pe = single_pred_edge (gimple_bb (preds->last ()));
if (need_to_lower_bitfields)
{
@@ -4236,7 +4224,7 @@ tree_if_conversion (class loop *loop, vec<gimple *>
*preds)
/* Now all statements are if-convertible. Combine all the basic
blocks into one huge basic block doing the if-conversion
on-the-fly. */
- combine_blocks (loop, loop_versioned);
+ combine_blocks (loop, true);
}
std::pair <tree, tree> *name_pair;
@@ -4327,9 +4315,7 @@ public:
bool
pass_if_conversion::gate (function *fun)
{
- return (((flag_tree_loop_vectorize || fun->has_force_vectorize_loops)
- && flag_tree_loop_if_convert != 0)
- || flag_tree_loop_if_convert == 1);
+ return flag_tree_loop_vectorize || fun->has_force_vectorize_loops;
}
unsigned int
@@ -4342,9 +4328,8 @@ pass_if_conversion::execute (function *fun)
auto_vec<gimple *> preds;
for (auto loop : loops_list (cfun, 0))
- if (flag_tree_loop_if_convert == 1
- || ((flag_tree_loop_vectorize || loop->force_vectorize)
- && !loop->dont_vectorize))
+ if ((flag_tree_loop_vectorize || loop->force_vectorize)
+ && !loop->dont_vectorize)
todo |= tree_if_conversion (loop, &preds);
if (todo)
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index f8dbd26abc1..fd9aa2bedb4 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -3947,8 +3947,7 @@ cond_if_else_store_replacement (basic_block then_bb,
basic_block else_bb,
/* If either vectorization or if-conversion is disabled then do
not sink any stores. */
if (param_max_stores_to_sink == 0
- || (!flag_tree_loop_vectorize && !flag_tree_slp_vectorize)
- || !flag_tree_loop_if_convert)
+ || (!flag_tree_loop_vectorize && !flag_tree_slp_vectorize))
return false;
/* Find data references. */
--
2.51.0