Hi! When looking at the rs6000_store_data_bypass_p stuff, I've noticed that it accepts PARALLELs containing not just SETs and CLOBBERs like store_data_bypass_p, but also USEs. Given that it is something that single_set also ignores, I think fixing store_data_bypass_p is the right fix here.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Note, the patch is larger due to the formatting fixes, the actual changes are just 3x - if (GET_CODE (xxx) == CLOBBER) + if (GET_CODE (xxx) == CLOBBER || GET_CODE (xxx) == USE) 2017-12-06 Jakub Jelinek <ja...@redhat.com> * recog.c (store_data_bypass_p): Handle USE in a PARALLEL like CLOBBER. Formatting fixes. --- gcc/recog.c.jj 2017-10-24 12:07:06.000000000 +0200 +++ gcc/recog.c 2017-12-06 12:20:37.256654794 +0100 @@ -3677,30 +3677,30 @@ store_data_bypass_p (rtx_insn *out_insn, out_set = single_set (out_insn); if (out_set) - { - if (reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set))) - return false; - } + { + if (reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set))) + return false; + } else - { - out_pat = PATTERN (out_insn); + { + out_pat = PATTERN (out_insn); if (GET_CODE (out_pat) != PARALLEL) return false; - for (i = 0; i < XVECLEN (out_pat, 0); i++) - { - out_exp = XVECEXP (out_pat, 0, i); - - if (GET_CODE (out_exp) == CLOBBER) - continue; - - gcc_assert (GET_CODE (out_exp) == SET); - - if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set))) - return false; - } - } + for (i = 0; i < XVECLEN (out_pat, 0); i++) + { + out_exp = XVECEXP (out_pat, 0, i); + + if (GET_CODE (out_exp) == CLOBBER || GET_CODE (out_exp) == USE) + continue; + + gcc_assert (GET_CODE (out_exp) == SET); + + if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set))) + return false; + } + } } else { @@ -3711,7 +3711,7 @@ store_data_bypass_p (rtx_insn *out_insn, { in_exp = XVECEXP (in_pat, 0, i); - if (GET_CODE (in_exp) == CLOBBER) + if (GET_CODE (in_exp) == CLOBBER || GET_CODE (in_exp) == USE) continue; gcc_assert (GET_CODE (in_exp) == SET); @@ -3719,31 +3719,32 @@ store_data_bypass_p (rtx_insn *out_insn, if (!MEM_P (SET_DEST (in_exp))) return false; - out_set = single_set (out_insn); - if (out_set) - { - if (reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_exp))) - return false; - } - else - { - out_pat = PATTERN (out_insn); - gcc_assert (GET_CODE (out_pat) == PARALLEL); - - for (j = 0; j < XVECLEN (out_pat, 0); j++) - { - out_exp = XVECEXP (out_pat, 0, j); - - if (GET_CODE (out_exp) == CLOBBER) - continue; - - gcc_assert (GET_CODE (out_exp) == SET); - - if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_exp))) - return false; - } - } - } + out_set = single_set (out_insn); + if (out_set) + { + if (reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_exp))) + return false; + } + else + { + out_pat = PATTERN (out_insn); + gcc_assert (GET_CODE (out_pat) == PARALLEL); + + for (j = 0; j < XVECLEN (out_pat, 0); j++) + { + out_exp = XVECEXP (out_pat, 0, j); + + if (GET_CODE (out_exp) == CLOBBER + || GET_CODE (out_exp) == USE) + continue; + + gcc_assert (GET_CODE (out_exp) == SET); + + if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_exp))) + return false; + } + } + } } return true; Jakub