https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123833
Roger Sayle <roger at nextmovesoftware dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |roger at nextmovesoftware dot
com
--- Comment #4 from Roger Sayle <roger at nextmovesoftware dot com> ---
Here's my proposed fix:
diff --git a/gcc/fwprop.cc b/gcc/fwprop.cc
index 68969d10401..46ad11db5cf 100644
--- a/gcc/fwprop.cc
+++ b/gcc/fwprop.cc
@@ -925,6 +925,10 @@ fwprop_done (void)
fprintf (dump_file,
"\nNumber of successful forward propagations: %d\n\n",
num_changes);
+
+ /* Clear insn_extract cache to avoid stale insn attributes. */
+ if (num_changes)
+ recog_data.insn = nullptr;
}
/* Try to optimize INSN, returning true if something changes.
The MIPS backend is more fragile than most targets to the correctness of
instruction attibutes, which are used for instruction costing. Initially,
insn #27 is
(insn 27 26 28 4 (set (reg:DI 207)
(zero_extend:DI (reg:SI 206 [ _10 ]))) "../../pr123833.c":18:13 discrim
1 223 {*zero_extendsidi2}
(nil))
which gets recognized/cached by insn_extract. During fwprop this instruction
is converted to:
insn 27 24 28 4 (set (reg:DI 207 [ _10 ])
(and:DI (reg:DI 198 [ _21 ])
(const_int 255 [0xff]))) "../../pr123833.c":18:13 discrim 1 192
{*an
ddi3}
(nil))
but recog's extract_insn cache isn't cleared. So when in the following pass,
ce1, the code calls mips_insn_cost, it calls get_attr_insn_count which finds a
cached entry with matching insn pointer, but with stale data, specifically
which_alternative, is for a *zero_extendsidi2 not for a *anddi3. Mistakenly
thinking the instruction is now of type "load" it hits the assertion that the
operand must be a MEM.
Finally, the reason that this is placed in fwprop_done rather than the perhaps
more obvious end of "try_fwprop_subst_pattern" in the chunk:
confirm_change_group ();
crtl->ssa->change_insn (use_change);
+ recog_data.insn = nullptr;
num_changes++;
return true;
(which was my first attempt) is that this something/somewhere undoes this
change, so that recog_data.insn is "conveniently" returned to its stale value
by the end of the pass.
Any thoughts on a better fix? (whilst I bootstrap and regression test on
x86_64).