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

            Bug ID: 112413
           Summary: Wrong switch jump table offset
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vincent.riviere at freesbee dot fr
  Target Milestone: ---

In some circumstances, gcc produces bad code for switch instruction.

Main goal of the testcase is to force gcc to produce a jump table.

$ cat swi.c
int g;

void f(int i)
{
        switch (i)
        {
                case 0: g = 6082; break;
                case 1: g = 9332; break;
                case 2: g = 5642; break;
                case 3: g = 1423; break;
                case 4: g = 2152; break;
                case 5: g = 6779; break;
                case 6: g = 7074; break;
                case 7: g = 8280; break;
        }
}

$ m68k-linux-gcc -Os -S -o - swi.c -mlong-jump-table-offsets -malign-int
#NO_APP
        .file   "swi.c"
        .text
        .align  2
        .globl  f
        .type   f, @function
f:
        move.l 4(%sp),%d0
        moveq #7,%d1
        cmp.l %d0,%d1
        jcs .L1
        lsl.l #2,%d0
        move.l .L4(%pc,%d0.l),%d0
        jmp %pc@(2,%d0:l)
        .balignw 4,0x284c   |Potential bug here
.L4:
        .long .L11-.L4
        .long .L10-.L4
        .long .L9-.L4
        .long .L8-.L4
        .long .L7-.L4
        .long .L6-.L4
        .long .L5-.L4
        .long .L3-.L4
.L11:
        move.l #6082,g
.L1:
        rts
.L10:
        move.l #9332,g
        jra .L1
...

As the jmp may not be aligned on a multiple of 4, the .balignw directive may
introduce a 2-byte filler, causing jmp to use a wrong offset.

Same happens with m68k-elf-gcc.

Reply via email to