Patchwork [RFC,i386] : Allow SUBREG_PROMOTED_UNSIGNED_P subregs in address

login
register
mail settings
Submitter Uros Bizjak
Date July 20, 2011, 9:49 p.m.
Message ID <CAFULd4Z1FbQ_z7aei5u5Z-B7D2ezzTsDEg4X84_p_EgcxXY2qg@mail.gmail.com>
Download mbox | patch
Permalink /patch/105847/
State New
Headers show

Comments

Uros Bizjak - July 20, 2011, 9:49 p.m.
On Wed, Jul 20, 2011 at 9:46 PM, Uros Bizjak <ubizjak@gmail.com> wrote:

> I have looked at example in rs6000.c, the only target that uses
> SUBREG_PROMOTED_UNSIGNED_P. Looking at other sources, S_P_U_P is used
> in conjunction with SUBREG_PROMOTED_VAR. It looks to me that using the
> combination should be OK to determine if subreg is correct.

Attached patch adds paradoxical subreg handling. Patch is diffed vs.
current mainline.

H.J., does it work for x32 branch? Does it make any difference?

(BTW: You will need [1] from the trunk).

[1] http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01693.html

Uros.
H.J. Lu - July 20, 2011, 10:46 p.m.
On Wed, Jul 20, 2011 at 2:49 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Wed, Jul 20, 2011 at 9:46 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
>
>> I have looked at example in rs6000.c, the only target that uses
>> SUBREG_PROMOTED_UNSIGNED_P. Looking at other sources, S_P_U_P is used
>> in conjunction with SUBREG_PROMOTED_VAR. It looks to me that using the
>> combination should be OK to determine if subreg is correct.
>
> Attached patch adds paradoxical subreg handling. Patch is diffed vs.
> current mainline.
>
> H.J., does it work for x32 branch? Does it make any difference?
>
> (BTW: You will need [1] from the trunk).
>
> [1] http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01693.html
>

I will give it a try.
H.J. Lu - July 21, 2011, 1:15 p.m.
On Wed, Jul 20, 2011 at 3:46 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Jul 20, 2011 at 2:49 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> On Wed, Jul 20, 2011 at 9:46 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
>>
>>> I have looked at example in rs6000.c, the only target that uses
>>> SUBREG_PROMOTED_UNSIGNED_P. Looking at other sources, S_P_U_P is used
>>> in conjunction with SUBREG_PROMOTED_VAR. It looks to me that using the
>>> combination should be OK to determine if subreg is correct.
>>
>> Attached patch adds paradoxical subreg handling. Patch is diffed vs.
>> current mainline.
>>
>> H.J., does it work for x32 branch? Does it make any difference?
>>
>> (BTW: You will need [1] from the trunk).
>>
>> [1] http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01693.html
>>
>
> I will give it a try.
>

No regressions on x32.

Thanks.

Patch

Index: i386.c
===================================================================
--- i386.c	(revision 176536)
+++ i386.c	(working copy)
@@ -11089,8 +11089,11 @@  ix86_decompose_address (rtx addr, struct
     base = addr;
   else if (GET_CODE (addr) == SUBREG)
     {
-      /* Allow only subregs of DImode hard regs.  */
-      if (register_no_elim_operand (SUBREG_REG (addr), DImode))
+      /* Allow only promoted paradoxical subregs
+	 or subregs of DImode hard regs.  */
+      if ((SUBREG_PROMOTED_VAR_P (addr)
+	   && SUBREG_PROMOTED_UNSIGNED_P (addr) > 0)
+	  || register_no_elim_operand (SUBREG_REG (addr), DImode))
 	base = addr;
       else
 	return 0;
@@ -11148,8 +11151,11 @@  ix86_decompose_address (rtx addr, struct
 	      break;
 
 	    case SUBREG:
-	      /* Allow only subregs of DImode hard regs in PLUS chains.  */
-	      if (!register_no_elim_operand (SUBREG_REG (op), DImode))
+	      /* Allow only promoted paradoxical subregs
+		 or subregs of DImode hard regs in PLUS chains.  */
+	      if (!((SUBREG_PROMOTED_VAR_P (op)
+		     && SUBREG_PROMOTED_UNSIGNED_P (op) > 0)
+		    || register_no_elim_operand (SUBREG_REG (op), DImode)))
 		return 0;
 	      /* FALLTHRU */
 
@@ -11201,9 +11207,12 @@  ix86_decompose_address (rtx addr, struct
     {
       if (REG_P (index))
 	;
-      /* Allow only subregs of DImode hard regs.  */
+      /* Allow only promoted paradoxical subregs
+	 or subregs of DImode hard regs.  */
       else if (GET_CODE (index) == SUBREG
-	       && !register_no_elim_operand (SUBREG_REG (index), DImode))
+	       && !((SUBREG_PROMOTED_VAR_P (index)
+		     && SUBREG_PROMOTED_UNSIGNED_P (index) > 0)
+		    || register_no_elim_operand (SUBREG_REG (index), DImode)))
 	return 0;
     }
 
@@ -11650,7 +11659,9 @@  ix86_legitimate_address_p (enum machine_
       else if (GET_CODE (base) == SUBREG && REG_P (SUBREG_REG (base)))
 	{
 	  reg = SUBREG_REG (base);
-	  gcc_assert (register_no_elim_operand (reg, DImode));
+	  gcc_assert ((SUBREG_PROMOTED_VAR_P (base)
+		       && SUBREG_PROMOTED_UNSIGNED_P (base) > 0)
+		      || register_no_elim_operand (reg, DImode));
 	}
       else
 	/* Base is not a register.  */
@@ -11675,7 +11686,9 @@  ix86_legitimate_address_p (enum machine_
       else if (GET_CODE (index) == SUBREG && REG_P (SUBREG_REG (index)))
 	{
 	  reg = SUBREG_REG (index);
-	  gcc_assert (register_no_elim_operand (reg, DImode));
+	  gcc_assert ((SUBREG_PROMOTED_VAR_P (index)
+		       && SUBREG_PROMOTED_UNSIGNED_P (index) > 0)
+		      || register_no_elim_operand (reg, DImode));
 	}
       else
 	/* Index is not a register.  */