This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Deep CSE bug!
- From: "Dave Korn" <dk at artimi dot com>
- To: <gcc at gcc dot gnu dot org>
- Date: Thu, 17 Jun 2004 12:19:31 +0100
- Subject: Deep CSE bug!
Hi everyone,
I'm chasing down a really nasty bug deep in the guts of cse_insn.
Basically, it ends up thinking that 0 == -1. The reason for that is down to
a confusion of equivalence classes. Let me demonstrate: I've got this
insn:
(insn 33 32 37 0 0x1002f510 (set (subreg:SI (reg:DI 80) 4)
(reg/v:SI 75)) 22 {movsi} (nil)
(expr_list:REG_EQUAL (const_double -1 [0xffffffff] 0 [0x0] 0 [0x0] 0
[0x0] 0 [0x0] 0 [0x0])
(nil)))
Now, reg 75 contains (and is known to contain) (const_int:SI 0). But then
we come to this bit of code in cse_insn:
---------->snip!<----------
/* Now enter all non-volatile source expressions in the hash table
if they are not already present.
Record their equivalence classes in src_elt.
This way we can insert the corresponding destinations into
the same classes even if the actual sources are no longer in them
(having been invalidated). */
if (src_eqv && src_eqv_elt == 0 && sets[0].rtl != 0 && ! src_eqv_volatile
&& ! rtx_equal_p (src_eqv, SET_DEST (sets[0].rtl)))
{
struct table_elt *elt;
struct table_elt *classp = sets[0].src_elt;
rtx dest = SET_DEST (sets[0].rtl);
enum machine_mode eqvmode = GET_MODE (dest);
if (GET_CODE (dest) == STRICT_LOW_PART)
{
eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
classp = 0;
}
if (insert_regs (src_eqv, classp, 0))
{
rehash_using_reg (src_eqv);
src_eqv_hash = HASH (src_eqv, eqvmode);
}
elt = insert (src_eqv, classp, src_eqv_hash, eqvmode);
elt->in_memory = src_eqv_in_memory;
src_eqv_elt = elt;
---------->snip!<----------
and at this point everything is wrong, because all of a sudden the qty_table
entry for reg 75 contains (const_int -1).
Now my grasp of this code is a little hazy as yet, but I *think* that
what's happening is that this code is trying to say that the dest of the set
(subreg:SI (reg:DI 80) 4) is now equivalent to the source (reg:si 75), and
it's looking at the reg_equal note, and it's forgetting about the offset of
4 in the subreg and fetching the -1 from the (const_double -1 [0xffffffff] 0
[0x0] 0 [0x0] 0 [0x0] 0 [0x0] 0 [0x0]) (which is what src_eqv points to)
when it should be fetching the zero immediately following.
So I guess my question for anyone who's on first-name terms with the CSE
machinery is, given this insn
(insn 33 32 37 0 0x1002f510 (set (subreg:SI (reg:DI 80) 4)
(reg/v:SI 75)) 22 {movsi} (nil)
(expr_list:REG_EQUAL (const_double -1 [0xffffffff] 0 [0x0] 0 [0x0] 0
[0x0] 0 [0x0] 0 [0x0])
(nil)))
is it valid that src_eqv is
(const_double -1 [0xffffffff] 0 [0x0] 0 [0x0] 0 [0x0] 0 [0x0] 0 [0x0])
or should it really be
(const_int 0)
by the time we reach this code?
cheers,
DaveK
--
Can't think of a witty .sigline today....