https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88308
--- Comment #3 from acsawdey at gcc dot gnu.org --- One difference between compiling this -m32 and -m64 is that the label for the jump table is marked /s in the 64-bit version: (code_label/s 22 21 23 4 (nil) [4 uses]) (jump_table_data 23 22 24 (addr_diff_vec:SI (label_ref:DI 22) [ (label_ref:DI 25) (label_ref:DI 54) (label_ref:DI 83) In the 32-bit version it is not, and that label plus the jump_table_data insn that follows are not present in the dumps after split2: (code_label 23 22 24 4 (nil) [4 uses]) ;; Insn is not within a basic block (jump_table_data 24 23 25 (addr_diff_vec:SI (label_ref:SI 23) [ (label_ref:SI 26) (label_ref:SI 64) (label_ref:SI 102) (label_ref:SI 140) (label_ref:SI 178) The significance of this is that tablejump_p() looks at the next insn to determine if it is in fact a tablejump: bool tablejump_p (const rtx_insn *insn, rtx_insn **labelp, rtx_jump_table_data **tablep) { if (!JUMP_P (insn)) return false; rtx target = JUMP_LABEL (insn); if (target == NULL_RTX || ANY_RETURN_P (target)) return false; rtx_insn *label = as_a<rtx_insn *> (target); rtx_insn *table = next_insn (label); if (table == NULL_RTX || !JUMP_TABLE_DATA_P (table)) return false; Since the label insn and jump table insn seem to be gone, this return false. Then in create_trace_edges() we end up in the final stanza of the if (JUMP_P(insn): else { rtx_insn *lab = JUMP_LABEL_AS_INSN (insn); gcc_assert (lab != NULL); maybe_record_trace_start (lab, insn); } And so we try to create a trace for the jump table label which leads to the ICE.