Re: [PATCH] Improve var_bound range test opt (PR tree-optimization/81655)
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)
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)
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)
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)
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