https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96542
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 CC| |jakub at gcc dot gnu.org Status|UNCONFIRMED |NEW Last reconfirmed| |2020-08-10 --- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- unsigned char foo (unsigned int x) { _Bool y = x; return (((unsigned char) ~0) >> y) * 2; } unsigned char bar (unsigned int x) { return (((unsigned char) ~0) >> (_Bool) x) * 2; } In bar, this is optimized, because fold_binary_op_with_conditional_arg optimizes 255 >> (x ? 1 : 0) into x ? 127 : 255 and when multiplied by two in unsigned char this results in x ? 254 : 254. We don't have anything comparable in match.pd yet I believe (and should we?). Or shall say VRP try harder if it sees [0, 1] ranges? Though, shouldn't we optimize e.g. unsigned baz (unsigned int x) { if (x >= 4) return 32; return (-1U >> x) * 16; } too to return x >= 4 ? 32U : -16U; ? Not sure where and how to generalize it though. Value range of -1U >> [0, 3] is not really useful here, nonzero bits either. And having a specialized (const1 >> x) * const2 optimizer based on x's value range would work, but not sure if it has a real-world benefit.