Re: [PATCH GCC8][31/33]Set range information for niter bound of vectorized loop

2017-06-07 Thread Bin.Cheng
On Wed, May 24, 2017 at 2:48 PM, Richard Biener
 wrote:
> On Mon, May 22, 2017 at 7:13 PM, Bin.Cheng  wrote:
>> On Fri, May 19, 2017 at 1:51 PM, Richard Biener
>>  wrote:
>>> On Mon, May 15, 2017 at 5:58 PM, Bin.Cheng  wrote:
 On Thu, May 11, 2017 at 12:02 PM, Richard Biener
  wrote:
> On Tue, Apr 18, 2017 at 12:54 PM, Bin Cheng  wrote
>> Hi,
>> Based on vect_peeling algorithm, we know for sure that vectorized loop 
>> must iterates at least once.
>> This patch sets range information for niter bounds of vectorized loop.  
>> This helps niter analysis,
>> so iv elimination too.
>> Is it OK?
>
>niters_vector = force_gimple_operand (niters_vector, , true, 
> var);
>gsi_insert_seq_on_edge_immediate (pe, stmts);
> +  /* Peeling algorithm guarantees that vector loop bound is at least 
> ONE,
> +we set range information to make niters analyzer's life easier.  
> */
> +  if (TREE_CODE (niters_vector) == SSA_NAME)
> +   set_range_info (niters_vector, VR_RANGE, build_int_cst (type, 1),
> +   fold_build2 (RSHIFT_EXPR, type,
> +TYPE_MAX_VALUE (type), log_vf));
>
> if all of niters_vector folds to an original SSA name then
> niters_vector after gimplification
> is not a new SSA name and thus you can't set range-info on it.
>
> Likewise for the other case where LOOP_VINFO_NITERS is just an SSA name.
 Hi,
 This is updated patch.  It checks whether the result ssa name is newly
 created tmp and only sets range information if so.

 Is it OK?
>>>
>>> A better way to check whether the SSA name is new is to see if 'stmts'
>>> filled by force_gimple_operand is non-empty.
>> Hi,
>> Here is updated patch checking empty gimple_seq.  Is it OK?
>
> Ok.  As a bonus you could have used wide-ints to feed set_range_info
> (not sure if wide_int_ref & allows you to pass '1' literally...)
Patch applied @r248958.  Being lazy not using wide_int here, I will
pick up this after current work.

Thanks,
bin
>
> Richard.
>
>> Thanks,
>> bin
>>>
>>> Richard.
>>>
 Thanks,
 bin

 2017-04-11  Bin Cheng  

 * tree-vectorizer.h (vect_build_loop_niters): New parameter.
 * tree-vect-loop-manip.c (vect_build_loop_niters): New parameter.
 Set true to new parameter if new ssa variable is defined.
 (vect_gen_vector_loop_niters): Refactor.  Set range information
 for the new vector loop bound variable.
 (vect_do_peeling): Ditto.

>
> Richard.
>
>> Thanks,
>> bin
>> 2017-04-11  Bin Cheng  
>>
>> * tree-vect-loop-manip.c (vect_gen_vector_loop_niters): Refactor.
>> Set range information for vector loop bound variable.
>> (vect_do_peeling): Ditto.


Re: [PATCH GCC8][31/33]Set range information for niter bound of vectorized loop

2017-05-24 Thread Richard Biener
On Mon, May 22, 2017 at 7:13 PM, Bin.Cheng  wrote:
> On Fri, May 19, 2017 at 1:51 PM, Richard Biener
>  wrote:
>> On Mon, May 15, 2017 at 5:58 PM, Bin.Cheng  wrote:
>>> On Thu, May 11, 2017 at 12:02 PM, Richard Biener
>>>  wrote:
 On Tue, Apr 18, 2017 at 12:54 PM, Bin Cheng  wrote
> Hi,
> Based on vect_peeling algorithm, we know for sure that vectorized loop 
> must iterates at least once.
> This patch sets range information for niter bounds of vectorized loop.  
> This helps niter analysis,
> so iv elimination too.
> Is it OK?

niters_vector = force_gimple_operand (niters_vector, , true, 
 var);
