https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112413
--- Comment #3 from Vincent Riviere <vincent.riviere at freesbee dot fr> --- (In reply to Andrew Pinski from comment #1) > I don't see any issues with the output of gcc. Are you sure this is not a > binutils gnu as issue where the offsets are done incorrectly there. Yes, I'm sure it's a gcc bug. With the testcase I initially provided, by chance it's the favourable case. But if I artificially add a misalignment with a nop, for example, the wrong result appears: $ cat swi2.c int g; void f(int i) { asm("nop"); 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 -c swi2.c -mlong-jump-table-offsets -malign-int $ m68k-linux-objdump -d swi2.o swi2.o: file format elf32-m68k Disassembly of section .text: 00000000 <f>: 0: 202f 0004 movel %sp@(4),%d0 4: 4e71 nop 6: 7207 moveq #7,%d1 8: b280 cmpl %d0,%d1 a: 6536 bcss 42 <f+0x42> c: e588 lsll #2,%d0 e: 203b 0808 movel %pc@(18 <f+0x18>,%d0:l),%d0 |right offset 12: 4efb 0802 jmp %pc@(16 <f+0x16>,%d0:l) |wrong offset 16: 284c moveal %a4,%a4 |harmful filler 18: 0000 0020 orib #32,%d0 1c: 0000 002c orib #44,%d0 20: 0000 0038 orib #56,%d0 See that: - actual jump table starts at offset 0x18 - at offset 0x16, a useless "moveal %a4,%a4" instruction is inserted as filler - at offset 0xe, offset 0x18 is used appropriately for label .L4. So the right jump table entry is properly read. - but at offset 0x12, a *wrong* offset 0x16 is used for the jump. That's actually the offset of the filler, while it should be 0x18 for label .L4. This can't work: - the jump table offsets are computed from the start of the jump table - but jmp, with that "2" hardcoded as offset, expects offsets being relative to the address right after itself. So if a filler is inserted between jmp and actual table contents, as in the example above, the jump occurs to a wrong address.