2014-08-14 Jakub Jelinek PR target/62025 * sched-deps.c (find_inc): Limit the test for inc_insn defs vs. mem_insn uses to !backwards case only. Give up also if any mem_insn def is used by inc_insn or if non-clobber mem_insn def in backwards case is clobbered by inc_insn. --- gcc/sched-deps.c.jj 2014-08-12 17:06:26.000000000 +0200 +++ gcc/sched-deps.c 2014-08-14 00:09:38.000000000 +0200 @@ -4746,23 +4746,70 @@ find_inc (struct mem_inc_info *mii, bool "inc conflicts with store failure.\n"); goto next; } + else + { + df_ref *use_rec, *def2_rec; + for (use_rec = DF_INSN_USES (mii->inc_insn); + *use_rec; use_rec++) + { + df_ref use = *use_rec; + if (reg_overlap_mentioned_p (DF_REF_REG (def), + DF_REF_REG (use))) + { + if (sched_verbose >= 5) + fprintf (sched_dump, + "mem def conflict with inc use " + "failure.\n"); + goto next; + } + } + /* If both inc_insn and mem_insn clobber the same register, + it is fine, but avoid the case where mem_insn e.g. + sets CC and originally earlier inc_insn clobbers it. */ + if ((DF_REF_FLAGS (def) & DF_REF_MUST_CLOBBER) == 0 + && backwards) + for (def2_rec = DF_INSN_DEFS (mii->inc_insn); + *def2_rec; def2_rec++) + { + df_ref def2 = *def2_rec; + if (reg_overlap_mentioned_p (DF_REF_REG (def), + DF_REF_REG (def2))) + { + if (sched_verbose >= 5) + fprintf (sched_dump, + "mem def conflict with inc def " + "failure.\n"); + goto next; + } + } + } } /* The inc instruction could have clobbers, make sure those - registers are not used in mem insn. */ - for (def_rec = DF_INSN_DEFS (mii->inc_insn); *def_rec; def_rec++) - if (!reg_overlap_mentioned_p (DF_REF_REG (*def_rec), mii->mem_reg0)) + registers are not used in mem insn, if mem_insn is originally + earlier than inc_insn. */ + if (!backwards) + for (def_rec = DF_INSN_DEFS (mii->inc_insn); *def_rec; def_rec++) { - df_ref *use_rec; - for (use_rec = DF_INSN_USES (mii->mem_insn); *use_rec; use_rec++) - if (reg_overlap_mentioned_p (DF_REF_REG (*def_rec), - DF_REF_REG (*use_rec))) - { - if (sched_verbose >= 5) - fprintf (sched_dump, - "inc clobber used in store failure.\n"); - goto next; - } + df_ref def = *def_rec; + if (!reg_overlap_mentioned_p (DF_REF_REG (def), mii->mem_reg0)) + { + df_ref *use_rec; + for (use_rec = DF_INSN_USES (mii->mem_insn); + *use_rec; use_rec++) + { + df_ref use = *use_rec; + if (reg_overlap_mentioned_p (DF_REF_REG (def), + DF_REF_REG (use))) + { + if (sched_verbose >= 5) + fprintf (sched_dump, + "inc def conflict with mem use " + "failure.\n"); + goto next; + } + } + } } newaddr = mii->inc_input;