https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69713
--- Comment #2 from Oleg Endo <olegendo at gcc dot gnu.org> --- Looks like an SH specific issue. The bounds check is there, but it's in the wrong place: _lookup_user_key: mov.l r8,@-r15 mov #0,r3 mov.l r9,@-r15 mov #15,r1 mov.l r10,@-r15 mov.l r11,@-r15 mov r5,r11 mov.l r12,@-r15 mov r4,r12 mov.l r13,@-r15 mov.l r14,@-r15 sts.l pr,@-r15 add #-76,r15 mov r15,r2 mov.l r6,@(4,r15) add #16,r2 .L18: add #-1,r1 mov.l r3,@r2 tst r1,r1 add #4,r2 bf .L18 mov.l .L106,r1 mov r12,r10 add #8,r10 <<< offset table index mova .L23,r0 <<< table base addr mov.l r1,@(32,r15) mov r10,r2 <<< mov #1,r1 mov.l r1,@(48,r15) add r2,r2 <<< table offset * 2 mov.w @(r0,r2),r1 <<< table access without bounds check add r0,r1 mov r11,r0 and #1,r0 mov.l .L107,r9 mov.l .L108,r8 mov.l r1,@(8,r15) mov.l r0,@(12,r15) .L20: .L60: ! 421 "sh_tmp.cpp" 1 stc r7_bank, r1 ! 0 "" 2 mov.l @r1,r1 jsr @r9 mov.l @r1,r14 mov.w .L110,r4 jsr @r8 mov r0,r13 mov.l @r14,r2 mov r13,r4 add #1,r2 jsr @r8 mov.l r2,@r14 mov #7,r2 <<< switch case upper bound mov.l r14,@(28,r15) cmp/hi r2,r10 <<< bounds check bf .L101 <<< As far as I can see it, the problem is in the expansion of emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4], reg)); emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3])); The casesi_0 pattern is supposed to emit the bounds checking code, followed by the table memory access expanded by casesi_worker_0 which is then split into casesi_worker_1. However, something seems off and the code emitted by casesi_worker_1 is hoisted above the code emitted by casesi_0.