gsi_insert_seq_on_edge_immediate (pe, stmts);
 +  /* Peeling algorithm guarantees that vector loop bound is at least 
 ONE,
 +we set range information to make niters analyzer's life easier.  
 */
 +  if (TREE_CODE (niters_vector) == SSA_NAME)
 +   set_range_info (niters_vector, VR_RANGE, build_int_cst (type, 1),
 +   fold_build2 (RSHIFT_EXPR, type,
 +TYPE_MAX_VALUE (type), log_vf));

 if all of niters_vector folds to an original SSA name then
 niters_vector after gimplification
 is not a new SSA name and thus you can't set range-info on it.

 Likewise for the other case where LOOP_VINFO_NITERS is just an SSA name.
>>> Hi,
>>> This is updated patch.  It checks whether the result ssa name is newly
>>> created tmp and only sets range information if so.
>>>
>>> Is it OK?
>>
>> A better way to check whether the SSA name is new is to see if 'stmts'
>> filled by force_gimple_operand is non-empty.
> Hi,
> Here is updated patch checking empty gimple_seq.  Is it OK?

Ok.  As a bonus you could have used wide-ints to feed set_range_info
(not sure if wide_int_ref & allows you to pass '1' literally...)

Richard.

> Thanks,
> bin
>>
>> Richard.
>>
>>> Thanks,
>>> bin
>>>
>>> 2017-04-11  Bin Cheng  
>>>
>>> * tree-vectorizer.h (vect_build_loop_niters): New parameter.
>>> * tree-vect-loop-manip.c (vect_build_loop_niters): New parameter.
>>> Set true to new parameter if new ssa variable is defined.
>>> (vect_gen_vector_loop_niters): Refactor.  Set range information
>>> for the new vector loop bound variable.
>>> (vect_do_peeling): Ditto.
>>>

 Richard.

> Thanks,
> bin
> 2017-04-11  Bin Cheng  
>
> * tree-vect-loop-manip.c (vect_gen_vector_loop_niters): Refactor.
> Set range information for vector loop bound variable.
> (vect_do_peeling): Ditto.


Re: [PATCH GCC8][31/33]Set range information for niter bound of vectorized loop

2017-05-22 Thread Bin.Cheng
On Fri, May 19, 2017 at 1:51 PM, Richard Biener
 wrote:
> On Mon, May 15, 2017 at 5:58 PM, Bin.Cheng  wrote:
>> On Thu, May 11, 2017 at 12:02 PM, Richard Biener
>>  wrote:
>>> On Tue, Apr 18, 2017 at 12:54 PM, Bin Cheng  wrote
 Hi,
 Based on vect_peeling algorithm, we know for sure that vectorized loop 
 must iterates at least once.
 This patch sets range information for niter bounds of vectorized loop.  
 This helps niter analysis,
 so iv elimination too.
 Is it OK?
>>>
>>>niters_vector = force_gimple_operand (niters_vector, , true, 
>>> var);
>>>gsi_insert_seq_on_edge_immediate (pe, stmts);
>>> +  /* Peeling algorithm guarantees that vector loop bound is at least 
>>> ONE,
>>> +we set range information to make niters analyzer's life easier.  */
>>> +  if (TREE_CODE (niters_vector) == SSA_NAME)
>>> +   set_range_info (niters_vector, VR_RANGE, build_int_cst (type, 1),
>>> +   fold_build2 (RSHIFT_EXPR, type,
>>> +TYPE_MAX_VALUE (type), log_vf));
>>>
>>> if all of niters_vector folds to an original SSA name then
>>> niters_vector after gimplification
>>> is not a new SSA name and thus you can't set range-info on it.
>>>
>>> Likewise for the other case where LOOP_VINFO_NITERS is just an SSA name.
>> Hi,
>> This is updated patch.  It checks whether the result ssa name is newly
>> created tmp and only sets range information if so.
>>
>> Is it OK?
>
> A better way to check whether the SSA name is new is to see if 'stmts'
> filled by force_gimple_operand is non-empty.
Hi,
Here is updated patch checking empty gimple_seq.  Is it OK?

