gen_lowpart_general handles forming a SUBREG of a MEM by using adjust_address to rework and validate a new version of the MEM. However, gen_highpart does not attempt this and simply returns (SUBREG (MEM)) if the change is not 'obviously' safe. Improve on that by using a similar approach so that gen_lowpart and gen_highpart are mostly symmetrical in this regard.
gcc/ChangeLog: PR target/102125 * emit-rtl.c (gen_highpart): If simplify_gen_subreg returns SUBREG (MEM) for a MEM, use adjust_address to produce a new MEM. --- gcc/emit-rtl.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 77ea8948ee8..bacf6fffa22 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1597,6 +1597,14 @@ gen_highpart (machine_mode mode, rtx x) result = validize_mem (result); gcc_assert (result); } + /* It may also just put a SUBREG wrapper around a MEM for the same + reason. */ + else if (GET_CODE (result) == SUBREG && MEM_P (SUBREG_REG (result)) + && MEM_P (x)) + { + poly_int64 offset = subreg_highpart_offset (mode, GET_MODE (x)); + result = adjust_address (x, mode, offset); + } return result; }