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]
Other format: [Raw text]

[cft/reload] maybe fix target/14532


I don't see how calling find_reloads_address_1 on CONSTs would do anything.
How would we determine what we can or cannot do?  I think better would be
to not create this kind of rtl in the first place.

The following appears to work on the given test case, but probably needs a
bit o testing to figure out if it's safe or not.


r~


	* reload.c (find_reloads_subreg_address): When applying an offset
	to a non-offsettable address, force the original into a register.

Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.229.4.5
diff -u -p -r1.229.4.5 reload.c
--- reload.c	10 Mar 2004 01:51:01 -0000	1.229.4.5
+++ reload.c	16 Mar 2004 04:46:48 -0000
@@ -5847,8 +5847,10 @@ find_reloads_subreg_address (rtx x, int 
 	  if (force_replace
 	      || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
 	    {
-	      unsigned outer_size = GET_MODE_SIZE (GET_MODE (x));
+	      enum machine_mode mode = GET_MODE (x);
+	      unsigned outer_size = GET_MODE_SIZE (mode);
 	      unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
+	      rtx orig_addr, new_addr;
 	      int offset;
 
 	      /* For big-endian paradoxical subregs, SUBREG_BYTE does not
@@ -5858,17 +5860,16 @@ find_reloads_subreg_address (rtx x, int 
 	      else
 		offset = SUBREG_BYTE (x);
 
-	      XEXP (tem, 0) = plus_constant (XEXP (tem, 0), offset);
-	      PUT_MODE (tem, GET_MODE (x));
-
+	      /* Calculate the new address, but don't install it yet.  */
+	      orig_addr = XEXP (tem, 0);
+	      new_addr = plus_constant (orig_addr, offset);
+	 
 	      /* If this was a paradoxical subreg that we replaced, the
 		 resulting memory must be sufficiently aligned to allow
 		 us to widen the mode of the memory.  */
 	      if (outer_size > inner_size && STRICT_ALIGNMENT)
 		{
-		  rtx base;
-
-		  base = XEXP (tem, 0);
+		  rtx base = new_addr;
 		  if (GET_CODE (base) == PLUS)
 		    {
 		      if (GET_CODE (XEXP (base, 1)) == CONST_INT
@@ -5882,9 +5883,31 @@ find_reloads_subreg_address (rtx x, int 
 		    return x;
 		}
 
-	      find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
-				    &XEXP (tem, 0), opnum, ADDR_TYPE (type),
-				    ind_levels, insn);
+	      /* If the original address is offsettable, then go ahead and
+		 use the offset address we computed earlier.  If it isn't,
+		 then we have to work harder in order to avoid creating
+		 something (involving const and unspec) that we can't fix.  */
+	      if (offsettable_memref_p (tem))
+		{
+	          XEXP (tem, 0) = new_addr;
+	          PUT_MODE (tem, mode);
+
+		  find_reloads_address (mode, &tem, new_addr,
+					&XEXP (tem, 0), opnum,
+					ADDR_TYPE (type), ind_levels, insn);
+		}
+	      else
+		{
+		  new_addr = gen_rtx_PLUS (Pmode, orig_addr, GEN_INT (offset));
+	          XEXP (tem, 0) = new_addr;
+	          PUT_MODE (tem, mode);
+
+		  find_reloads_address_part (XEXP (new_addr, 0),
+					     &XEXP (new_addr, 0),
+					     MODE_BASE_REG_CLASS (mode),
+					     Pmode, opnum, ADDR_TYPE (type),
+					     ind_levels);
+		}
 
 	      /* If this is not a toplevel operand, find_reloads doesn't see
 		 this substitution.  We have to emit a USE of the pseudo so


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