http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52412

             Bug #: 52412
           Summary: another unnecessary register move on arm
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: car...@google.com
            Target: arm-linux-gnueabi


Compile following code with options -march=armv7-a -mthumb -Os

extern int Table[256];
typedef struct {
      char* f0;
      int f1;
      int f2;
      char f3[256];
      int f4;
   } S;

void t0m(S* s)
{
   int i;
   char ch = (char)(s->f1);
   for (i = 0; i < 10 ; i++)
      s->f4 =  Table[s->f4 ^ ch];
   s->f3[s->f1] = 1;
   switch (s->f2) {
      case 1:
         *s->f0 = ch;
         break;
      case 2:
         *s->f0 = ch;
         break;
   }
}

ARM gcc 4.7 generates:


t0m:
    ldr    r1, [r0, #4]
    movs    r2, #10
    push    {r4, r5, r6, lr}
    uxtb    r3, r1
    ldr    r5, .L7
    mov    r6, r3                // A
.L2:
    ldr    r4, [r0, #268]
    subs    r2, r2, #1
    eor    r4, r6, r4
    ldr    r4, [r5, r4, lsl #2]
    str    r4, [r0, #268]
    bne    .L2
    adds    r1, r0, r1
    movs    r2, #1
    strb    r2, [r1, #12]
    ldr    r2, [r0, #8]
    cmp    r2, #1
    beq    .L5
    cmp    r2, #2
    bne    .L1
.L5:
    ldr    r2, [r0, #0]
    strb    r3, [r2, #0]
.L1:
    pop    {r4, r5, r6, pc}
.L8:
    .align    2
.L7:
    .word    Table

Instruction A moves register r3 to r6, but both r3 and r6 are read only in
following code, so any one is enough for following usage.

Compile it to arm mode instructions has the same problem.

Reply via email to