James E Wilson wrote:
Yes, that is what I was suggesting.
It's corrected and tested on ia64 and x86-64. I've attached new version. Denis.
Index: reload.c =================================================================== *** reload.c (revision 111135) --- reload.c (working copy) *************** static int find_inc_amount (rtx, rtx); *** 281,286 **** --- 281,287 ---- static int refers_to_mem_for_reload_p (rtx); static int refers_to_regno_for_reload_p (unsigned int, unsigned int, rtx, rtx *); + static int reg_inc_found_and_valid_p (unsigned int, unsigned int, rtx); /* Determine if any secondary reloads are needed for loading (if IN_P is nonzero) or storing (if IN_P is zero) X to or from a reload register of *************** find_inc_amount (rtx x, rtx inced) *** 6941,6949 **** return 0; } /* Return 1 if register REGNO is the subject of a clobber in insn INSN. ! If SETS is nonzero, also consider SETs. REGNO must refer to a hard ! register. */ int regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode, --- 6942,6977 ---- return 0; } + /* Return 1 if registers from REGNO to ENDREGNO are the subjects of a + REG_INC note in insn INSN. REGNO must refer to a hard register. */ + + static int + reg_inc_found_and_valid_p (unsigned int regno ATTRIBUTE_UNUSED, + unsigned int endregno ATTRIBUTE_UNUSED, + rtx insn ATTRIBUTE_UNUSED) + { + #ifdef AUTO_INC_DEC + rtx link; + + gcc_assert (insn); + + if (! INSN_P (insn)) + return 0; + + for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) + if (REG_NOTE_KIND (link) == REG_INC) + { + unsigned int test = (int) REGNO (XEXP (link, 0)); + if (test >= regno && test < endregno) + return 1; + } + #endif + return 0; + } + /* Return 1 if register REGNO is the subject of a clobber in insn INSN. ! If SETS is 1, also consider SETs. If SETS is 2, enable checking REG_INC. ! REGNO must refer to a hard register. */ int regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode, *************** regno_clobbered_p (unsigned int regno, r *** 6958,6964 **** endregno = regno + nregs; if ((GET_CODE (PATTERN (insn)) == CLOBBER ! || (sets && GET_CODE (PATTERN (insn)) == SET)) && REG_P (XEXP (PATTERN (insn), 0))) { unsigned int test = REGNO (XEXP (PATTERN (insn), 0)); --- 6986,6992 ---- endregno = regno + nregs; if ((GET_CODE (PATTERN (insn)) == CLOBBER ! || (sets == 1 && GET_CODE (PATTERN (insn)) == SET)) && REG_P (XEXP (PATTERN (insn), 0))) { unsigned int test = REGNO (XEXP (PATTERN (insn), 0)); *************** regno_clobbered_p (unsigned int regno, r *** 6966,6971 **** --- 6994,7002 ---- return test >= regno && test < endregno; } + if (sets == 2 && reg_inc_found_and_valid_p (regno, endregno, insn)) + return 1; + if (GET_CODE (PATTERN (insn)) == PARALLEL) { int i = XVECLEN (PATTERN (insn), 0) - 1; *************** regno_clobbered_p (unsigned int regno, r *** 6974,6980 **** { rtx elt = XVECEXP (PATTERN (insn), 0, i); if ((GET_CODE (elt) == CLOBBER ! || (sets && GET_CODE (PATTERN (insn)) == SET)) && REG_P (XEXP (elt, 0))) { unsigned int test = REGNO (XEXP (elt, 0)); --- 7005,7011 ---- { rtx elt = XVECEXP (PATTERN (insn), 0, i); if ((GET_CODE (elt) == CLOBBER ! || (sets == 1 && GET_CODE (PATTERN (insn)) == SET)) && REG_P (XEXP (elt, 0))) { unsigned int test = REGNO (XEXP (elt, 0)); *************** regno_clobbered_p (unsigned int regno, r *** 6982,6987 **** --- 7013,7020 ---- if (test >= regno && test < endregno) return 1; } + if (sets == 2 && reg_inc_found_and_valid_p (regno, endregno, elt)) + return 1; } } Index: reload1.c =================================================================== *** reload1.c (revision 110905) --- reload1.c (working copy) *************** choose_reload_regs (struct insn_chain *c *** 5780,5786 **** if (equiv != 0) { ! if (regno_clobbered_p (regno, insn, rld[r].mode, 0)) switch (rld[r].when_needed) { case RELOAD_FOR_OTHER_ADDRESS: --- 5780,5786 ---- if (equiv != 0) { ! if (regno_clobbered_p (regno, insn, rld[r].mode, 2)) switch (rld[r].when_needed) { case RELOAD_FOR_OTHER_ADDRESS:
2006-02-16 Denis Nagorny <[EMAIL PROTECTED]> PR rtl-optimization/25603 * reload.c (reg_inc_found_and_valid_p): New. Check REG_INC note. (regno_clobbered_p): Use it. Reusing SETS argument for REG_INC case. * reload1.c (choose_reload_regs): Added call of regno_clobbered_p with new meaning of SETS.