Thanks,
bin
>
> Richard.
>
>> Thanks,
>> bin
>>
>> 2017-04-11  Bin Cheng  
>>
>> * tree-vectorizer.h (vect_build_loop_niters): New parameter.
>> * tree-vect-loop-manip.c (vect_build_loop_niters): New parameter.
>> Set true to new parameter if new ssa variable is defined.
>> (vect_gen_vector_loop_niters): Refactor.  Set range information
>> for the new vector loop bound variable.
>> (vect_do_peeling): Ditto.
>>
>>>
>>> Richard.
>>>
 Thanks,
 bin
 2017-04-11  Bin Cheng  

 * tree-vect-loop-manip.c (vect_gen_vector_loop_niters): Refactor.
 Set range information for vector loop bound variable.
 (vect_do_peeling): Ditto.
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index f48336b..93c1542 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -1095,10 +1095,11 @@ vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters)
 
 
 /* This function builds ni_name = number of iterations.  Statements
-   are emitted on the loop preheader edge.  */
+   are emitted on the loop preheader edge.  If NEW_VAR_P is not NULL, set
+   it to TRUE if new ssa_var is generated.  */
 
 tree
-vect_build_loop_niters (loop_vec_info loop_vinfo)
+vect_build_loop_niters (loop_vec_info loop_vinfo, bool *new_var_p)
 {
   tree ni = unshare_expr (LOOP_VINFO_NITERS (loop_vinfo));
   if (TREE_CODE (ni) == INTEGER_CST)
@@ -1112,7 +1113,11 @@ vect_build_loop_niters (loop_vec_info loop_vinfo)
   var = create_tmp_var (TREE_TYPE (ni), "niters");
   ni_name = force_gimple_operand (ni, , false, var);
   if (stmts)
-	gsi_insert_seq_on_edge_immediate (pe, stmts);
+	{
+	  gsi_insert_seq_on_edge_immediate (pe, stmts);
+	  if (new_var_p != NULL)
+	*new_var_p = true;
+	}
 
   return ni_name;
 }
