https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103815
Bug ID: 103815 Summary: Misoptimization of a bounded do/while loop Product: gcc Version: og10 (devel/omp/gcc-10) Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: matthias at urlichs dot de Target Milestone: --- This code, which calculates an integer square root ..: #include <inttypes.h> uint16_t int_sqrt32(uint32_t x) { uint16_t res=0; uint16_t add= 0x8000; do { uint16_t temp=res | add; uint32_t g2=temp*temp; if (x>=g2) res=temp; add>>=1; } while(add); return res; } ... should be compileable 1:1, since the right shift sets the condition flags appropriately. Unfortunately, GCC's optimizer notices that this is a 16-step loop, "helpfully" invents a loop counter, and pessimizes the code to this sub-optimal result (ARM Thumb output; x86 has essentially the same problem): 0: b500 push {lr} 2: 2110 movs r1, #16 4: 4686 mov lr, r0 6: f44f 4200 mov.w r2, #32768 ; 0x8000 a: 2000 movs r0, #0 c: ea40 0302 orr.w r3, r0, r2 10: 0852 lsrs r2, r2, #1 12: b29b uxth r3, r3 14: fb03 fc03 mul.w ip, r3, r3 18: 45f4 cmp ip, lr 1a: bf98 it ls 1c: 4618 movls r0, r3 1e: 3901 subs r1, #1 20: d1f4 bne.n c <int_sqrt32+0xc> 22: f85d fb04 ldr.w pc, [sp], #4