Hi,
Previously I reported pr52804 in bugzilla about reload pass reloads wrong
register.
After investigation I believe it is a bug in reload pass and here comes the
patch.
You can refer to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52804 for
details.
In short, I think the confliction of reloads with type
RELOAD_FOR_INPADDR_ADDRESS
and type RELOAD_FOR_INPUT_ADDRESS should be handled in
"reload_reg_reaches_end_p".
Also I think RELOAD_FOR_OUTPUT_ADDRESS/RELOAD_FOR_OUTADDR_ADDRESS have the
issue
symmetrically, though I have no test case for it.
I have tested the patch for x86 and arm. Is it OK?
I think it is a bug of reload, and I understand reload pass should be rarely
touched,
so any comments are highly appreciated on this topic.
Thanks very much.
2012-04-20 Bin Cheng <bin.ch...@arm.com>
PR target/52804
* reload1.c (reload_reg_reaches_end_p): Check whether successor
reload with
type RELOAD_FOR_INPUT_ADDRESS kills reload register of current one
with type
RELOAD_FOR_INPADDR_ADDRESS.
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c (revision 185992)
+++ gcc/reload1.c (working copy)
@@ -5429,6 +5429,13 @@
if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
return 0;
+ /* Reload register of reload with type RELOAD_FOR_INPADDR_ADDRESS
+ could be killed if the register is also used by reload with type
+ RELOAD_FOR_INPUT_ADDRESS, so check it. */
+ if (type == RELOAD_FOR_INPADDR_ADDRESS
+ && TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], regno))
+ return 0;
+
for (i = opnum + 1; i < reload_n_operands; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
@@ -5503,6 +5510,13 @@
|| TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno))
return 0;
+ /* Reload register of reload with type RELOAD_FOR_OUTADDR_ADDRESS
+ could be killed if the register is also used by reload with type
+ RELOAD_FOR_OUTPUT_ADDRESS, so check it. */
+ if (type == RELOAD_FOR_OUTADDR_ADDRESS
+ && TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], regno))
+ return 0;
+
return 1;
default: