Re: [PATCH] Improve var_bound range test opt (PR tree-optimization/81655)

2017-08-03 Thread Richard Biener
On Thu, 3 Aug 2017, Jeff Law wrote:

> On 08/03/2017 03:32 AM, Jakub Jelinek wrote:
> > On Thu, Aug 03, 2017 at 10:58:07AM +0200, Richard Biener wrote:
> >>> The reason why we punt is the unexpected _4 != 1 condition, the code
> >>> is prepared to handle just _4 == 0 (or _4 != 0) where _4 == 0 is 
> >>> equivalent
> >>> to _4 != 1 for boolean type.
> >>
> >> Hmm, I thought we had code to canonicalize boolean compares (but I can't 
> >> find that right now).  Some is in 
> > 
> > I was looking for that too, but didn't find anything that would be done
> > always.
> I can recall looking for that kind of canonicalization as well, but not
> finding it.  Furthermore instrumentation showed the different forms
> could show up in the IL, but forms such as != 1 were relatively rare.

We have foldings that canonicalize to some extent but further 
canonicalization requires switching edges which means even if we'd
do that in CFG cleanup it would be delayed until the next such run.

Richard.


Re: [PATCH] Improve var_bound range test opt (PR tree-optimization/81655)

2017-08-03 Thread Jeff Law
On 08/03/2017 03:32 AM, Jakub Jelinek wrote:
> On Thu, Aug 03, 2017 at 10:58:07AM +0200, Richard Biener wrote:
>>> The reason why we punt is the unexpected _4 != 1 condition, the code
>>> is prepared to handle just _4 == 0 (or _4 != 0) where _4 == 0 is equivalent
>>> to _4 != 1 for boolean type.
>>
>> Hmm, I thought we had code to canonicalize boolean compares (but I can't 
>> find that right now).  Some is in 
> 
> I was looking for that too, but didn't find anything that would be done
> always.
I can recall looking for that kind of canonicalization as well, but not
finding it.  Furthermore instrumentation showed the different forms
could show up in the IL, but forms such as != 1 were relatively rare.

Jeff


Re: [PATCH] Improve var_bound range test opt (PR tree-optimization/81655)

2017-08-03 Thread Jakub Jelinek
On Thu, Aug 03, 2017 at 10:58:07AM +0200, Richard Biener wrote:
> > The reason why we punt is the unexpected _4 != 1 condition, the code
> > is prepared to handle just _4 == 0 (or _4 != 0) where _4 == 0 is equivalent
> > to _4 != 1 for boolean type.
> 
> Hmm, I thought we had code to canonicalize boolean compares (but I can't 
> find that right now).  Some is in 

I was looking for that too, but didn't find anything that would be done
always.

> forwprop:forward_propagate_into_gimple_cond where it canonicalizes
> != 1 to == 0.

Yes, but from
Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 by swapping edges.
it seems that it can keep _Bool == 1 around, which is something
optimize_range_tests_var_bound didn't handle before either and now does.

Jakub


Re: [PATCH] Improve var_bound range test opt (PR tree-optimization/81655)

2017-08-03 Thread Richard Biener
On Thu, 3 Aug 2017, Jakub Jelinek wrote:

> Hi!
> 
> For the PR81588 testcase, on targets with branch cost 1, we end up with:
>   b.0_1 = b;
>   _2 = (long long int) b.0_1;
>   a.1_3 = a;
>   _4 = _2 > a.1_3;
>   _5 = (int) _4;
>   if (a.1_3 < 0)
> goto ; [36.00%] [count: INV]
>   else
> goto ; [64.00%] [count: INV]
> 
>[64.00%] [count: INV]:
>   if (_4 != 1)
> goto ; [46.88%] [count: INV]
>   else
> goto ; [53.13%] [count: INV]
> 
>[66.00%] [count: INV]:
>   c = 0;
> 
>[100.00%] [count: INV]:
> The reason why we punt is the unexpected _4 != 1 condition, the code
> is prepared to handle just _4 == 0 (or _4 != 0) where _4 == 0 is equivalent
> to _4 != 1 for boolean type.

Hmm, I thought we had code to canonicalize boolean compares (but I can't 
find that right now).  Some is in 
forwprop:forward_propagate_into_gimple_cond where it canonicalizes
!= 1 to == 0.

