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.  */
