The code generated for "switch (n & 7)" which has all possible cases (0-7)
includes a redundant range check.

To illustrate, this source code:

void foo(unsigned int *d, const unsigned int *s, unsigned int n)
{
    switch (n & 7) {
      case 7:
        d[7] = s[7];
        break;
      case 6:
        d[6] = s[6];
        break;
      case 5:
        d[5] = s[5];
        break;
      case 4:
        d[4] = s[4];
        break;
      case 3:
        d[3] = s[3];
        break;
      case 2:
        d[2] = s[2];
        break;
      case 1:
        d[1] = s[1];
        break;
      case 0:
        d[0] = s[0];
        break;
    }
}

compiles (gcc-4.2.3 -O2 -fomit-frame-pointer -S) to:

        .text
        .p2align 4,,15
.globl foo
        .type   foo, @function
foo:
        movl    12(%esp), %eax
        andl    $7, %eax
        cmpl    $7, %eax
        ja      .L12
        jmp     *.L11(,%eax,4)
        .section        .rodata
        .align 4
        .align 4
.L11:
        .long   .L3
        .long   .L4
        .long   .L5
        .long   .L6
        .long   .L7
        .long   .L8
        .long   .L9
        .long   .L10
(the rest omitted)

In the sequence:
        andl    $7, %eax
        cmpl    $7, %eax
        ja      .L12
the compare-and-jump can never trigger.


-- 
           Summary: redundant range check in trivial switch statements
           Product: gcc
           Version: 4.2.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: mikpe at it dot uu dot se
  GCC host triplet: i686-pc-linux-gnu


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

Reply via email to