https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86011

            Bug ID: 86011
           Summary: Inefficient code generated for ldivmod with constant
                    value
           Product: gcc
           Version: 7.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: patrick at motec dot com.au
  Target Milestone: ---

Tested with 7.2.0 and 8.1.0.

The following example unnecessarily calls ldivmod twice:

struct foo { long a, b; };
struct foo test(long long x)
{
        return (struct foo){x / 77, x % 77};
}

armv7m-linux-musleabi-gcc -c -O2 test.c
armv7m-linux-musleabi-objdump -d test.o

00000000 <test>:
   0:   b5d0            push    {r4, r6, r7, lr}
   2:   4616            mov     r6, r2
   4:   461f            mov     r7, r3
   6:   4604            mov     r4, r0
   8:   224d            movs    r2, #77 ; 0x4d
   a:   2300            movs    r3, #0
   c:   4630            mov     r0, r6
   e:   4639            mov     r1, r7
  10:   f7ff fffe       bl      0 <__aeabi_ldivmod>
  14:   4639            mov     r1, r7
  16:   6020            str     r0, [r4, #0]
  18:   224d            movs    r2, #77 ; 0x4d
  1a:   4630            mov     r0, r6
  1c:   2300            movs    r3, #0
  1e:   f7ff fffe       bl      0 <__aeabi_ldivmod>
  22:   4620            mov     r0, r4
  24:   6062            str     r2, [r4, #4]
  26:   bdd0            pop     {r4, r6, r7, pc}

If the test is rearranged so that the denominator is a function argument the
generated code is as expected:

struct foo { long a, b; };
struct foo test(long long x, long den)
{
        return (struct foo){x / den, x % den};
}

armv7m-linux-musleabi-gcc -c -O2 test.c
armv7m-linux-musleabi-objdump -d test.o

00000000 <test>:
   0:   b5d0            push    {r4, r6, r7, lr}
   2:   4616            mov     r6, r2
   4:   461f            mov     r7, r3
   6:   9a04            ldr     r2, [sp, #16]
   8:   4604            mov     r4, r0
   a:   4639            mov     r1, r7
   c:   4630            mov     r0, r6
   e:   17d3            asrs    r3, r2, #31
  10:   f7ff fffe       bl      0 <__aeabi_ldivmod>
  14:   e9c4 0200       strd    r0, r2, [r4]
  18:   4620            mov     r0, r4
  1a:   bdd0            pop     {r4, r6, r7, pc}

Reply via email to