Improve code generated for a switch statement

Bug #645267 reported by Andrew Stubbs
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Linaro GCC
Confirmed
Low
Unassigned

Bug Description

Consider:

unsigned int
f (unsigned int a)
{
  switch (a)
    {
    case 32:
    case 13:
    case 10:
    case 9:
      return 0;
    default:
      return a;
    }
}

"arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb O2 -S kazu.c" generates

        sub r3, r0, #9
        cmp r3, #23
        bhi .L2
        movs r1, #1
        lsls r2, r1, r3
        movw r1, #:lower16:8388627
        movt r1, #:upper16:8388627
        and r3, r2, r1
        cmp r3, #0
        it ne
        movne r0, #0
.L2:
        bx lr

which is equivalent to:

  a -= 9;
  if (a > 23)
    return a;
  if (0x800013 & (1 << a))
    return 0;
  return a;

We can improve this sequence by shifting the magic constant to left
and test the sign bit like so:

  a -= 9;
  if (a > 23)
    return a;
  if (((signed int) 0xc8000100 << a) < 0)
    return 0;
  return a;

The assembly would be:

        sub r3, r0, #9
        cmp r3, #23
        bhi .L2
        movw r2, #:lower16:-939523840
        movt r2, #:upper16:-939523840
        lsls r2, r2, r3
        it mi
        movmi r0, #0
.L2:
        bx lr

Note that the "and" and "cmp r3,#0" have disappeared.

[CodeSourcery Tracker ID #7899]

Michael Hope (michaelh1)
tags: added: speed task
Changed in gcc-linaro:
status: New → Triaged
importance: Undecided → Low
Changed in gcc-linaro:
status: Triaged → Won't Fix
Changed in gcc-linaro:
status: Won't Fix → Confirmed
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.