https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64833
--- Comment #12 from Kazumoto Kojima <kkojima at gcc dot gnu.org> --- I could reproduce the problem on trunk with '-DXS_VERSION=\"6.89\" -fwrapv -fno-strict-aliasing -fopenmp -O2 -fstack-protector-strong -fexceptions -fPIC' with the cross sh4-unknown-linux-gnu compiler. It seems that get_attr_length returns 4 instead of 8 which is the correct length for casesi_worker_2 in find_barrier function for the problematic situation. In that case, the casesi_worker_1 insn of which length is 4, was transformed to casesi_worker_2 and get_attr_length returns the cached old value which is the length for the original casesi_worker_1. It looks to be latent in the older compilers, though the PR is a 4.9/5/6 regression formally. Here is a possible fix: diff --git a/config/sh/sh.c b/config/sh/sh.c index 0139095..86cbea7 100644 --- a/config/sh/sh.c +++ b/config/sh/sh.c @@ -5261,6 +5261,11 @@ find_barrier (int num_mova, rtx_insn *mova, rtx_insn *from) && GET_CODE (PATTERN (from)) == UNSPEC_VOLATILE && XINT (PATTERN (from), 1) == UNSPECV_CONST_END) return from; + /* get_attr_length might return the length of the original worker + for casesi_worker_2. Get uncached length for it. */ + else if (NONJUMP_INSN_P (from) + && recog_memoized (from) == CODE_FOR_casesi_worker_2) + inc = insn_default_length (from); if (BARRIER_P (from)) {