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.