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))

Reply via email to