rtx_equal_for_field_assignment_p had: x = adjust_address_nv (x, GET_MODE (y), -subreg_lowpart_offset (GET_MODE (x), GET_MODE (y)));
But subreg_lowpart_offset returns an unsigned int and adjust_address_nv takes a HWI, so a subreg offset of 4 would give a memory offset of 0x00000000fffffffffc. The SVE series makes this go away by using HWI-based types for both interfaces, but in this case the fix is also a minor clean-up. Tested on aarch64-linux-gnu, powerpc64le-linux-gnu and x86_64-linux-gnu. OK to install? Richard 2017-10-22 Richard Sandiford <richard.sandif...@linaro.org> gcc/ * combine.c (rtx_equal_for_field_assignment_p): Use byte_lowpart_offset. Index: gcc/combine.c =================================================================== --- gcc/combine.c 2017-10-22 21:04:50.138830154 +0100 +++ gcc/combine.c 2017-10-22 21:04:59.000825360 +0100 @@ -9526,13 +9526,9 @@ rtx_equal_for_field_assignment_p (rtx x, return 0; if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN) return 0; - /* For big endian, adjust the memory offset. */ - if (BYTES_BIG_ENDIAN) - x = adjust_address_nv (x, GET_MODE (y), - -subreg_lowpart_offset (GET_MODE (x), - GET_MODE (y))); - else - x = adjust_address_nv (x, GET_MODE (y), 0); + x = adjust_address_nv (x, GET_MODE (y), + byte_lowpart_offset (GET_MODE (y), + GET_MODE (x))); } if (x == y || rtx_equal_p (x, y))