Message ID | 20110625184145.GA9684@intel.com |
---|---|
State | New |
Headers | show |
On Mon, Jun 27, 2011 at 7:52 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote: > H.J. Lu wrote: > >> Given input: >> >> (plus:SI (subreg:SI (plus:DI (reg/f:DI 7 sp) >> (const_int 16 [0x10])) 0) >> (const_int -1 [0xffffffffffffffff])) > > Once again, this seems weird as legitimate address ... If this really > can occur validly, there'll probably need to be an insn+splitter and/or > a secondard reload provided by the back-end to handle it. This is the valid memory address for any instructions which take a memory operand under x32. How will insn+splitter and/or a secondard reload help x32 here? Do I implement such a thing for all instructions which take a memory operand? >> reloads tries to add >> >> (subreg:SI (plus:DI (reg/f:DI 7 sp) >> (const_int 16 [0x10])) 0) >> >> to >> >> (reg:SI 1 dx) > > And what happens then? If the only problem is that this is then > rejected by the back-end, I don't think we need to change anything > in gen_reload ... > > With your change below, it seems you're just falling through to > the generic gen_rtx_SET case, right? How does this help? > I added ix86_simplify_base_disp to i386.c to handle such cases. It translates (set (reg:SI 40 r11) (plus:SI (plus:SI (mult:SI (reg:SI 1 dx) (const_int 8)) (subreg:SI (plus:DI (reg/f:DI 7 sp) (const_int CONST1)) 0)) (const_int CONST2))) into (set (reg:SI 40 r11) (plus:SI (plus:SI (mult:SI (reg:SI 1 dx) (const_int 8)) (reg/f:SI 7 sp)) (const_int [CONST1 + CONST2]))) It also translates (plus:DI (zero_extend:DI (plus:SI (plus:SI (reg:SI 4 si [70]) (reg:SI 2 cx [86])) (const_int CONST1))) (const_int CONST2)) into (plus:DI (zero_extend:DI (plus:SI (reg:SI 4 si [70]) (reg:SI 2 cx [86])) (const_int [CONST1 + CONST2]))) It also translates (plus:SI (plus:SI (plus:SI (reg:SI 4 si [70]) (reg:SI 2 cx [86])) (symbol_ref:SI ("A.193.2210"))) (const_int CONST)) into (plus:SI (plus:SI (reg:SI 4 si [70]) (reg:SI 2 cx [86])) (const (plus:SI (symbol_ref:SI ("A.193.2210")) (const_int CONST)))) It aslo translates (set (reg:SI 40 r11) (plus:SI (plus:SI (reg:SI 1 dx) (subreg:SI (plus:DI (reg/f:DI 7 sp) (const_int CONST1)) 0)) (const_int CONST2))) into (set (reg:SI 40 r11) (plus:SI (plus:SI (reg:SI 1 dx) (reg/f:SI 7 sp)) (const_int [CONST1 + CONST2])))
diff --git a/gcc/reload1.c b/gcc/reload1.c index e65503b..1864ae6 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -5544,6 +5544,54 @@ substitute (rtx *where, const_rtx what, rtx repl) } } +/* Return TRUE if IN is a valid plus operation. */ + +static bool +reload_plus_ok (rtx in) +{ + if (GET_CODE (in) == PLUS) + { + rtx op0 = XEXP (in, 0); + rtx op1 = XEXP (in, 1); + if ((REG_P (op0) + || GET_CODE (op0) == SUBREG + || MEM_P (op0)) + && (REG_P (op1) + || GET_CODE (op1) == SUBREG + || CONSTANT_P (op1) + || MEM_P (op1))) + { + rtx subreg, other; + if (GET_CODE (op0) == SUBREG) + { + subreg = SUBREG_REG (op0); + other = op1; + } + else if (GET_CODE (op1) == SUBREG) + { + subreg = SUBREG_REG (op1); + other = op0; + } + else + return true; + + /* Avoid + (plus (subreg (plus (reg) + (const_int NNN))) + (const_int NNN)) + */ + if (GET_CODE (subreg) == PLUS + && (CONSTANT_P (XEXP (subreg, 0)) + || CONSTANT_P (XEXP (subreg, 1))) + && CONSTANT_P (other)) + return false; + + return true; + } + } + return false; +} + /* The function returns TRUE if chain of reload R1 and R2 (in any order) can be evaluated without usage of intermediate register for the reload containing another reload. It is important to see @@ -5596,14 +5644,7 @@ gen_reload_chain_without_interm_reg_p (int r1, int r2) opposite SUBREG on OUT. Likewise for a paradoxical SUBREG on OUT. */ strip_paradoxical_subreg (&in, &out); - if (GET_CODE (in) == PLUS - && (REG_P (XEXP (in, 0)) - || GET_CODE (XEXP (in, 0)) == SUBREG - || MEM_P (XEXP (in, 0))) - && (REG_P (XEXP (in, 1)) - || GET_CODE (XEXP (in, 1)) == SUBREG - || CONSTANT_P (XEXP (in, 1)) - || MEM_P (XEXP (in, 1)))) + if (reload_plus_ok (in)) { insn = emit_insn (gen_rtx_SET (VOIDmode, out, in)); code = recog_memoized (insn); @@ -8449,14 +8490,7 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type) ??? At some point, this whole thing needs to be rethought. */ - if (GET_CODE (in) == PLUS - && (REG_P (XEXP (in, 0)) - || GET_CODE (XEXP (in, 0)) == SUBREG - || MEM_P (XEXP (in, 0))) - && (REG_P (XEXP (in, 1)) - || GET_CODE (XEXP (in, 1)) == SUBREG - || CONSTANT_P (XEXP (in, 1)) - || MEM_P (XEXP (in, 1)))) + if (reload_plus_ok (in)) { /* We need to compute the sum of a register or a MEM and another register, constant, or MEM, and put it into the reload