[patch] for PR 20249
Zdenek Dvorak
rakdver@atrey.karlin.mff.cuni.cz
Mon Mar 7 10:28:00 GMT 2005
Hello,
my patch to safe_insert_insn_on_edge exposed a latent bug in cse. The
rtl looks as follows (saving and restoring of reg:si 5 to reg:si 124 is
due to the patch):
(set (reg:si 124) (reg:si 5))
...
(set (reg:si 5) (reg:si 124))
...
(set (reg:di 119) (reg:di 5)) (*)
...
(set (reg:di 3) (reg:di 119))
CSE copy propagates all over, creating invalid insn
(set (reg:di 3) (reg:si 5))
The reason is that at the insn (*), reg 119 is recorded to be equivalent
to register 5. However the record for reg 5 is in SImode, which causes
the problem.
This patch fixes the problem by preventing the recording of equivalence
with a register in a different mode.
Bootstrapped & regtested on i686 and ia64 with -fprofile-arcs. I have
also tried bootstrapping on ppc, this is successful except for a
bootstrap misscompare (which is a progress, since without the patch
the bootstrap fails with an ICE similar to the one of the PR). I need
to check whether the misscompare problem is related to the PR or not.
Zdenek
PR middle-end/20249
* cse.c (insert_regs): Do not record equivalence of registers in
different modes.
Index: cse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cse.c,v
retrieving revision 1.348
diff -c -3 -p -r1.348 cse.c
*** cse.c 6 Mar 2005 20:05:58 -0000 1.348
--- cse.c 6 Mar 2005 23:20:50 -0000
*************** insert_regs (rtx x, struct table_elt *cl
*** 1234,1240 ****
if (REG_P (classp->exp)
&& GET_MODE (classp->exp) == GET_MODE (x))
{
! make_regs_eqv (regno, REGNO (classp->exp));
return 1;
}
--- 1234,1257 ----
if (REG_P (classp->exp)
&& GET_MODE (classp->exp) == GET_MODE (x))
{
! unsigned c_regno = REGNO (classp->exp);
!
! gcc_assert (REGNO_QTY_VALID_P (c_regno));
!
! /* Suppose that 5 is hard reg and 100 and 101 are
! pseudos. Consider
!
! (set (reg:si 100) (reg:si 5))
! (set (reg:si 5) (reg:si 100))
! (set (reg:di 101) (reg:di 5))
!
! We would now set REG_QTY (101) = REG_QTY (5), but the
! entry for 5 is in SImode. When we use this later in
! copy propagation, we get the register in wrong mode. */
! if (qty_table[REG_QTY (c_regno)].mode != GET_MODE (x))
! continue;
!
! make_regs_eqv (regno, c_regno);
return 1;
}
More information about the Gcc-patches
mailing list