This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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....


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]