diff mbox

RFC: PATCH: PR rtl-optimization/48155: Reload doesn't handle subreg properly

Message ID 20110317213002.GA3755@intel.com
State New
Headers show

Commit Message

H.J. Lu March 17, 2011, 9:30 p.m. UTC
Hi,

Reload tries to handle plus operation such as:

	     (plus (subreg (plus (reg)
				 (const_int NNN)))
		   (const_int NNN))

and nothing good comes out of it. I am not quite happy with this patch.
Any comments?

Thanks.

H.J.
---
commit 17ee20b0bd58b0e5d5bbdd79014eb370ab590001
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Mar 17 13:57:14 2011 -0700

    Add and use reload_plus_ok.
diff mbox

Patch

diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
index 52ff01d..6d5eda6 100644
--- a/gcc/ChangeLog.x32
+++ b/gcc/ChangeLog.x32
@@ -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.
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 3d58e58..14537bd 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -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