On Wed, Jul 20, 2011 at 9:46 PM, Uros Bizjak <ubiz...@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.
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.  */

Reply via email to