> The following patch handles even comparison with 1 if the type is
> unsigned 1-bit precision.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2017-08-03  Jakub Jelinek  
> 
>   PR tree-optimization/81655
>   PR tree-optimization/81588
>   * tree-ssa-reassoc.c (optimize_range_tests_var_bound): Handle also
>   the case when ranges[i].low and high are 1 for unsigned type with
>   precision 1.
> 
> --- gcc/tree-ssa-reassoc.c.jj 2017-08-01 10:28:50.0 +0200
> +++ gcc/tree-ssa-reassoc.c2017-08-02 11:28:44.789134681 +0200
> @@ -2918,11 +2918,22 @@ optimize_range_tests_var_bound (enum tre
>  
>for (i = 0; i < length; i++)
>  {
> +  bool in_p = ranges[i].in_p;
>if (ranges[i].low == NULL_TREE
> -   || ranges[i].high == NULL_TREE
> -   || !integer_zerop (ranges[i].low)
> -   || !integer_zerop (ranges[i].high))
> +   || ranges[i].high == NULL_TREE)
>   continue;
> +  if (!integer_zerop (ranges[i].low)
> +   || !integer_zerop (ranges[i].high))
> + {
> +   if (ranges[i].exp
> +   && TYPE_PRECISION (TREE_TYPE (ranges[i].exp)) == 1
> +   && TYPE_UNSIGNED (TREE_TYPE (ranges[i].exp))
> +   && integer_onep (ranges[i].low)
> +   && integer_onep (ranges[i].high))
> + in_p = !in_p;
> +   else
> + continue;
> + }
>  
>gimple *stmt;
>tree_code ccode;
> @@ -2964,7 +2975,7 @@ optimize_range_tests_var_bound (enum tre
>   default:
> continue;
>   }
> -  if (ranges[i].in_p)
> +  if (in_p)
>   ccode = invert_tree_comparison (ccode, false);
>switch (ccode)
>   {
> 
>   Jakub
> 
> 

-- 
Richard Biener 
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)


[PATCH] Improve var_bound range test opt (PR tree-optimization/81655)

2017-08-03 Thread Jakub Jelinek
Hi!

For the PR81588 testcase, on targets with branch cost 1, we end up with:
  b.0_1 = b;
  _2 = (long long int) b.0_1;
  a.1_3 = a;
  _4 = _2 > a.1_3;
  _5 = (int) _4;
  if (a.1_3 < 0)
goto ; [36.00%] [count: INV]
  else
goto ; [64.00%] [count: INV]

   [64.00%] [count: INV]:
  if (_4 != 1)
goto ; [46.88%] [count: INV]
  else
goto ; [53.13%] [count: INV]

   [66.00%] [count: INV]:
  c = 0;

   [100.00%] [count: INV]:
The reason why we punt is the unexpected _4 != 1 condition, the code
is prepared to handle just _4 == 0 (or _4 != 0) where _4 == 0 is equivalent
to _4 != 1 for boolean type.

The following patch handles even comparison with 1 if the type is
unsigned 1-bit precision.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-08-03  Jakub Jelinek  

PR tree-optimization/81655
PR tree-optimization/81588
* tree-ssa-reassoc.c (optimize_range_tests_var_bound): Handle also
the case when ranges[i].low and high are 1 for unsigned type with
precision 1.

--- gcc/tree-ssa-reassoc.c.jj   2017-08-01 10:28:50.0 +0200
+++ gcc/tree-ssa-reassoc.c  2017-08-02 11:28:44.789134681 +0200
@@ -2918,11 +2918,22 @@ optimize_range_tests_var_bound (enum tre
 
   for (i = 0; i < length; i++)
 {
+  bool in_p = ranges[i].in_p;
   if (ranges[i].low == NULL_TREE
- || ranges[i].high == NULL_TREE
- || !integer_zerop (ranges[i].low)
- || !integer_zerop (ranges[i].high))
+ || ranges[i].high == NULL_TREE)
continue;
+  if (!integer_zerop (ranges[i].low)
+ || !integer_zerop (ranges[i].high))
+   {
+ if (ranges[i].exp
+ && TYPE_PRECISION (TREE_TYPE (ranges[i].exp)) == 1
+ && TYPE_UNSIGNED (TREE_TYPE (ranges[i].exp))
+ && integer_onep (ranges[i].low)
+ && integer_onep (ranges[i].high))
+   in_p = !in_p;
+ else
+   continue;
+   }
 
   gimple *stmt;
   tree_code ccode;
@@ -2964,7 +2975,7 @@ optimize_range_tests_var_bound (enum tre
default:
  continue;
}
-  if (ranges[i].in_p)
+  if (in_p)
ccode = invert_tree_comparison (ccode, false);
   switch (ccode)
{

Jakub