@@ -1043,53 +1043,72 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
1043
1043
Also reload the inner expression if it does not require a secondary
1044
1044
reload but the SUBREG does.
1045
1045
1046
- Finally, reload the inner expression if it is a register that is in
1046
+ Also reload the inner expression if it is a register that is in
1047
1047
the class whose registers cannot be referenced in a different size
1048
1048
and M1 is not the same size as M2. If subreg_lowpart_p is false, we
1049
1049
cannot reload just the inside since we might end up with the wrong
1050
1050
register class. But if it is inside a STRICT_LOW_PART, we have
1051
- no choice, so we hope we do get the right register class there. */
1051
+ no choice, so we hope we do get the right register class there.
1052
+
1053
+ Finally, reload the inner expression if it is a pseudo that will
1054
+ become a MEM and the MEM has a mode-dependent address, as in that
1055
+ case we obviously cannot change the mode of the MEM to that of the
1056
+ containing SUBREG as that would change the interpretation of the
1057
+ address. */
1052
1058
1053
1059
scalar_int_mode inner_mode ;
1054
1060
if (in != 0 && GET_CODE (in ) == SUBREG
1055
- && (subreg_lowpart_p (in ) || strict_low )
1056
1061
&& targetm .can_change_mode_class (GET_MODE (SUBREG_REG (in )),
1057
1062
inmode , rclass )
1058
1063
&& contains_allocatable_reg_of_mode [rclass ][GET_MODE (SUBREG_REG (in ))]
1059
- && (CONSTANT_P (SUBREG_REG (in ))
1060
- || GET_CODE (SUBREG_REG (in )) == PLUS
1061
- || strict_low
1062
- || (((REG_P (SUBREG_REG (in ))
1063
- && REGNO (SUBREG_REG (in )) >= FIRST_PSEUDO_REGISTER )
1064
- || MEM_P (SUBREG_REG (in )))
1065
- && (paradoxical_subreg_p (inmode , GET_MODE (SUBREG_REG (in )))
1066
- || (known_le (GET_MODE_SIZE (inmode ), UNITS_PER_WORD )
1067
- && is_a < scalar_int_mode > (GET_MODE (SUBREG_REG (in )),
1068
- & inner_mode )
1069
- && GET_MODE_SIZE (inner_mode ) <= UNITS_PER_WORD
1070
- && paradoxical_subreg_p (inmode , inner_mode )
1071
- && LOAD_EXTEND_OP (inner_mode ) != UNKNOWN )
1072
- || (WORD_REGISTER_OPERATIONS
1073
- && partial_subreg_p (inmode , GET_MODE (SUBREG_REG (in )))
1074
- && (known_equal_after_align_down
1075
- (GET_MODE_SIZE (inmode ) - 1 ,
1076
- GET_MODE_SIZE (GET_MODE (SUBREG_REG (in ))) - 1 ,
1077
- UNITS_PER_WORD )))))
1078
- || (REG_P (SUBREG_REG (in ))
1079
- && REGNO (SUBREG_REG (in )) < FIRST_PSEUDO_REGISTER
1080
- /* The case where out is nonzero
1081
- is handled differently in the following statement. */
1082
- && (out == 0 || subreg_lowpart_p (in ))
1083
- && (complex_word_subreg_p (inmode , SUBREG_REG (in ))
1084
- || !targetm .hard_regno_mode_ok (subreg_regno (in ), inmode )))
1085
- || (secondary_reload_class (1 , rclass , inmode , in ) != NO_REGS
1086
- && (secondary_reload_class (1 , rclass , GET_MODE (SUBREG_REG (in )),
1087
- SUBREG_REG (in ))
1088
- == NO_REGS ))
1064
+ && (strict_low
1065
+ || (subreg_lowpart_p (in )
1066
+ && (CONSTANT_P (SUBREG_REG (in ))
1067
+ || GET_CODE (SUBREG_REG (in )) == PLUS
1068
+ || (((REG_P (SUBREG_REG (in ))
1069
+ && REGNO (SUBREG_REG (in )) >= FIRST_PSEUDO_REGISTER )
1070
+ || MEM_P (SUBREG_REG (in )))
1071
+ && (paradoxical_subreg_p (inmode ,
1072
+ GET_MODE (SUBREG_REG (in )))
1073
+ || (known_le (GET_MODE_SIZE (inmode ), UNITS_PER_WORD )
1074
+ && is_a < scalar_int_mode > (GET_MODE (SUBREG_REG
1075
+ (in )),
1076
+ & inner_mode )
1077
+ && GET_MODE_SIZE (inner_mode ) <= UNITS_PER_WORD
1078
+ && paradoxical_subreg_p (inmode , inner_mode )
1079
+ && LOAD_EXTEND_OP (inner_mode ) != UNKNOWN )
1080
+ || (WORD_REGISTER_OPERATIONS
1081
+ && partial_subreg_p (inmode ,
1082
+ GET_MODE (SUBREG_REG (in )))
1083
+ && (known_equal_after_align_down
1084
+ (GET_MODE_SIZE (inmode ) - 1 ,
1085
+ GET_MODE_SIZE (GET_MODE (SUBREG_REG
1086
+ (in ))) - 1 ,
1087
+ UNITS_PER_WORD )))))
1088
+ || (REG_P (SUBREG_REG (in ))
1089
+ && REGNO (SUBREG_REG (in )) < FIRST_PSEUDO_REGISTER
1090
+ /* The case where out is nonzero
1091
+ is handled differently in the following statement. */
1092
+ && (out == 0 || subreg_lowpart_p (in ))
1093
+ && (complex_word_subreg_p (inmode , SUBREG_REG (in ))
1094
+ || !targetm .hard_regno_mode_ok (subreg_regno (in ),
1095
+ inmode )))
1096
+ || (secondary_reload_class (1 , rclass , inmode , in ) != NO_REGS
1097
+ && (secondary_reload_class (1 , rclass ,
1098
+ GET_MODE (SUBREG_REG (in )),
1099
+ SUBREG_REG (in ))
1100
+ == NO_REGS ))
1101
+ || (REG_P (SUBREG_REG (in ))
1102
+ && REGNO (SUBREG_REG (in )) < FIRST_PSEUDO_REGISTER
1103
+ && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (in )),
1104
+ GET_MODE (SUBREG_REG (in )),
1105
+ inmode ))))
1089
1106
|| (REG_P (SUBREG_REG (in ))
1090
- && REGNO (SUBREG_REG (in )) < FIRST_PSEUDO_REGISTER
1091
- && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (in )),
1092
- GET_MODE (SUBREG_REG (in )), inmode ))))
1107
+ && REGNO (SUBREG_REG (in )) >= FIRST_PSEUDO_REGISTER
1108
+ && reg_equiv_mem (REGNO (SUBREG_REG (in )))
1109
+ && (mode_dependent_address_p
1110
+ (XEXP (reg_equiv_mem (REGNO (SUBREG_REG (in ))), 0 ),
1111
+ MEM_ADDR_SPACE (reg_equiv_mem (REGNO (SUBREG_REG (in )))))))))
1093
1112
{
1094
1113
#ifdef LIMIT_RELOAD_CLASS
1095
1114
in_subreg_loc = inloc ;
@@ -3157,6 +3176,19 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
3157
3176
&& paradoxical_subreg_p (operand_mode [i ],
3158
3177
inner_mode )
3159
3178
&& LOAD_EXTEND_OP (inner_mode ) != UNKNOWN )))
3179
+ /* We must force a reload of a SUBREG's inner expression
3180
+ if it is a pseudo that will become a MEM and the MEM
3181
+ has a mode-dependent address, as in that case we
3182
+ obviously cannot change the mode of the MEM to that
3183
+ of the containing SUBREG as that would change the
3184
+ interpretation of the address. */
3185
+ || (REG_P (operand )
3186
+ && REGNO (operand ) >= FIRST_PSEUDO_REGISTER
3187
+ && reg_equiv_mem (REGNO (operand ))
3188
+ && (mode_dependent_address_p
3189
+ (XEXP (reg_equiv_mem (REGNO (operand )), 0 ),
3190
+ (MEM_ADDR_SPACE
3191
+ (reg_equiv_mem (REGNO (operand )))))))
3160
3192
)
3161
3193
force_reload = 1 ;
3162
3194
}
0 commit comments