gcc/ChangeLog:

        * regcprop.c (maybe_mode_change): Determine offset relative to
        high or low part depending on endianness.

Bootstrapped and regtested on IBM Z. Ok for mainline and gcc-{11,10,9}?

---
 gcc/regcprop.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/gcc/regcprop.c b/gcc/regcprop.c
index d2a01130fe1..0e1ac12458a 100644
--- a/gcc/regcprop.c
+++ b/gcc/regcprop.c
@@ -414,9 +414,14 @@ maybe_mode_change (machine_mode orig_mode, machine_mode 
copy_mode,
                            copy_nregs, &bytes_per_reg))
        return NULL_RTX;
       poly_uint64 copy_offset = bytes_per_reg * (copy_nregs - use_nregs);
-      poly_uint64 offset
-       = subreg_size_lowpart_offset (GET_MODE_SIZE (new_mode) + copy_offset,
-                                     GET_MODE_SIZE (orig_mode));
+      poly_uint64 offset =
+#if WORDS_BIG_ENDIAN
+       subreg_size_highpart_offset
+#else
+       subreg_size_lowpart_offset
+#endif
+                                   (GET_MODE_SIZE (new_mode) + copy_offset,
+                                    GET_MODE_SIZE (orig_mode));
       regno += subreg_regno_offset (regno, orig_mode, offset, new_mode);
       if (targetm.hard_regno_mode_ok (regno, new_mode))
        return gen_raw_REG (new_mode, regno);
-- 
2.31.1

Reply via email to