http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53705

Michael Matz <matz at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |matz at gcc dot gnu.org

--- Comment #1 from Michael Matz <matz at gcc dot gnu.org> 2012-06-17 15:21:10 
UTC ---
Problem is somewhere in cselib.  We test true_dependence of these two insns
(last write to q[] and the read of the last element):

(insn 13 299 22 2 (set (mem/f:DI (plus:DI (reg/v/f:DI 2 cx [orig:63 q ] [63])
                (const_int 144 [0x90])) [2 *q_19+0 S8 A64])
        (reg:DI 1 dx [73])) pr53705.c:9 62 {*movdi_internal_rex64}
     (expr_list:REG_DEAD (reg/v/f:DI 2 cx [orig:63 q ] [63])
        (nil)))

(insn 21 350 257 2 (set (reg:CCZ 17 flags)
        (compare:CCZ (mem/f/c:DI (plus:DI (reg/f:DI 6 bp)
                    (const_int -8 [0xfffffffffffffff8])) [2 q+152 S8 A64])
            (reg:DI 1 dx [73]))) pr53705.c:19 7 {*cmpdi_1}
     (expr_list:REG_DEAD (reg:DI 1 dx [73])
        (nil)))

For that we check write_dependence of:
  (mem/f:DI (plus:DI (reg/v/f:DI 2 cx [orig:63 q ] [63])
                     (const_int 144 [0x90])) [2 *q_19+0 S8 A64])
vs
  (mem/f/c:DI (plus:DI (reg/f:DI 6 bp)
                       (const_int -8 [0xfffffffffffffff8])) [2 q+152 S8 A64])

(note that at this point cx == bp-152, hence this accesses the same memory.

true_dependence uses base_alias_check to test these two mems and wants
to disambiguate the bases.  cselib is used for that and in valueized form
the two addresses look like so:
  (plus:DI (value:DI 8:12039 @0x1b9ef68/0x1b55410) (const_int 144 [0x90]))
  (plus:DI (value:DI 2:4059 @0x1b9eed8/0x1b552f0) (const_int -8))

>From cselib we have these details of the two involved VALUEs:

(value:DI 8:12039 @0x1b9ef68/0x1b55410)
 locs:
  from insn 43 (reg/v/f:DI 2 cx [orig:63 q ] [63])
  from insn 43 (plus:DI (value:DI 5:7965 @0x1b9ef20/0x1b55380)
            (const_int 8 [0x8]))

(value:DI 2:4059 @0x1b9eed8/0x1b552f0)
 locs:
  from insn 352 (reg/f:DI 6 bp)
  from insn 351 (plus:DI (value:DI 1:1 @0x1b9eec0/0x1b552c0)
            (const_int -8 [0xfffffffffffffff8]))

That is, value 2 is bp-based (or value 1) based, and value 8 is value 5 based,
which itself is:

(value:DI 5:7965 @0x1b9ef20/0x1b55380)
 locs:
  from insn 353 (reg/f:DI 7 sp)
  from insn 353 (plus:DI (value:DI 2:4059 @0x1b9eed8/0x1b552f0)
            (const_int -160 [0xffffffffffffff60]))

I.e. value 5 (and hence 8) is value 2 based (like the other mem), or sp based.

Now, find_base_term() for [bp-8] will return "(address:DI -4)", which comes
from
the REG_BASE_VALUE of the (reg/f:DI 6 bp).

find_base_term ([cx+144]) otoh will go via value 8 to value 5, from there
to REG_BASE_VALUE([sp]), which returns "(address:DI -1)".  If find_base_term
would skip the first loc ("sp") and try to look into the second loc (val 2)
it would also return (address:DI -4).

Now, two ADDRESS rtxes that aren't pointer-equal aren't equivalent, and hence
the disambiguator thinks that the two mems cannot point into the same memory.

Obviously the problem is some confusion in setting up REG_BASE_VALUE for
sp and bp.  When we have a frame pointer then both should have the same base,
not different ones.

Reply via email to