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 <bb 4>; [36.00%] [count: INV] else goto <bb 3>; [64.00%] [count: INV]
<bb 3> [64.00%] [count: INV]: if (_4 != 1) goto <bb 4>; [46.88%] [count: INV] else goto <bb 5>; [53.13%] [count: INV] <bb 4> [66.00%] [count: INV]: c = 0; <bb 5> [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 <ja...@redhat.com> 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.000000000 +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