[Bug rtl-optimization/57915] [4.8/4.9 Regression] ICE in set_address_disp, at rtlanal.c:5537
abel at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Jan 23 13:55:00 GMT 2014
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57915
Andrey Belevantsev <abel at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |abel at gcc dot gnu.org
--- Comment #6 from Andrey Belevantsev <abel at gcc dot gnu.org> ---
The cprop pass doesn't care much in this case, it only passes the resulting set
to simplify_rtx which does nothing. Fwprop does the right thing with the
similar insn (insn 9) but doesn't work for insn in question (insn 58) because
it is inside the loop:
1466 Do not forward propagate addresses into loops until after unrolling.
1467 CSE did so because it was able to fix its own mess, but we are not.
*/
But come on, in this case the def/use are in the same basic block(!) so this
stuff not fixed by fwprop is later fixed (wrongly) by _local_ cprop. Fwprop2
is supposed to fix this but it surely runs after the 1st cprop so it doesn't
have a chance.
So either we:
1) drop the loop check altogether -- forward_propagate_into already has code
not to propagate into the inner loop; this might be too risky as I don't know
all reasons of why the first fwprop does not propagate inside loops;
2) allow at least propagating into the same blocks to offset the local cprop
code as in the below patch;
3) teach cprop to leave it for the second fwprop_addr -- but there's a lot of
stuff happening in between;
4) teach cprop to simplify rtxes in line with the fwprop's propagate rtx code,
i.e. diving inside and when looking at a mem, pass its address to
simplify_gen_binary and other address-related things.
The below patch is the simplest option 2) and fixes the test case.
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index 4317f51..c62a501 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -1469,11 +1469,14 @@ fwprop (void)
for (i = 0; i < DF_USES_TABLE_SIZE (); i++)
{
df_ref use = DF_USES_GET (i);
+ df_ref def;
if (use)
if (DF_REF_TYPE (use) == DF_REF_REG_USE
|| DF_REF_BB (use)->loop_father == NULL
/* The outer most loop is not really a loop. */
- || loop_outer (DF_REF_BB (use)->loop_father) == NULL)
+ || loop_outer (DF_REF_BB (use)->loop_father) == NULL
+ || ((def = get_def_for_use (use))
+ && DF_REF_BB (use) == DF_REF_BB (def)))
need_cleanup |= forward_propagate_into (use);
}
More information about the Gcc-bugs
mailing list