Hi,

This change deals with reloading a subreg(reg) using the inner mode
to prevent partial spilling of data like in the case described here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78660#c8

No test case for now but I am investigating a targeted test using
the RTL frontend for later submission.

Thanks,
Matthew

gcc/
        PR target/78660
        * lra-constraints.c (curr_insn_transform): Handle
        WORD_REGISTER_OPERATIONS requirements when reloading SUBREGs.
---
 gcc/lra-constraints.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 22323b2..f29308f 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -4130,7 +4130,14 @@ curr_insn_transform (bool check_only_p)
                          && (goal_alt[i] == NO_REGS
                              || (simplify_subreg_regno
                                  (ira_class_hard_regs[goal_alt[i]][0],
-                                  GET_MODE (reg), byte, mode) >= 0)))))
+                                  GET_MODE (reg), byte, mode) >= 0)))
+                     /* WORD_REGISTER_OPERATIONS targets require the register
+                        to be reloaded when the outer mode is strictly
+                        narrower than the inner mode.  Note: It may be
+                        necessary to always reload the inner mode here but it
+                        requires further investigation.  */
+                     || (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (reg))
+                         && WORD_REGISTER_OPERATIONS)))
                {
                  if (type == OP_OUT)
                    type = OP_INOUT;
-- 
2.2.1

Reply via email to