This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[RFA]: Fix pb in find_reloads_subreg_address()


Hi!

I found a problem in the reload pass, in find_reloads_subreg_address()
the type of the reload is changed which is wrong.

For 68HC11 target, the following insn:

(insn 531 527 534 (parallel[
            (set (mem/f:DF (reg/f:HI 53) 0)
                (subreg:DF (reg/v:DI 55) 0))
            (clobber (scratch:HI))
        ] ) 11 {movdf} (insn_list 527 (nil))
    (expr_list:REG_DEAD (reg/v:DI 55)
        (expr_list:REG_UNUSED (scratch:HI)
            (nil))))


has these registers (reg_equiv_memory_loc):

  reg:HI 53 => (mem:HI (plus:HI (reg/f:HI 46 *sframe)
        (const_int 17 [0x11])) 0)

  reg:DI 55 => (mem:DI (plus:HI (reg/f:HI 46 *sframe)
        (const_int 19 [0x13])) 0)


It generates the following reloads:

Reload 0: reload_in (HI) = (reg/f:HI 9 *_.frame)
        A_REGS, RELOAD_FOR_OPADDR_ADDR (opnum = 0)
        reload_in_reg: (reg/f:HI 9 *_.frame)
        reload_reg_rtx: (reg:HI 2 y)
Reload 1: reload_in (HI) = (mem:HI (plus:HI (reg/f:HI 9 *_.frame)
                                                        (const_int 17 [0x11])) 0)
        A_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 0), can't combine
        reload_in_reg: (reg/f:HI 53)
        reload_reg_rtx: (reg:HI 2 y)
Reload 2: A_REGS, RELOAD_FOR_OPADDR_ADDR (opnum = 1)
        reload_in_reg: (reg/f:HI 9 *_.frame)
Reload 3: reload_out (DF) = (mem/f:DF (reg/f:HI 53) 0)
        NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
        reload_out_reg: (mem/f:DF (reg/f:HI 53) 0)
Reload 4: reload_out (HI) = (scratch:HI)
        D_REGS, RELOAD_FOR_INSN (opnum = 2)
        reload_out_reg: (scratch:HI)
        reload_reg_rtx: (reg:HI 1 d)


Reload 0 and 1 are for (reg:HI 53).
Reload 2 is for (reg:DI 55).
Reload 4 is the scratch.


And the insn is reloaded as follows:

(insn 531 1052 534 (parallel[
            (set (mem/f:DF (reg:HI 2 y) 0)
                (mem:DF (plus:HI (reg:HI 2 y)
                        (const_int 19 [0x13])) 0))
            (clobber (reg:HI 1 d))
        ] ) 11 {movdf} (insn_list 527 (nil))
    (expr_list:REG_DEAD (reg/v:DI 55)
        (expr_list:REG_UNUSED (reg:HI 1 d)
            (nil))))


This is wrong because the reload 0 and reload 2 are using
the same register (reg:HI 2 y).  This is so because the
reload 2 is specified with RELOAD_FOR_OPADDR_ADDR which indicates
that the lifetime of this reload ends with RELOAD_FOR_OPERAND_ADDRESS.
(nothing wrong in reload1.c)

I tracked down the problem in find_reloads() and discovered that
the problem is in find_reloads_subreg_address().  This function
is called for '(subreg:DF (reg/v:DI 55) 0)' with type=RELOAD_FOR_INPUT_ADDRESS,
and it calls find_reloads_address() as follows (reload.c, line 5683):

	      find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
				    &XEXP (tem, 0), opnum,
                                    ADDR_TYPE (type),
				    ind_levels, insn);

and 'tem' is the reg_equiv_memory_loc[] of the register 55 (+ register
elimination,...). Due to ADDR_TYPE (type), the type of reloads 
generated for 'tem' is 'RELOAD_FOR_INPADDR_ADDRESS'.  This is wrong 
because at the end this will be changed to RELOAD_FOR_OPADDR_ADDR,
the type is still RELOAD_FOR_INPUT_ADDRESS (which is what 'tem' is really).

The good call is:

	      find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
				    &XEXP (tem, 0), opnum,
                                    type,
				    ind_levels, insn);

This is also much more coherent with the way the (REG N) are handled
in find_reloads_toplev(): the register is replaced by its corresponding
reg_equiv_memory_loc[] and find_reloads_address() is called with
the *same* type. See line 4262.


Can you integrate or approve this patch for the 3.0 branch?

Thanks,

	Stephane

2001-02-24  Stephane Carrez  <Stephane.Carrez@worldnet.fr>

	* reload.c (find_reloads_subreg_address): Call find_reloads_address
	with the same reload type.
--- /src/gnu/cygnus/gcc/gcc/reload.c	Sun Jan 28 09:19:22 2001
+++ gcc/reload.c	Sat Feb 24 19:35:15 2001
@@ -5681,7 +5681,7 @@ find_reloads_subreg_address (x, force_re
 		}
 
 	      find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
-				    &XEXP (tem, 0), opnum, ADDR_TYPE (type),
+				    &XEXP (tem, 0), opnum, type,
 				    ind_levels, insn);
 
 	      /* If this is not a toplevel operand, find_reloads doesn't see

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]