@@ -1177,22 +1182,21 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters,
 			 tree *niters_vector_ptr, bool niters_no_overflow)
 {
   tree ni_minus_gap, var;
-  tree niters_vector;
+  tree niters_vector, type = TREE_TYPE (niters);
   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
   edge pe = loop_preheader_edge (LOOP_VINFO_LOOP (loop_vinfo));
-  tree log_vf = build_int_cst (TREE_TYPE (niters), exact_log2 (vf));
+  tree log_vf = build_int_cst (type, exact_log2 (vf));
 
   /* If epilogue loop is required because of data accesses with gaps, we
  subtract one iteration from the total number of iterations here for
  correct calculation of RATIO.  */
   if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo))
 {
-  ni_minus_gap = fold_build2 (MINUS_EXPR, TREE_TYPE (niters),
-  niters,
-  build_one_cst (TREE_TYPE (niters)));
+  ni_minus_gap = fold_build2 (MINUS_EXPR, type, niters,
+  build_one_cst (type));
   if (!is_gimple_val (ni_minus_gap))
 	{
-	  var = create_tmp_var (TREE_TYPE (niters), "ni_gap");
+	  var = create_tmp_var (type, "ni_gap");
 	  gimple *stmts = NULL;
 	  ni_minus_gap = force_gimple_operand (ni_minus_gap, ,
 	   true, var);
@@ -1208,25 +1212,28 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters,
  (niters - vf) >> log2(vf) + 1 by using the fact that we know 

Re: [PATCH GCC8][31/33]Set range information for niter bound of vectorized loop

2017-05-19 Thread Richard Biener
On Mon, May 15, 2017 at 5:58 PM, Bin.Cheng  wrote:
> On Thu, May 11, 2017 at 12:02 PM, Richard Biener
>  wrote:
>> On Tue, Apr 18, 2017 at 12:54 PM, Bin Cheng  wrote
>>> Hi,
>>> Based on vect_peeling algorithm, we know for sure that vectorized loop must 
>>> iterates at least once.
>>> This patch sets range information for niter bounds of vectorized loop.  
>>> This helps niter analysis,
>>> so iv elimination too.
>>> Is it OK?
>>
>>niters_vector = force_gimple_operand (niters_vector, , true, 
>> var);
>>gsi_insert_seq_on_edge_immediate (pe, stmts);
>> +  /* Peeling algorithm guarantees that vector loop bound is at least 
>> ONE,
>> +we set range information to make niters analyzer's life easier.  */
>> +  if (TREE_CODE (niters_vector) == SSA_NAME)
>> +   set_range_info (niters_vector, VR_RANGE, build_int_cst (type, 1),
>> +   fold_build2 (RSHIFT_EXPR, type,
>> +TYPE_MAX_VALUE (type), log_vf));
>>
>> if all of niters_vector folds to an original SSA name then
>> niters_vector after gimplification
>> is not a new SSA name and thus you can't set range-info on it.
>>
>> Likewise for the other case where LOOP_VINFO_NITERS is just an SSA name.
> Hi,
> This is updated patch.  It checks whether the result ssa name is newly
> created tmp and only sets range information if so.
>
> Is it OK?

A better way to check whether the SSA name is new is to see if 'stmts'
filled by force_gimple_operand is non-empty.

Richard.

> Thanks,
> bin
>
> 2017-04-11  Bin Cheng  
>
> * tree-vectorizer.h (vect_build_loop_niters): New parameter.
> * tree-vect-loop-manip.c (vect_build_loop_niters): New parameter.
> Set true to new parameter if new ssa variable is defined.
> (vect_gen_vector_loop_niters): Refactor.  Set range information
> for the new vector loop bound variable.
> (vect_do_peeling): Ditto.
>
>>
>> Richard.
>>
>>> Thanks,
>>> bin
>>> 2017-04-11  Bin Cheng  
>>>
>>> * tree-vect-loop-manip.c (vect_gen_vector_loop_niters): Refactor.
>>> Set range information for vector loop bound variable.
>>> (vect_do_peeling): Ditto.


Re: [PATCH GCC8][31/33]Set range information for niter bound of vectorized loop

2017-05-15 Thread Bin.Cheng
On Thu, May 11, 2017 at 12:02 PM, Richard Biener
 wrote:
> On Tue, Apr 18, 2017 at 12:54 PM, Bin Cheng  wrote
>> Hi,
>> Based on vect_peeling algorithm, we know for sure that vectorized loop must 
>> iterates at least once.
>> This patch sets range information for niter bounds of vectorized loop.  This 
>> helps niter analysis,
>> so iv elimination too.
>> Is it OK?
>
>niters_vector = force_gimple_operand (niters_vector, , true, 
> var);
>gsi_insert_seq_on_edge_immediate (pe, stmts);
> +  /* Peeling algorithm guarantees that vector loop bound is at least ONE,
> +we set range information to make niters analyzer's life easier.  */
> +  if (TREE_CODE (niters_vector) == SSA_NAME)
> +   set_range_info (niters_vector, VR_RANGE, build_int_cst (type, 1),
> +   fold_build2 (RSHIFT_EXPR, type,
> +TYPE_MAX_VALUE (type), log_vf));
>
> if all of niters_vector folds to an original SSA name then
> niters_vector after gimplification
> is not a new SSA name and thus you can't set range-info on it.
>
> Likewise for the other case where LOOP_VINFO_NITERS is just an SSA name.
Hi,
This is updated patch.  It checks whether the result ssa name is newly
created tmp and only sets range information if so.

Is it OK?

Thanks,
bin

2017-04-11  Bin Cheng  

* tree-vectorizer.h (vect_build_loop_niters): New parameter.
* tree-vect-loop-manip.c (vect_build_loop_niters): New parameter.
Set true to new parameter if new ssa variable is defined.
(vect_gen_vector_loop_niters): Refactor.  Set range information
for the new vector loop bound variable.
(vect_do_peeling): Ditto.

>
> Richard.
>
>> Thanks,
>> bin
>> 2017-04-11  Bin Cheng  
>>
>> * tree-vect-loop-manip.c (vect_gen_vector_loop_niters): Refactor.
>> Set range information for vector loop bound variable.
>> (vect_do_peeling): Ditto.
From fbf6867a1f8d8fed94ce53861ccefb0d704e9f96 Mon Sep 17 00:00:00 2001
From: Bin Cheng 
Date: Thu, 11 May 2017 17:26:57 +0100
Subject: [PATCH 5/9] range_info-for-vect_loop-niters-20170225.txt

---
 gcc/tree-vect-loop-manip.c | 52 +-
 gcc/tree-vectorizer.h  |  2 +-
 2 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index f48336b..52cd2bb 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -1095,10 +1095,11 @@ vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters)
 
 
 /* This function builds ni_name = number of iterations.  Statements
-   are emitted on the loop preheader edge.  */
+   are emitted on the loop preheader edge.  If NEW_VAR_P is not NULL, set
+   it to TRUE if new ssa_var is generated.  */
 
 tree
-vect_build_loop_niters (loop_vec_info loop_vinfo)
+vect_build_loop_niters (loop_vec_info loop_vinfo, bool *new_var_p)
 {
   tree ni = unshare_expr (LOOP_VINFO_NITERS (loop_vinfo));
   if (TREE_CODE (ni) == INTEGER_CST)
@@ -1114,6 +1115,10 @@ vect_build_loop_niters (loop_vec_info loop_vinfo)
   if (stmts)
 	gsi_insert_seq_on_edge_immediate (pe, stmts);
 
+  if (new_var_p != NULL)
+	*new_var_p = (TREE_CODE (ni_name) == SSA_NAME
+		  && SSA_NAME_VAR (ni_name) == var);
+
   return ni_name;
 }
 }
