---------- Forwarded message ----------
From: Paulo Matos <pmatos@broadcom.com>
Date: Wed, Dec 19, 2012 at 11:59 AM
Subject: cselib_record_set breaks due to auto_inc_dec
To: "gcc@gcc.gnu.org" <gcc@gcc.gnu.org>
Hi,
After pro and epilogue pass I have the following epilogue insn:
(insn/f 20 19 21 2 (parallel [
(set (mem:DI (plus:SI (reg:SI 26 r26)
(reg/f:SI 57 r57)) [0 S8 A8])
(reg:DI 57 r57))
(set (reg/f:SI 57 r57)
(plus:SI (reg:SI 26 r26)
(reg/f:SI 57 r57)))
]) bdra_main.i:2 -1
(expr_list:REG_DEAD (reg:SI 26 r26)
(expr_list:REG_FRAME_RELATED_EXPR (set (mem:DI (pre_modify:SI
(reg/f:SI 57 r57)
(plus:SI (reg/f:SI 57 r57)
(const_int -8208 [0xffffffffffffdff0]))) [0 S8 A8])
(reg:DI 57 r57))
(nil))))
During cselib_record_sets, 2 sets are recognized (the ones in the
parallel) and then a third one is added by cselib_record_autoinc_cb:
(set (reg:SI 57) (plus (reg:SI 57) (const_int -8208)))
After for_each_inc_dec calling cselib_record_autoinc_cb sets array is:
sets[0]:
dest: (reg/f:SI 57 r57)
src: (plus:SI (reg:SI 26 r26)
(reg/f:SI 57 r57))
sets[1]:
dest: (mem:DI (plus:SI (reg:SI 26 r26)
(reg/f:SI 57 r57)))
src: (reg:DI 57 r57)
sets[2]:
dest: (reg/f:SI 57 r57)
src: (plus:SI (reg/f:SI 57 r57)
(const_int -8208 [0xffffffffffffdff0]))))
The last loop in cselib_record_sets is:
for (i = 0; i < n_sets; i++)
{
rtx dest = sets[i].dest;
if (REG_P (dest)
|| (MEM_P (dest) && cselib_record_memory))
cselib_record_set (dest, sets[i].src_elt, sets[i].dest_addr_elt);
}
This fails while trying to register the second set to reg:SI 57, in
/* The register should have been invalidated. */
gcc_assert (REG_VALUES (dreg)->elt == 0);
This seems to be a manifestation of PR32335, where the extra
assignment to the same register (in this case r57) is added by
auto_inc_dec analysis and not explicit in the parallel.
Has anyone come across this before?
Paulo Matos