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.