@@ -1177,22 +1182,21 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters,
 			 tree *niters_vector_ptr, bool niters_no_overflow)
 {
   tree ni_minus_gap, var;
-  tree niters_vector;
+  tree niters_vector, type = TREE_TYPE (niters);
   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
   edge pe = loop_preheader_edge (LOOP_VINFO_LOOP (loop_vinfo));
-  tree log_vf = build_int_cst (TREE_TYPE (niters), exact_log2 (vf));
+  tree log_vf = build_int_cst (type, exact_log2 (vf));
 
   /* If epilogue loop is required because of data accesses with gaps, we
  subtract one iteration from the total number of iterations here for
  correct calculation of RATIO.  */
   if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo))
 {
-  ni_minus_gap = fold_build2 (MINUS_EXPR, TREE_TYPE (niters),
-  niters,
-  build_one_cst (TREE_TYPE (niters)));
+  ni_minus_gap = fold_build2 (MINUS_EXPR, type, niters,
+  build_one_cst (type));
   if (!is_gimple_val (ni_minus_gap))
 	{
-	  var = create_tmp_var (TREE_TYPE (niters), "ni_gap");
+	  var = create_tmp_var (type, "ni_gap");
 	  gimple *stmts = NULL;
 	  ni_minus_gap = force_gimple_operand (ni_minus_gap, ,
 	   true, var);
@@ -1208,25 +1212,29 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters,
  (niters - vf) >> log2(vf) + 1 by using the fact that we know ratio
  will be at least one.  */
   if (niters_no_overflow)
-niters_vector = fold_build2 (RSHIFT_EXPR, TREE_TYPE (niters),
- ni_minus_gap, log_vf);
+niters_vector = 

Re: [PATCH GCC8][31/33]Set range information for niter bound of vectorized loop

2017-05-11 Thread Richard Biener
On Tue, Apr 18, 2017 at 12:54 PM, Bin Cheng  wrote
> Hi,
> Based on vect_peeling algorithm, we know for sure that vectorized loop must 
> iterates at least once.
> This patch sets range information for niter bounds of vectorized loop.  This 
> helps niter analysis,
> so iv elimination too.
> Is it OK?

   niters_vector = force_gimple_operand (niters_vector, , true, var);
   gsi_insert_seq_on_edge_immediate (pe, stmts);
+  /* Peeling algorithm guarantees that vector loop bound is at least ONE,
+we set range information to make niters analyzer's life easier.  */
+  if (TREE_CODE (niters_vector) == SSA_NAME)
+   set_range_info (niters_vector, VR_RANGE, build_int_cst (type, 1),
+   fold_build2 (RSHIFT_EXPR, type,
+TYPE_MAX_VALUE (type), log_vf));

if all of niters_vector folds to an original SSA name then
niters_vector after gimplification
is not a new SSA name and thus you can't set range-info on it.

Likewise for the other case where LOOP_VINFO_NITERS is just an SSA name.

Richard.

> Thanks,
> bin
> 2017-04-11  Bin Cheng  
>
> * tree-vect-loop-manip.c (vect_gen_vector_loop_niters): Refactor.
> Set range information for vector loop bound variable.
> (vect_do_peeling): Ditto.


[PATCH GCC8][31/33]Set range information for niter bound of vectorized loop

2017-04-18 Thread Bin Cheng
Hi,
Based on vect_peeling algorithm, we know for sure that vectorized loop must 
iterates at least once.
This patch sets range information for niter bounds of vectorized loop.  This 
helps niter analysis,
so iv elimination too.
Is it OK?

Thanks,
bin
2017-04-11  Bin Cheng  

* tree-vect-loop-manip.c (vect_gen_vector_loop_niters): Refactor.
Set range information for vector loop bound variable.
(vect_do_peeling): Ditto.From 0962735526bf474591e410104d6c9576691e0a1f Mon Sep 17 00:00:00 2001
From: Bin Cheng 
Date: Tue, 14 Mar 2017 17:46:55 +
Subject: [PATCH 31/33] range_info-for-vect_loop-niters-20170224.txt

---
 gcc/tree-vect-loop-manip.c | 39 +++
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index faeaa6d..0fc8cd3 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -1177,22 +1177,21 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, 
tree niters,
 tree *niters_vector_ptr, bool niters_no_overflow)
 {
   tree ni_minus_gap, var;
-  tree niters_vector;
+  tree niters_vector, type = TREE_TYPE (niters);
   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
   edge pe = loop_preheader_edge (LOOP_VINFO_LOOP (loop_vinfo));
-  tree log_vf = build_int_cst (TREE_TYPE (niters), exact_log2 (vf));
+  tree log_vf = build_int_cst (type, exact_log2 (vf));
 
   /* If epilogue loop is required because of data accesses with gaps, we
  subtract one iteration from the total number of iterations here for
  correct calculation of RATIO.  */
   if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo))
 {
-  ni_minus_gap = fold_build2 (MINUS_EXPR, TREE_TYPE (niters),
- niters,
- build_one_cst (TREE_TYPE (niters)));
+  ni_minus_gap = fold_build2 (MINUS_EXPR, type, niters,
+ build_one_cst (type));
   if (!is_gimple_val (ni_minus_gap))
{
- var = create_tmp_var (TREE_TYPE (niters), "ni_gap");
+ var = create_tmp_var (type, "ni_gap");
  gimple *stmts = NULL;
  ni_minus_gap = force_gimple_operand (ni_minus_gap, ,
   true, var);
@@ -1208,25 +1207,28 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, 
tree niters,
  (niters - vf) >> log2(vf) + 1 by using the fact that we know ratio
  will be at least one.  */
   if (niters_no_overflow)
-niters_vector = fold_build2 (RSHIFT_EXPR, TREE_TYPE (niters),
-ni_minus_gap, log_vf);
+niters_vector = fold_build2 (RSHIFT_EXPR, type, ni_minus_gap, log_vf);
   else
 niters_vector
-  = fold_build2 (PLUS_EXPR, TREE_TYPE (niters),
-fold_build2 (RSHIFT_EXPR, TREE_TYPE (niters),
- fold_build2 (MINUS_EXPR, TREE_TYPE (niters),
-  ni_minus_gap,
-  build_int_cst
-(TREE_TYPE (niters), vf)),
+  = fold_build2 (PLUS_EXPR, type,
+fold_build2 (RSHIFT_EXPR, type,
+ fold_build2 (MINUS_EXPR, type, ni_minus_gap,
+  build_int_cst (type, vf)),
  log_vf),
-build_int_cst (TREE_TYPE (niters), 1));
+build_int_cst (type, 1));
 
   if (!is_gimple_val (niters_vector))
 {
-  var = create_tmp_var (TREE_TYPE (niters), "bnd");
+  var = create_tmp_var (type, "bnd");
   gimple *stmts = NULL;
   niters_vector = force_gimple_operand (niters_vector, , true, var);
   gsi_insert_seq_on_edge_immediate (pe, stmts);
+  /* Peeling algorithm guarantees that vector loop bound is at least ONE,
+we set range information to make niters analyzer's life easier.  */
+  if (TREE_CODE (niters_vector) == SSA_NAME)
+   set_range_info (niters_vector, VR_RANGE, build_int_cst (type, 1),
+   fold_build2 (RSHIFT_EXPR, type,
+TYPE_MAX_VALUE (type), log_vf));
 }
   *niters_vector_ptr = niters_vector;
 
@@ -1773,6 +1775,11 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, 
tree nitersm1,
= fold_build2 (MINUS_EXPR, type,
   LOOP_VINFO_NITERSM1 (loop_vinfo), niters_prolog);
   niters = vect_build_loop_niters (loop_vinfo);
+  /* It's guaranteed that vector loop bound before vectorization is at
+least VF, so set range information.  */
+  if (TREE_CODE (niters) == SSA_NAME)
+   set_range_info (niters, VR_RANGE,
+   build_int_cst (type, vf), TYPE_MAX_VALUE (type));
 
   /* Prolog iterates at most bound_prolog times, latch iterates at