@@ -1,5 +1,12 @@
2011-03-16 H.J. Lu <hongjiu.lu@intel.com>
+ PR rtl-optimization/48155
+ * reload1.c (reload_plus_ok): New.
+ (gen_reload_chain_without_interm_reg_p): Use it.
+ (gen_reload): Likewise.
+
+2011-03-16 H.J. Lu <hongjiu.lu@intel.com>
+
PR middle-end/48016
* function.c (expand_function_start): Properly store frame
pointer for non-local goto.
@@ -5516,6 +5516,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
@@ -5572,14 +5620,7 @@ gen_reload_chain_without_interm_reg_p (int r1, int r2)
&& (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (in)), out)) != 0)
in = SUBREG_REG (in), out = tem;
- 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);
@@ -8456,14 +8497,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