https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87355

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Marc Glisse from comment #2)
> For f, this is a classic case where gcc canonicalizes n>=100 as n>99, and
> thus cannot as easily merge it with the other comparison n==100.
> 
> For g, n >= 103 || n == 100 || n == 101 || n == 102 is replaced in the
> front-end with (n > 102 || n == 100) || (unsigned int) n + 4294967195 <= 1,
> that's a bit strange. Merging comparisons into a range test is normal, but
> why merge precisely tests 3 and 4? Inserting || n == 99 before n == 100
> yields the even stranger ((n > 102 || n == 99) || (unsigned int) n +
> 4294967196 <= 1) || n == 102...

We have two places where we perform these range optimizations, in fold-const.c
and in the reassoc pass.  The optimization in fold-const.c is able to merge
just adjacent ranges, so if you sort the comparisons properly in the source
code (either ascending, or descending, but not randomly or intermixed with
checks to other variables), it is optimized, otherwise it isn't.  Looking
through some more nested ||s or &&s like the toplevel operation would be
possible (if all the ||/&& expressions are simple_operand_p_2), but would have
to be with some upper bound, otherwise we run into compile time complexity
problems.
The reassoc pass is more capable here, it gathers all the comparisons at once,
provided there are no other statements in between those and no other side
effects, sorts them according to the variables being compared and ranges for
those.  The reason why it doesn't do anything on this weird testcase is the
nested == THRESHOLD comparison in there, where jump threading in dom2 pass
comes before reassoc1 and threads it first, so reassoc1 doesn't see something
it can optimize anymore.  You can see what you get with -O2
-fno-tree-dominator-opts by disabling the jump threading, then reassoc
optimizes the 3 range tests (the last two adjacent being merged in the FE
already) into one.

Reply via email to