This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Reload reloading outdated values ?
On 2 October 2012 20:25, Frederic Riss <frederic.riss@gmail.com> wrote:
> Something must be wrong, as I don't see how reload can safely move
> memory expressions other than constant addresses around like this.
I dug a bit more, and I'm still confused about this reload behavior.
Let's take this pseudo-RTL code as example:
r229 = mem(r6835, r6823)
... (other insns not touching r229, r6835 or r6823)
r3357 = xor(r219, r229)
At one point at the start of IRA, update_equiv_regs() adds the
REG_EQUIV note after checking that no insn between the r229 def and
it's use break the equivalence:
r229 = mem(r6835, r6823) => REG_EQUIV mem(r6835, r6823)
... (other insns not touching r229, r6835 or r6823)
r3357 = xor(r219, r229)
Register allocation runs. All register mentioned above _except_ r229
get allocated. r229 is marked for spill by IRA.
Then reload kicks in. It records the equivalence in its reg_equiv
arrays. We end up with a situation like this:
r229 = mem(r8, r21) => REG_EQUIV mem(r8, r21)
... (other insns not touching r229, r6835 or r6823, _but using r8_)
r54 = xor(r54, r229)
The second insn is reloaded using the recorded equivalence, and the
initial def of r229 is deleted as it was only setting up the
equivalence:
... (other insns not touching r229, r6835 or r6823, _but using r8_)
r44 = mem(r8, r21)
r54 = xor(r54, r44)
Obviously, the code is wrong, and I don't see what can prevent such a
scenario from happening.
I'm even more confused when reading validate_equiv_mem() that is used
to check the equivalence in update_equiv_regs(). It contains that
comment and code in the scan of the insns between the def and the
death of the analyzed register:
/* This used to ignore readonly memory and const/pure calls. The problem
is the equivalent form may reference a pseudo which gets assigned a
call clobbered hard reg. When we later replace REG with its
equivalent form, the value in the call-clobbered reg has been
changed and all hell breaks loose. */
if (CALL_P (insn))
return 0;
I understand the comment and the issue, but I don't see what make an
ordinary instruction different from a call. Every pseudo used in any
insn can get allocated to a hard register that would break the
equivalence, depending of the pseudo interference.
Any clue of what I'm missing?
Fred