diff mbox

New GCC options for loop vectorization

Message ID CAAkRFZKiGcyeAG-dNFVc1RwKZdaBLcE6d4j1D_GeOqV39mJSwQ@mail.gmail.com
State New
Headers show

Commit Message

Xinliang David Li Sept. 13, 2013, 4:56 p.m. UTC
Updated patch implementing the logic that more specific option wins.

Ok for trunk?

thanks,

David

On Fri, Sep 13, 2013 at 9:48 AM, Xinliang David Li <davidxl@google.com> wrote:
> Ok -- then my updated patch is wrong then. The implementation in the
> first version matches the requirement.
>
> thanks,
>
> David
>
>
> On Fri, Sep 13, 2013 at 9:45 AM, Joseph S. Myers
> <joseph@codesourcery.com> wrote:
>> On Fri, 13 Sep 2013, Richard Biener wrote:
>>
>>> @@ -1691,6 +1695,12 @@ common_handle_option (struct gcc_options
>>>          opts->x_flag_ipa_reference = false;
>>>        break;
>>>
>>> +    case OPT_ftree_vectorize:
>>> +      if (!opts_set->x_flag_tree_loop_vectorize)
>>> + opts->x_flag_tree_loop_vectorize = value;
>>> +      if (!opts_set->x_flag_tree_slp_vectorize)
>>> + opts->x_flag_tree_slp_vectorize = value;
>>> +      break;
>>>
>>> doesn't look obviously correct.  Does that handle
>>
>> It looks right to me.  The general principle is that the more specific
>> option takes precedence over the less specific one, whatever the order on
>> the command line.
>>
>>>   -ftree-vectorize -fno-tree-loop-vectorize -ftree-vectorize
>>
>> Should mean -ftree-slp-vectorize.
>>
>>>   -ftree-loop-vectorize -fno-tree-vectorize
>>
>> Should mean -ftree-loop-vectorize.
>>
>>>   -ftree-slp-vectorize -fno-tree-vectorize
>>
>> Should mean -ftree-slp-vectorize.
>>
>> --
>> Joseph S. Myers
>> joseph@codesourcery.com

Comments

Richard Biener Sept. 16, 2013, 10:07 a.m. UTC | #1
On Fri, Sep 13, 2013 at 6:56 PM, Xinliang David Li <davidxl@google.com> wrote:
> Updated patch implementing the logic that more specific option wins.
>
> Ok for trunk?

@@ -2305,8 +2305,8 @@ omp_max_vf (void)
 {
   if (!optimize
       || optimize_debug
-      || (!flag_tree_vectorize
-  && global_options_set.x_flag_tree_vectorize))
+      || (!flag_tree_loop_vectorize
+  && global_options_set.x_flag_tree_loop_vectorize))
     return 1;

Not sure what is the intent here, but it looks like
-fno-tree-vectorize will no longer disable this.  So it would
need to check (global_options_set.x_flag_tree_vectorize ||
global_options_set.x_flag_tree_loop_vectorize)?  Jakub?

   int vs = targetm.vectorize.autovectorize_vector_sizes ();
@@ -5684,10 +5684,10 @@ expand_omp_simd (struct omp_region *regi
   loop->simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
   cfun->has_simduid_loops = true;
  }
-      /* If not -fno-tree-vectorize, hint that we want to vectorize
+      /* If not -fno-tree-loop-vectorize, hint that we want to vectorize
  the loop.  */
-      if ((flag_tree_vectorize
-   || !global_options_set.x_flag_tree_vectorize)
+      if ((flag_tree_loop_vectorize
+   || !global_options_set.x_flag_tree_loop_vectorize)
   && loop->safelen > 1)
  {
   loop->force_vect = true;

similar.

-      if (!opts_set->x_flag_tree_vectorize)
- opts->x_flag_tree_vectorize = value;
+      if (!opts_set->x_flag_tree_loop_vectorize)
+ opts->x_flag_tree_loop_vectorize = value;
+      if (!opts_set->x_flag_tree_slp_vectorize)
+ opts->x_flag_tree_slp_vectorize = value;

similar - if I use -fprofile-use -fno-tree-vecotorize you override this choice.
This case should be wrapped in if (!opts_set->x_flag_tree_vectorize)

 @item -ftree-vectorize
 @opindex ftree-vectorize
+Perform vectorization on trees. This flag enables
@option{-ftree-loop-vectorize}
+and @option{-ftree-slp-vectorize} if neither option is explicitly specified.

"if neither option is explicitely specified" doesn't correctly document
-ftree-loop-vectorize -ftree-vectorize behavior, no? (-ftree-slp-vectorize
is still enabled here)

I'm not a native speaker so I cannot suggest a clearer wording here
but maybe just say "if not explicitely specified".

Ok with the -fprofile-use change I suggested and whatever resolution Jakub
suggests and the doc adjustment.

Thanks,
Richard.

> thanks,
>
> David
>
> On Fri, Sep 13, 2013 at 9:48 AM, Xinliang David Li <davidxl@google.com> wrote:
>> Ok -- then my updated patch is wrong then. The implementation in the
>> first version matches the requirement.
>>
>> thanks,
>>
>> David
>>
>>
>> On Fri, Sep 13, 2013 at 9:45 AM, Joseph S. Myers
>> <joseph@codesourcery.com> wrote:
>>> On Fri, 13 Sep 2013, Richard Biener wrote:
>>>
>>>> @@ -1691,6 +1695,12 @@ common_handle_option (struct gcc_options
>>>>          opts->x_flag_ipa_reference = false;
>>>>        break;
>>>>
>>>> +    case OPT_ftree_vectorize:
>>>> +      if (!opts_set->x_flag_tree_loop_vectorize)
>>>> + opts->x_flag_tree_loop_vectorize = value;
>>>> +      if (!opts_set->x_flag_tree_slp_vectorize)
>>>> + opts->x_flag_tree_slp_vectorize = value;
>>>> +      break;
>>>>
>>>> doesn't look obviously correct.  Does that handle
>>>
>>> It looks right to me.  The general principle is that the more specific
>>> option takes precedence over the less specific one, whatever the order on
>>> the command line.
>>>
>>>>   -ftree-vectorize -fno-tree-loop-vectorize -ftree-vectorize
>>>
>>> Should mean -ftree-slp-vectorize.
>>>
>>>>   -ftree-loop-vectorize -fno-tree-vectorize
>>>
>>> Should mean -ftree-loop-vectorize.
>>>
>>>>   -ftree-slp-vectorize -fno-tree-vectorize
>>>
>>> Should mean -ftree-slp-vectorize.
>>>
>>> --
>>> Joseph S. Myers
>>> joseph@codesourcery.com
Jakub Jelinek Sept. 16, 2013, 10:17 a.m. UTC | #2
On Mon, Sep 16, 2013 at 12:07:37PM +0200, Richard Biener wrote:
> On Fri, Sep 13, 2013 at 6:56 PM, Xinliang David Li <davidxl@google.com> wrote:
> > Updated patch implementing the logic that more specific option wins.
> >
> > Ok for trunk?
> 
> @@ -2305,8 +2305,8 @@ omp_max_vf (void)
>  {
>    if (!optimize
>        || optimize_debug
> -      || (!flag_tree_vectorize
> -  && global_options_set.x_flag_tree_vectorize))
> +      || (!flag_tree_loop_vectorize
> +  && global_options_set.x_flag_tree_loop_vectorize))
>      return 1;
> 
> Not sure what is the intent here, but it looks like
> -fno-tree-vectorize will no longer disable this.  So it would
> need to check (global_options_set.x_flag_tree_vectorize ||
> global_options_set.x_flag_tree_loop_vectorize)?  Jakub?

The point of omp_max_vf is to allow vectorization of simd routines
in the source even without -O3/-Ofast/-ftree-vectorize, as long
as user hasn't requested no vectorization (-fno-tree-vectorize, or
-O0, -Og).  So yes, you'd probably need to change this spot
to check for either global_options_set.x_flag_tree_vectorize
|| global_options_set.x_flag_tree_loop_vectorize, because either
of them meant explicit request to either vectorize or not vectorize loops.
If user has requested vectorization or non-vectorization of loops, then
simd loops just should follow those requests, it is only the default
if there was nothing explicit, which will for now be different between
normal and simd loops, normal loops won't be vectorized, simd loops will be,
because they were specially marked in the source and so it is probably
worthwhile to vectorize them.

	Jakub
Xinliang David Li Sept. 16, 2013, 7:56 p.m. UTC | #3
I incorporated all the comments and committed the change (also fixed a
test failure with --help=optimizers).

thanks,

David

On Mon, Sep 16, 2013 at 3:07 AM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Fri, Sep 13, 2013 at 6:56 PM, Xinliang David Li <davidxl@google.com> wrote:
>> Updated patch implementing the logic that more specific option wins.
>>
>> Ok for trunk?
>
> @@ -2305,8 +2305,8 @@ omp_max_vf (void)
>  {
>    if (!optimize
>        || optimize_debug
> -      || (!flag_tree_vectorize
> -  && global_options_set.x_flag_tree_vectorize))
> +      || (!flag_tree_loop_vectorize
> +  && global_options_set.x_flag_tree_loop_vectorize))
>      return 1;
>
> Not sure what is the intent here, but it looks like
> -fno-tree-vectorize will no longer disable this.  So it would
> need to check (global_options_set.x_flag_tree_vectorize ||
> global_options_set.x_flag_tree_loop_vectorize)?  Jakub?
>
>    int vs = targetm.vectorize.autovectorize_vector_sizes ();
> @@ -5684,10 +5684,10 @@ expand_omp_simd (struct omp_region *regi
>    loop->simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
>    cfun->has_simduid_loops = true;
>   }
> -      /* If not -fno-tree-vectorize, hint that we want to vectorize
> +      /* If not -fno-tree-loop-vectorize, hint that we want to vectorize
>   the loop.  */
> -      if ((flag_tree_vectorize
> -   || !global_options_set.x_flag_tree_vectorize)
> +      if ((flag_tree_loop_vectorize
> +   || !global_options_set.x_flag_tree_loop_vectorize)
>    && loop->safelen > 1)
>   {
>    loop->force_vect = true;
>
> similar.
>
> -      if (!opts_set->x_flag_tree_vectorize)
> - opts->x_flag_tree_vectorize = value;
> +      if (!opts_set->x_flag_tree_loop_vectorize)
> + opts->x_flag_tree_loop_vectorize = value;
> +      if (!opts_set->x_flag_tree_slp_vectorize)
> + opts->x_flag_tree_slp_vectorize = value;
>
> similar - if I use -fprofile-use -fno-tree-vecotorize you override this choice.
> This case should be wrapped in if (!opts_set->x_flag_tree_vectorize)
>
>  @item -ftree-vectorize
>  @opindex ftree-vectorize
> +Perform vectorization on trees. This flag enables
> @option{-ftree-loop-vectorize}
> +and @option{-ftree-slp-vectorize} if neither option is explicitly specified.
>
> "if neither option is explicitely specified" doesn't correctly document
> -ftree-loop-vectorize -ftree-vectorize behavior, no? (-ftree-slp-vectorize
> is still enabled here)
>
> I'm not a native speaker so I cannot suggest a clearer wording here
> but maybe just say "if not explicitely specified".
>
> Ok with the -fprofile-use change I suggested and whatever resolution Jakub
> suggests and the doc adjustment.
>
> Thanks,
> Richard.
>
>> thanks,
>>
>> David
>>
>> On Fri, Sep 13, 2013 at 9:48 AM, Xinliang David Li <davidxl@google.com> wrote:
>>> Ok -- then my updated patch is wrong then. The implementation in the
>>> first version matches the requirement.
>>>
>>> thanks,
>>>
>>> David
>>>
>>>
>>> On Fri, Sep 13, 2013 at 9:45 AM, Joseph S. Myers
>>> <joseph@codesourcery.com> wrote:
>>>> On Fri, 13 Sep 2013, Richard Biener wrote:
>>>>
>>>>> @@ -1691,6 +1695,12 @@ common_handle_option (struct gcc_options
>>>>>          opts->x_flag_ipa_reference = false;
>>>>>        break;
>>>>>
>>>>> +    case OPT_ftree_vectorize:
>>>>> +      if (!opts_set->x_flag_tree_loop_vectorize)
>>>>> + opts->x_flag_tree_loop_vectorize = value;
>>>>> +      if (!opts_set->x_flag_tree_slp_vectorize)
>>>>> + opts->x_flag_tree_slp_vectorize = value;
>>>>> +      break;
>>>>>
>>>>> doesn't look obviously correct.  Does that handle
>>>>
>>>> It looks right to me.  The general principle is that the more specific
>>>> option takes precedence over the less specific one, whatever the order on
>>>> the command line.
>>>>
>>>>>   -ftree-vectorize -fno-tree-loop-vectorize -ftree-vectorize
>>>>
>>>> Should mean -ftree-slp-vectorize.
>>>>
>>>>>   -ftree-loop-vectorize -fno-tree-vectorize
>>>>
>>>> Should mean -ftree-loop-vectorize.
>>>>
>>>>>   -ftree-slp-vectorize -fno-tree-vectorize
>>>>
>>>> Should mean -ftree-slp-vectorize.
>>>>
>>>> --
>>>> Joseph S. Myers
>>>> joseph@codesourcery.com
diff mbox

Patch

Index: omp-low.c
===================================================================
--- omp-low.c	(revision 202540)
+++ omp-low.c	(working copy)
@@ -2305,8 +2305,8 @@  omp_max_vf (void)
 {
   if (!optimize
       || optimize_debug
-      || (!flag_tree_vectorize
-	  && global_options_set.x_flag_tree_vectorize))
+      || (!flag_tree_loop_vectorize
+	  && global_options_set.x_flag_tree_loop_vectorize))
     return 1;
 
   int vs = targetm.vectorize.autovectorize_vector_sizes ();
@@ -5684,10 +5684,10 @@  expand_omp_simd (struct omp_region *regi
 	  loop->simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
 	  cfun->has_simduid_loops = true;
 	}
-      /* If not -fno-tree-vectorize, hint that we want to vectorize
+      /* If not -fno-tree-loop-vectorize, hint that we want to vectorize
 	 the loop.  */
-      if ((flag_tree_vectorize
-	   || !global_options_set.x_flag_tree_vectorize)
+      if ((flag_tree_loop_vectorize
+	   || !global_options_set.x_flag_tree_loop_vectorize)
 	  && loop->safelen > 1)
 	{
 	  loop->force_vect = true;
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 202540)
+++ ChangeLog	(working copy)
@@ -1,3 +1,22 @@ 
+2013-09-12  Xinliang David Li  <davidxl@google.com>
+
+	* tree-if-conv.c (main_tree_if_conversion): Check new flag.
+	* omp-low.c (omp_max_vf): Ditto.
+	(expand_omp_simd): Ditto.
+	* tree-vectorizer.c (vectorize_loops): Ditto.
+	(gate_vect_slp): Ditto.
+	(gate_increase_alignment): Ditto.
+	* tree-ssa-pre.c (inhibit_phi_insertion): Ditto.
+	* tree-ssa-loop.c (gate_tree_vectorize): Ditto.
+	(gate_tree_vectorize): Name change.
+	(tree_vectorize): Ditto.
+	(pass_vectorize::gate): Call new function.
+	(pass_vectorize::execute): Ditto.
+	opts.c: O3 default setting change.
+	(finish_options): Check new flag.
+	* doc/invoke.texi: Document new flags.
+	* common.opt: New flags.
+
 2013-09-12  Vladimir Makarov  <vmakarov@redhat.com>
 
 	PR middle-end/58335
Index: opts.c
===================================================================
--- opts.c	(revision 202540)
+++ opts.c	(working copy)
@@ -498,7 +498,8 @@  static const struct default_options defa
     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
     { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
     { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
-    { OPT_LEVELS_3_PLUS, OPT_ftree_vectorize, NULL, 1 },
+    { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 },
+    { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 },
     { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model, NULL, 1 },
     { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
     { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
@@ -826,7 +827,8 @@  finish_options (struct gcc_options *opts
 
   /* Set PARAM_MAX_STORES_TO_SINK to 0 if either vectorization or if-conversion
      is disabled.  */
-  if (!opts->x_flag_tree_vectorize || !opts->x_flag_tree_loop_if_convert)
+  if ((!opts->x_flag_tree_loop_vectorize && !opts->x_flag_tree_slp_vectorize)
+       || !opts->x_flag_tree_loop_if_convert)
     maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0,
                            opts->x_param_values, opts_set->x_param_values);
 
@@ -1660,8 +1662,10 @@  common_handle_option (struct gcc_options
 	opts->x_flag_unswitch_loops = value;
       if (!opts_set->x_flag_gcse_after_reload)
 	opts->x_flag_gcse_after_reload = value;
-      if (!opts_set->x_flag_tree_vectorize)
-	opts->x_flag_tree_vectorize = value;
+      if (!opts_set->x_flag_tree_loop_vectorize)
+	opts->x_flag_tree_loop_vectorize = value;
+      if (!opts_set->x_flag_tree_slp_vectorize)
+	opts->x_flag_tree_slp_vectorize = value;
       if (!opts_set->x_flag_vect_cost_model)
 	opts->x_flag_vect_cost_model = value;
       if (!opts_set->x_flag_tree_loop_distribute_patterns)
@@ -1691,6 +1695,12 @@  common_handle_option (struct gcc_options
         opts->x_flag_ipa_reference = false;
       break;
 
+    case OPT_ftree_vectorize:
+      if (!opts_set->x_flag_tree_loop_vectorize)
+        opts->x_flag_tree_loop_vectorize = value;
+      if (!opts_set->x_flag_tree_slp_vectorize)
+        opts->x_flag_tree_slp_vectorize = value;
+      break;
     case OPT_fshow_column:
       dc->show_column = value;
       break;
Index: tree-if-conv.c
===================================================================
--- tree-if-conv.c	(revision 202540)
+++ tree-if-conv.c	(working copy)
@@ -1789,7 +1789,7 @@  main_tree_if_conversion (void)
   FOR_EACH_LOOP (li, loop, 0)
     if (flag_tree_loop_if_convert == 1
 	|| flag_tree_loop_if_convert_stores == 1
-	|| flag_tree_vectorize
+	|| flag_tree_loop_vectorize
 	|| loop->force_vect)
     changed |= tree_if_conversion (loop);
 
@@ -1815,7 +1815,7 @@  main_tree_if_conversion (void)
 static bool
 gate_tree_if_conversion (void)
 {
-  return (((flag_tree_vectorize || cfun->has_force_vect_loops)
+  return (((flag_tree_loop_vectorize || cfun->has_force_vect_loops)
 	   && flag_tree_loop_if_convert != 0)
 	  || flag_tree_loop_if_convert == 1
 	  || flag_tree_loop_if_convert_stores == 1);
Index: tree-vectorizer.c
===================================================================
--- tree-vectorizer.c	(revision 202540)
+++ tree-vectorizer.c	(working copy)
@@ -341,7 +341,7 @@  vectorize_loops (void)
      than all previously defined loops.  This fact allows us to run
      only over initial loops skipping newly generated ones.  */
   FOR_EACH_LOOP (li, loop, 0)
-    if ((flag_tree_vectorize && optimize_loop_nest_for_speed_p (loop))
+    if ((flag_tree_loop_vectorize && optimize_loop_nest_for_speed_p (loop))
 	|| loop->force_vect)
       {
 	loop_vec_info loop_vinfo;
@@ -486,10 +486,7 @@  execute_vect_slp (void)
 static bool
 gate_vect_slp (void)
 {
-  /* Apply SLP either if the vectorizer is on and the user didn't specify
-     whether to run SLP or not, or if the SLP flag was set by the user.  */
-  return ((flag_tree_vectorize != 0 && flag_tree_slp_vectorize != 0)
-          || flag_tree_slp_vectorize == 1);
+  return flag_tree_slp_vectorize != 0;
 }
 
 namespace {
@@ -579,7 +576,7 @@  increase_alignment (void)
 static bool
 gate_increase_alignment (void)
 {
-  return flag_section_anchors && flag_tree_vectorize;
+  return flag_section_anchors && flag_tree_loop_vectorize;
 }
 
 
Index: tree-ssa-pre.c
===================================================================
--- tree-ssa-pre.c	(revision 202540)
+++ tree-ssa-pre.c	(working copy)
@@ -3026,7 +3026,7 @@  inhibit_phi_insertion (basic_block bb, p
   unsigned i;
 
   /* If we aren't going to vectorize we don't inhibit anything.  */
-  if (!flag_tree_vectorize)
+  if (!flag_tree_loop_vectorize)
     return false;
 
   /* Otherwise we inhibit the insertion when the address of the
Index: cp/lambda.c
===================================================================
--- cp/lambda.c	(revision 202540)
+++ cp/lambda.c	(working copy)
@@ -792,7 +792,7 @@  maybe_add_lambda_conv_op (tree type)
      particular, parameter pack expansions are marked PACK_EXPANSION_LOCAL_P in
      the body CALL, but not in DECLTYPE_CALL.  */
 
-  vec<tree, va_gc> *direct_argvec;
+  vec<tree, va_gc> *direct_argvec = NULL;
   tree decltype_call = 0, call;
   tree fn_result = TREE_TYPE (TREE_TYPE (callop));
 
Index: tree-ssa-loop.c
===================================================================
--- tree-ssa-loop.c	(revision 202540)
+++ tree-ssa-loop.c	(working copy)
@@ -303,7 +303,7 @@  make_pass_predcom (gcc::context *ctxt)
 /* Loop autovectorization.  */
 
 static unsigned int
-tree_vectorize (void)
+tree_loop_vectorize (void)
 {
   if (number_of_loops (cfun) <= 1)
     return 0;
@@ -312,9 +312,9 @@  tree_vectorize (void)
 }
 
 static bool
-gate_tree_vectorize (void)
+gate_tree_loop_vectorize (void)
 {
-  return flag_tree_vectorize || cfun->has_force_vect_loops;
+  return flag_tree_loop_vectorize || cfun->has_force_vect_loops;
 }
 
 namespace {
@@ -342,8 +342,8 @@  public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_vectorize (); }
-  unsigned int execute () { return tree_vectorize (); }
+  bool gate () { return gate_tree_loop_vectorize (); }
+  unsigned int execute () { return tree_loop_vectorize (); }
 
 }; // class pass_vectorize
 
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 202540)
+++ doc/invoke.texi	(working copy)
@@ -419,10 +419,11 @@  Objective-C and Objective-C++ Dialects}.
 -ftree-loop-if-convert-stores -ftree-loop-im @gol
 -ftree-phiprop -ftree-loop-distribution -ftree-loop-distribute-patterns @gol
 -ftree-loop-ivcanon -ftree-loop-linear -ftree-loop-optimize @gol
+-ftree-loop-vectorize @gol
 -ftree-parallelize-loops=@var{n} -ftree-pre -ftree-partial-pre -ftree-pta @gol
 -ftree-reassoc -ftree-sink -ftree-slsr -ftree-sra @gol
--ftree-switch-conversion -ftree-tail-merge @gol
--ftree-ter -ftree-vect-loop-version -ftree-vectorize -ftree-vrp @gol
+-ftree-switch-conversion -ftree-tail-merge -ftree-ter @gol
+-ftree-vect-loop-version -ftree-vectorize -ftree-vrp @gol
 -funit-at-a-time -funroll-all-loops -funroll-loops @gol
 -funsafe-loop-optimizations -funsafe-math-optimizations -funswitch-loops @gol
 -fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol
@@ -6751,8 +6752,8 @@  invoking @option{-O2} on programs that u
 Optimize yet more.  @option{-O3} turns on all optimizations specified
 by @option{-O2} and also turns on the @option{-finline-functions},
 @option{-funswitch-loops}, @option{-fpredictive-commoning},
-@option{-fgcse-after-reload}, @option{-ftree-vectorize},
-@option{-fvect-cost-model},
+@option{-fgcse-after-reload}, @option{-ftree-loop-vectorize},
+@option{-ftree-slp-vectorize}, @option{-fvect-cost-model},
 @option{-ftree-partial-pre} and @option{-fipa-cp-clone} options.
 
 @item -O0
@@ -8011,8 +8012,13 @@  higher.
 
 @item -ftree-vectorize
 @opindex ftree-vectorize
+Perform vectorization on trees. This flag enables @option{-ftree-loop-vectorize}
+and @option{-ftree-slp-vectorize} if neither option is explicitly specified.
+
+@item -ftree-loop-vectorize
+@opindex ftree-loop-vectorize
 Perform loop vectorization on trees. This flag is enabled by default at
-@option{-O3}.
+@option{-O3} and when @option{-ftree-vectorize} is enabled.
 
 @item -ftree-slp-vectorize
 @opindex ftree-slp-vectorize
Index: common.opt
===================================================================
--- common.opt	(revision 202540)
+++ common.opt	(working copy)
@@ -2263,15 +2263,19 @@  Common Report Var(flag_var_tracking_unin
 Perform variable tracking and also tag variables that are uninitialized
 
 ftree-vectorize
-Common Report Var(flag_tree_vectorize) Optimization
-Enable loop vectorization on trees
+Common Report Optimization
+Enable vectorization on trees
 
 ftree-vectorizer-verbose=
 Common RejectNegative Joined UInteger Var(common_deferred_options) Defer
 -ftree-vectorizer-verbose=<number>	This switch is deprecated. Use -fopt-info instead.
 
+ftree-loop-vectorize
+Common Report Var(flag_tree_loop_vectorize) Optimization
+Enable loop vectorization on trees
+
 ftree-slp-vectorize
-Common Report Var(flag_tree_slp_vectorize) Init(2) Optimization
+Common Report Var(flag_tree_slp_vectorize) Optimization
 Enable basic block vectorization (SLP) on trees
 
 fvect-cost-model