This patch uses subreg_size_lowpart_offset in places that open-coded the calculation. The reload use (and the LRA one that was based on it) seemed to ignore the BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN case; it's not obvious whether that was deliberate or an oversight.
Tested on aarch64-linux-gnu and x86_64-linux-gnu, and by making sure that there were no differences in testsuite assembly output for one target per CPU. OK to install? Richard 2017-08-23 Richard Sandiford <richard.sandif...@linaro.org> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@arm.com> gcc/ * lra-spills.c (assign_mem_slot): Use subreg_size_lowpart_offset. * regcprop.c (maybe_mode_change): Likewise. * reload1.c (alter_reg): Likewise. Index: gcc/lra-spills.c =================================================================== --- gcc/lra-spills.c 2017-05-18 07:51:05.680420976 +0100 +++ gcc/lra-spills.c 2017-08-23 10:46:45.029672093 +0100 @@ -153,9 +153,7 @@ assign_mem_slot (int i) /* On a big endian machine, the "address" of the slot is the address of the low part that fits its inherent mode. */ - if (BYTES_BIG_ENDIAN && inherent_size < total_size) - adjust += (total_size - inherent_size); - + adjust += subreg_size_lowpart_offset (inherent_size, total_size); x = adjust_address_nv (x, GET_MODE (regno_reg_rtx[i]), adjust); /* Set all of the memory attributes as appropriate for a spill. */ Index: gcc/regcprop.c =================================================================== --- gcc/regcprop.c 2017-08-23 10:46:06.553156355 +0100 +++ gcc/regcprop.c 2017-08-23 10:46:45.029672093 +0100 @@ -410,13 +410,9 @@ maybe_mode_change (machine_mode orig_mod int use_nregs = hard_regno_nregs[copy_regno][new_mode]; int copy_offset = GET_MODE_SIZE (copy_mode) / copy_nregs * (copy_nregs - use_nregs); - int offset - = GET_MODE_SIZE (orig_mode) - GET_MODE_SIZE (new_mode) - copy_offset; - int byteoffset = offset % UNITS_PER_WORD; - int wordoffset = offset - byteoffset; - - offset = ((WORDS_BIG_ENDIAN ? wordoffset : 0) - + (BYTES_BIG_ENDIAN ? byteoffset : 0)); + unsigned int offset + = subreg_size_lowpart_offset (GET_MODE_SIZE (new_mode) + copy_offset, + GET_MODE_SIZE (orig_mode)); regno += subreg_regno_offset (regno, orig_mode, offset, new_mode); if (HARD_REGNO_MODE_OK (regno, new_mode)) return gen_raw_REG (new_mode, regno); Index: gcc/reload1.c =================================================================== --- gcc/reload1.c 2017-08-22 17:14:30.339835581 +0100 +++ gcc/reload1.c 2017-08-23 10:46:45.030666964 +0100 @@ -2253,8 +2253,7 @@ alter_reg (int i, int from_reg, bool don /* On a big endian machine, the "address" of the slot is the address of the low part that fits its inherent mode. */ - if (BYTES_BIG_ENDIAN && inherent_size < total_size) - adjust += (total_size - inherent_size); + adjust += subreg_size_lowpart_offset (inherent_size, total_size); /* If we have any adjustment to make, or if the stack slot is the wrong mode, make a new stack slot. */