[Bug rtl-optimization/40209] ICE in iv_analyze_def caused by stale REG_UNUSED note
steven at gcc dot gnu dot org
gcc-bugzilla@gcc.gnu.org
Fri Jul 24 17:05:00 GMT 2009
------- Comment #6 from steven at gcc dot gnu dot org 2009-07-24 17:04 -------
Then we should write a new function, something like this in df.h perhaps:
/* Given an INSN, return a SET expression if the insn has only one
SET whose SET_DEST is used. If SET_DEST is memory, then the SET is
assumed to be used somewhere, always.
This means that:
* If an insn has multiple SETs to only registers, but only one of those
SETs is used, return that one set.
* If an insn has multiple SETs to only registers, but none one of those
SETs is used, return NULL_RTX.
* If an insn has multiple SETs to registers and/or memory, but the SETs to
registers are dead, return the one memory SET, or NULL_RTX if there are
multiple sets to memory.
Only accept INSNs. single_set() can take a pattern, but that is
"old skool" style that should be abolished.
May miss some single_set SETs that single_set() can find, because this
function just looks for the number of uses of a register to determine
whether a set is used (which may fail for hard registers and for unusual
situations with pseudos that somehow are set twice but never used) whereas
single_set() uses liveness information through REG_UNUSED notes. Still,
I expect that, in practice, this function works just as well as
single_set().
One more caveat: The DF user must use incremental scanning, or the
DF_REG_USE_COUNT may be wrong. The result of df_single_set would be
unconservative for new registers since the last scan (DF_REG_USE_COUNT
will still be 0, indicating the new reg is unused and its SET can be
ignored). */
rtx
df_single_set (rtx insn)
{
rtx pat;
gcc_assert (INSN_P (insn));
/* ??? Could even just fall back if the current DF mode is not incremental
scanning. */
pat = PATTERN (insn);
if (GET_CODE (pat) == SET)
return pat;
else if (GET_CODE (pat) == PARALLEL)
{
int i;
rtx set = NULL_RTX;
for (i = 0; i < XVECLEN (pat, 0); i++)
{
rtx sub = XVECEXP (pat, 0, i);
switch (GET_CODE (sub))
{
case USE:
case CLOBBER:
break;
case SET:
if (! set)
{
rtx dest = SET_DEST (set);
if (GET_CODE (dest) == SUBREG)
dest = SUBREG_REG (dest);
if (! REG_P (dest)
|| DF_REG_USE_COUNT (dest) > 0)
set = sub;
}
else
return NULL_RTX;
break;
default:
return NULL_RTX;
}
}
}
else
return NULL_RTX;
}
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40209
More information about the Gcc-bugs
mailing list