c/7871: ICE on legal code, global register variables problems
Richard Henderson
rth@redhat.com
Fri Feb 28 05:49:00 GMT 2003
On Thu, Feb 27, 2003 at 10:23:53PM -0500, Jim Wilson wrote:
> ! /* Calls change all call-used registers. Calls may or may not
> ! change global registers. Since this will cause previous stores
> ! to be deleted as dead, we must assume that global registers are
> ! not set in the call. */
> for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
> ! if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)
> ! && ! global_regs[i])
I don't think this is right. The call may change the variable.
If we don't mark the value set, we won't have proper log_links.
The register was *supposed* to be marked used by
/* Calls may also reference any of the global registers,
so they are made live. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (global_regs[i])
mark_used_reg (pbi, regno_reg_rtx[i], cond, insn);
so I'm not sure where we went wrong...
A test case that I think may fail with your change is
register int d __asm__("d7");
void bar()
{
if (d != 1)
abort();
d = 4;
}
void baz()
{
if (d != 6)
abort();
}
int main()
{
d = 1;
bar();
d |= 2;
baz();
return 0;
}
If log_links are wrong, combine will see d=1 linked with d|=2 and
produce d=3.
r~
More information about the Gcc-bugs
mailing list