https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121344
--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> --- (In reply to Krister Walfridsson from comment #4) > Hmm. The discussion in 111280 says it cannot create new basic blocks, but > the compiler is correctly creating a new basic block for the function in > this PR when compiled with -O1, -O2, and -O3. So why is -Os different? It is not generating a new BB at -O1/-O2/-O3; before coming into SCCP the IR looks like: ``` <bb 2> [local count: 118111600]: if (b_3(D) != 0) goto <bb 5>; [89.00%] else goto <bb 7>; [11.00%] <bb 5> [local count: 105119324]: <bb 3> [local count: 955630224]: # b_9 = PHI <b_5(6), b_3(D)(5)> # c_10 = PHI <c_6(6), 0(5)> b_5 = b_9 >> 1; c_6 = c_10 + 1; if (b_5 != 0) goto <bb 6>; [89.00%] else goto <bb 8>; [11.00%] <bb 8> [local count: 105119324]: # c_2 = PHI <c_6(3)> goto <bb 4>; [100.00%] ``` So the check for `b!=0` was there beforehand due to copying of the loop header and changing it from a while(){} loop into a do{}while(); loop. In the other one the count is an increment of the CLZ by 1 and already in a do while loop form. You run also into the same issue at -O1/-O2/-O3 with: ``` int foo (unsigned long long b) { int c = 0; do { b >>= 1; c++; }while (b); return c-1; } ```