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:

Reply via email to