[backport from gcc-4.7/trunk, fixes PR48770 regression from PR37273 patch ] gcc/ 2011-06-23 Jeff Law PR middle-end/48770 * reload.h (reload): Change to return a bool. * ira.c (ira): If requested by reload, run a fast DCE pass after reload has completed. Fix comment typo. * reload1.c (need_dce): New file scoped static. (reload): Set reload_completed here. Return whether or not a DCE pass after reload is needed. (delete_dead_insn): Set need_dce as needed. gcc/testsuite/ 2011-06-23 Jeff Law PR middle-end/48770 * gcc.dg/pr48770.c: New test. --- gcc-4.6.1/gcc/ira.c.~1~ 2011-03-08 16:51:12.000000000 +0100 +++ gcc-4.6.1/gcc/ira.c 2011-07-06 13:15:32.000000000 +0200 @@ -321,6 +321,7 @@ along with GCC; see the file COPYING3. #include "integrate.h" #include "ggc.h" #include "ira-int.h" +#include "dce.h" struct target_ira default_target_ira; @@ -3081,6 +3082,7 @@ ira (FILE *f) int rebuild_p; int saved_flag_ira_share_spill_slots; basic_block bb; + bool need_dce; timevar_push (TV_IRA); @@ -3271,7 +3273,7 @@ ira (FILE *f) df_set_flags (DF_NO_INSN_RESCAN); build_insn_chain (); - reload_completed = !reload (get_insns (), ira_conflicts_p); + need_dce = reload (get_insns (), ira_conflicts_p); timevar_pop (TV_RELOAD); @@ -3314,7 +3316,7 @@ ira (FILE *f) #endif /* The code after the reload has changed so much that at this point - we might as well just rescan everything. Not that + we might as well just rescan everything. Note that df_rescan_all_insns is not going to help here because it does not touch the artificial uses and defs. */ df_finish_pass (true); @@ -3326,6 +3328,9 @@ ira (FILE *f) if (optimize) df_analyze (); + if (need_dce && optimize) + run_fast_dce (); + timevar_pop (TV_IRA); } --- gcc-4.6.1/gcc/reload.h.~1~ 2010-08-14 23:46:11.000000000 +0200 +++ gcc-4.6.1/gcc/reload.h 2011-07-06 13:15:32.000000000 +0200 @@ -378,7 +378,7 @@ extern void reload_cse_regs (rtx); extern void init_reload (void); /* The reload pass itself. */ -extern int reload (rtx, int); +extern bool reload (rtx, int); /* Mark the slots in regs_ever_live for the hard regs used by pseudo-reg number REGNO. */ --- gcc-4.6.1/gcc/reload1.c.~1~ 2011-06-17 13:13:38.000000000 +0200 +++ gcc-4.6.1/gcc/reload1.c 2011-07-06 13:15:32.000000000 +0200 @@ -288,6 +288,10 @@ static char *reload_insn_firstobj; examine. */ struct insn_chain *reload_insn_chain; +/* TRUE if we potentially left dead insns in the insn stream and want to + run DCE immediately after reload, FALSE otherwise. */ +static bool need_dce; + /* List of all insns needing reloads. */ static struct insn_chain *insns_need_reload; @@ -711,10 +715,11 @@ static int *temp_pseudo_reg_arr; If GLOBAL is zero, we do not have enough information to do that, so any pseudo reg that is spilled must go to the stack. - Return value is nonzero if reload failed - and we must not do any more for this function. */ + Return value is TRUE if reload likely left dead insns in the + stream and a DCE pass should be run to elimiante them. Else the + return value is FALSE. */ -int +bool reload (rtx first, int global) { int i, n; @@ -1318,7 +1323,9 @@ reload (rtx first, int global) gcc_assert (bitmap_empty_p (&spilled_pseudos)); - return failure; + reload_completed = !failure; + + return need_dce; } /* Yet another special case. Unfortunately, reg-stack forces people to @@ -2115,14 +2122,19 @@ delete_dead_insn (rtx insn) rtx prev = prev_active_insn (insn); rtx prev_dest; - /* If the previous insn sets a register that dies in our insn, delete it - too. */ + /* If the previous insn sets a register that dies in our insn make + a note that we want to run DCE immediately after reload. + + We used to delete the previous insn & recurse, but that's wrong for + block local equivalences. Instead of trying to figure out the exact + circumstances where we can delete the potentially dead insns, just + let DCE do the job. */ if (prev && GET_CODE (PATTERN (prev)) == SET && (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest)) && reg_mentioned_p (prev_dest, PATTERN (insn)) && find_regno_note (insn, REG_DEAD, REGNO (prev_dest)) && ! side_effects_p (SET_SRC (PATTERN (prev)))) - delete_dead_insn (prev); + need_dce = 1; SET_INSN_DELETED (insn); } --- gcc-4.6.1/gcc/testsuite/gcc.dg/pr48770.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.6.1/gcc/testsuite/gcc.dg/pr48770.c 2011-07-06 13:15:32.000000000 +0200 @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-options "-O -fprofile-arcs -fPIC -fno-dce -fno-forward-propagate" } */ + +int test_goto2 (int f) +{ + int i; + for (i = 0; ({_Bool a = i < 10;a;}); i++) + { + if (i == f) + goto lab2; + } + return 4; +lab2: + return 8; +} + +int main () +{ + test_goto2 (30); + return 0; +}