https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108360
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Seems it happens even with short b; static short c; unsigned char e; char f; void foo(); short(a)(short h, short i) { return h + i; } static short(d)(short h, int i) { return (h >= 32 || h > (7 >> i)) ? h : h << i; } unsigned g(short h, short i) { return h + i; } int main() { short j, k = -1; c = a(0 >= b, k); f = c <= 0xD315BEF1; e = f << 4; j = d(e, 5); if (3 >= g(j == b, k)) foo(); b = 32; } where we can't assume anything about b's value initially. Still in GCC 12 we decide to thread jump it based on whether e (h in inlined d) is 0 or non-0 - h >= 32 is based on ranges clearly always false and as e has [0, 16] range, h > 0 and h != 0 are the same thing, if h != 0, then d returns h, otherwise h << 5. Later on we correctly figure out that if h == 0, then h << 5 is 0. But what I really don't understand how threadfull1 in that case decided that foo will not be called.