diff --git a/gcc/expr.c b/gcc/expr.c
index 5dd98a9bccc987e500ba066ed1309a0a86aebea9..17f2c2f3b8bf2a9e5447c1dc1dc805380cdd8122 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -690,17 +690,20 @@ convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp)
       && SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp))
     {
       scalar_int_mode int_orig_mode;
+      scalar_int_mode int_inner_mode;
       machine_mode orig_mode = GET_MODE (x);
       x = gen_lowpart (int_mode, SUBREG_REG (x));
 
       /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
 	 the original mode, but narrower than the inner mode.  */
       if (GET_CODE (x) == SUBREG
-	  && GET_MODE_PRECISION (subreg_promoted_mode (x))
-	     > GET_MODE_PRECISION (int_mode)
 	  && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
 	  && GET_MODE_PRECISION (int_mode)
-	     > GET_MODE_PRECISION (int_orig_mode))
+	     > GET_MODE_PRECISION (int_orig_mode)
+	  && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (x)),
+				     &int_inner_mode)
+	  && GET_MODE_PRECISION (int_inner_mode)
+	     > GET_MODE_PRECISION (int_mode))
 	{
 	  SUBREG_PROMOTED_VAR_P (x) = 1;
 	  SUBREG_PROMOTED_SET (x, unsignedp);