https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101129

--- Comment #6 from Bill Schmidt <wschmidt at gcc dot gnu.org> ---
Testing this patch.

diff --git a/gcc/config/rs6000/rs6000-p8swap.c
b/gcc/config/rs6000/rs6000-p8swap.c
index 21cbcb2e28a..00693e6dc60 100644
--- a/gcc/config/rs6000/rs6000-p8swap.c
+++ b/gcc/config/rs6000/rs6000-p8swap.c
@@ -1523,6 +1523,20 @@ replace_swap_with_copy (swap_web_entry *insn_entry,
unsigned i)
   insn->set_deleted ();
 }

+/* INSN is known to contain a SUBREG, which we can normally handle,
+   but if the SUBREG itself contains a MULT then we need to leave it alone
+   to avoid turning a mult_hipart into a mult_lopart, for example.  */
+static bool
+has_part_mult (rtx_insn *insn)
+{
+  rtx body = PATTERN (insn);
+  rtx src = SET_SRC (body);
+  if (GET_CODE (src) != SUBREG)
+    return false;
+  rtx inner = XEXP (src, 0);
+  return (GET_CODE (inner) == MULT);
+}
+
 /* Make NEW_MEM_EXP's attributes and flags resemble those of
    ORIGINAL_MEM_EXP.  */
 static void
@@ -2501,6 +2515,9 @@ rs6000_analyze_swaps (function *fun)
                    insn_entry[uid].is_swappable = 0;
                  else if (special != SH_NONE)
                    insn_entry[uid].special_handling = special;
+                 else if (insn_entry[uid].contains_subreg
+                          && has_part_mult (insn))
+                   insn_entry[uid].is_swappable = 0;
                  else if (insn_entry[uid].contains_subreg)
                    insn_entry[uid].special_handling = SH_SUBREG;
                }

Reply via email to