The following patch fixes http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58418
The patch also fixes a duplicated bug PR58419. The patch was successfully tested and bootstrapped on x86/x86-64. Committed as rev. 202630. 2013-09-16 Vladimir Makarov <vmaka...@redhat.com> PR middle-end/58418 * lra-constraints.c (undo_optional_reloads): Consider all optional reload even if it did not get a hard reg. 2013-09-16 Vladimir Makarov <vmaka...@redhat.com> * gcc.target/i386/pr58418.c: New.
Index: lra-constraints.c =================================================================== --- lra-constraints.c (revision 202626) +++ lra-constraints.c (working copy) @@ -5454,43 +5454,42 @@ undo_optional_reloads (void) bitmap_initialize (&removed_optional_reload_pseudos, ®_obstack); bitmap_copy (&removed_optional_reload_pseudos, &lra_optional_reload_pseudos); EXECUTE_IF_SET_IN_BITMAP (&lra_optional_reload_pseudos, 0, regno, bi) - if (reg_renumber[regno] >= 0) - { - keep_p = false; - if (reg_renumber[lra_reg_info[regno].restore_regno] >= 0) - /* If the original pseudo changed its allocation, just - removing the optional pseudo is dangerous as the original - pseudo will have longer live range. */ - keep_p = true; - else - EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi2) - { - insn = lra_insn_recog_data[uid]->insn; - if ((set = single_set (insn)) == NULL_RTX) - continue; - src = SET_SRC (set); - dest = SET_DEST (set); - if (! REG_P (src) || ! REG_P (dest)) - continue; - if (REGNO (dest) == regno - /* Ignore insn for optional reloads itself. */ - && lra_reg_info[regno].restore_regno != (int) REGNO (src) - /* Check only inheritance on last inheritance pass. */ - && (int) REGNO (src) >= new_regno_start - /* Check that the optional reload was inherited. */ - && bitmap_bit_p (&lra_inheritance_pseudos, REGNO (src))) - { - keep_p = true; - break; - } - } - if (keep_p) + { + keep_p = false; + if (reg_renumber[lra_reg_info[regno].restore_regno] >= 0) + /* If the original pseudo changed its allocation, just + removing the optional pseudo is dangerous as the original + pseudo will have longer live range. */ + keep_p = true; + else if (reg_renumber[regno] >= 0) + EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi2) { - bitmap_clear_bit (&removed_optional_reload_pseudos, regno); - if (lra_dump_file != NULL) - fprintf (lra_dump_file, "Keep optional reload reg %d\n", regno); + insn = lra_insn_recog_data[uid]->insn; + if ((set = single_set (insn)) == NULL_RTX) + continue; + src = SET_SRC (set); + dest = SET_DEST (set); + if (! REG_P (src) || ! REG_P (dest)) + continue; + if (REGNO (dest) == regno + /* Ignore insn for optional reloads itself. */ + && lra_reg_info[regno].restore_regno != (int) REGNO (src) + /* Check only inheritance on last inheritance pass. */ + && (int) REGNO (src) >= new_regno_start + /* Check that the optional reload was inherited. */ + && bitmap_bit_p (&lra_inheritance_pseudos, REGNO (src))) + { + keep_p = true; + break; + } } - } + if (keep_p) + { + bitmap_clear_bit (&removed_optional_reload_pseudos, regno); + if (lra_dump_file != NULL) + fprintf (lra_dump_file, "Keep optional reload reg %d\n", regno); + } + } change_p = ! bitmap_empty_p (&removed_optional_reload_pseudos); bitmap_initialize (&insn_bitmap, ®_obstack); EXECUTE_IF_SET_IN_BITMAP (&removed_optional_reload_pseudos, 0, regno, bi) Index: testsuite/gcc.target/i386/pr58418.c =================================================================== --- testsuite/gcc.target/i386/pr58418.c (revision 0) +++ testsuite/gcc.target/i386/pr58418.c (working copy) @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern void abort (void); +int a, b, *c = &b, d = -1, e, f, *g, *h = &f, **i = &g, j; + +unsigned int +foo (unsigned int p) +{ + return p == 0 ? 0 : 1 / p; +} + +static int * +bar () +{ + *c = *h = foo (d) & (-9 < d); + for (e = 0; e; e++) + ; + return 0; +} + +int +main () +{ + for (; j; j++) + for (;; a--) + ; + *i = bar (); + if (f != 0) + abort (); + return 0; +}