This patch returns false in HARD_REGNO_CALL_PART_CLOBBERED if !HARD_REGNO_MODE_OK.
Returning true for such registers might lead to performance degradation that eat up all performance gained from 4.6 to 4.7 for example. Ok to apply? Johann PR 53595 * config/avr/avr.c (avr_hard_regno_call_part_clobbered): New. * config/avr/avr-protos.h (avr_hard_regno_call_part_clobbered): New. * config/avr/avr.h (HARD_REGNO_CALL_PART_CLOBBERED): Forward to avr_hard_regno_call_part_clobbered.
Index: config/avr/avr-protos.h =================================================================== --- config/avr/avr-protos.h (revision 189011) +++ config/avr/avr-protos.h (working copy) @@ -47,6 +47,7 @@ extern void init_cumulative_args (CUMULA #endif /* TREE_CODE */ #ifdef RTX_CODE +extern int avr_hard_regno_call_part_clobbered (unsigned, enum machine_mode); extern const char *output_movqi (rtx insn, rtx operands[], int *l); extern const char *output_movhi (rtx insn, rtx operands[], int *l); extern const char *output_movsisf (rtx insn, rtx operands[], int *l); Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 189011) +++ config/avr/avr.c (working copy) @@ -8856,6 +8856,28 @@ avr_hard_regno_mode_ok (int regno, enum } +/* Implement `HARD_REGNO_CALL_PART_CLOBBERED'. */ + +int +avr_hard_regno_call_part_clobbered (unsigned regno, enum machine_mode mode) +{ + /* FIXME: This hook gets called with MODE:REGNO combinations that don't + represent valid hard registers like, e.g. HI:29. Returning TRUE + for such registers can lead to performance degradation as mentioned + in PR53595. Thus, report invalid hard registers as FALSE. */ + + if (!avr_hard_regno_mode_ok (regno, mode)) + return 0; + + /* Return true if any of the following boundaries is crossed: + 17/18, 27/28 and 29/30. */ + + return ((regno < 18 && regno + GET_MODE_SIZE (mode) > 18) + || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y) + || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z)); +} + + /* Implement `MODE_CODE_BASE_REG_CLASS'. */ enum reg_class Index: config/avr/avr.h =================================================================== --- config/avr/avr.h (revision 189011) +++ config/avr/avr.h (working copy) @@ -402,10 +402,8 @@ enum reg_class { #define REGNO_OK_FOR_INDEX_P(NUM) 0 -#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ - (((REGNO) < 18 && (REGNO) + GET_MODE_SIZE (MODE) > 18) \ - || ((REGNO) < REG_Y && (REGNO) + GET_MODE_SIZE (MODE) > REG_Y) \ - || ((REGNO) < REG_Z && (REGNO) + GET_MODE_SIZE (MODE) > REG_Z)) +#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ + avr_hard_regno_call_part_clobbered (REGNO, MODE) #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true