https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82569
--- Comment #10 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
Index: cfgexpand.c
===================================================================
--- cfgexpand.c (revision 253921)
+++ cfgexpand.c (working copy)
@@ -3661,7 +3661,9 @@ expand_gimple_stmt_1 (gimple *stmt)
bool promoted = false;
target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
- if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
+ if (GET_CODE (target) == SUBREG
+ && (SUBREG_PROMOTED_VAR_P (target)
+ || TREE_CODE (lhs) == SSA_NAME))
promoted = true;
ops.code = gimple_assign_rhs_code (assign_stmt);
@@ -3693,7 +3695,16 @@ expand_gimple_stmt_1 (gimple *stmt)
;
else if (promoted)
{
- int unsignedp = SUBREG_PROMOTED_SIGN (target);
+ int unsignedp;
+
+ if (SUBREG_PROMOTED_VAR_P (target))
+ unsignedp = SUBREG_PROMOTED_SIGN (target);
+ else
+ {
+ machine_mode pmode = promote_ssa_mode (lhs, &unsignedp);
+ gcc_assert (GET_MODE (SUBREG_REG (target)) == pmode);
+ }
+
/* If TEMP is a VOIDmode constant, use convert_modes to make
sure that we properly convert it. */
if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)