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

Reply via email to