summaryrefslogtreecommitdiff
path: root/0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch
diff options
context:
space:
mode:
Diffstat (limited to '0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch')
-rw-r--r--0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch140
1 files changed, 140 insertions, 0 deletions
diff --git a/0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch b/0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch
new file mode 100644
index 0000000..95b50de
--- /dev/null
+++ b/0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch
@@ -0,0 +1,140 @@
+From 29a71fc5cbfc3b5e4649abf51740daed5ea243bd Mon Sep 17 00:00:00 2001
+From: Richard Sandiford <richard.sandiford@arm.com>
+Date: Tue, 5 Dec 2023 09:20:55 +0000
+Subject: [PATCH 134/157] [Backport][SME] lra: Updates of biggest mode for hard
+ regs [PR112278]
+
+Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=6e2e0ce6795c863e295eb33559f8dc0500297da3
+
+LRA keeps track of the biggest mode for both hard registers and
+pseudos. The updates assume that the modes are ordered, i.e. that
+we can tell whether one is no bigger than the other at compile time.
+
+That is (or at least seemed to be) a reasonable restriction for pseudos.
+But it isn't necessarily so for hard registers, since the uses of hard
+registers can be logically distinct. The testcase is an example of this.
+
+The biggest mode of hard registers is also special for other reasons.
+As the existing comment says:
+
+ /* A reg can have a biggest_mode of VOIDmode if it was only ever seen as
+ part of a multi-word register. In that case, just use the reg_rtx
+ mode. Do the same also if the biggest mode was larger than a register
+ or we can not compare the modes. Otherwise, limit the size to that of
+ the biggest access in the function or to the natural mode at least. */
+
+This patch applies the same approach to the updates.
+
+gcc/
+ PR rtl-optimization/112278
+ * lra-int.h (lra_update_biggest_mode): New function.
+ * lra-coalesce.cc (merge_pseudos): Use it.
+ * lra-lives.cc (process_bb_lives): Likewise.
+ * lra.cc (new_insn_reg): Likewise.
+
+gcc/testsuite/
+ PR rtl-optimization/112278
+ * gcc.target/aarch64/sve/pr112278.c: New test.
+---
+ gcc/lra-coalesce.cc | 4 +---
+ gcc/lra-int.h | 15 +++++++++++++++
+ gcc/lra-lives.cc | 4 +---
+ gcc/lra.cc | 5 ++---
+ gcc/testsuite/gcc.target/aarch64/sve/pr112278.c | 15 +++++++++++++++
+ 5 files changed, 34 insertions(+), 9 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/pr112278.c
+
+diff --git a/gcc/lra-coalesce.cc b/gcc/lra-coalesce.cc
+index c82934569..901a44663 100644
+--- a/gcc/lra-coalesce.cc
++++ b/gcc/lra-coalesce.cc
+@@ -112,9 +112,7 @@ merge_pseudos (int regno1, int regno2)
+ = (lra_merge_live_ranges
+ (lra_reg_info[first].live_ranges,
+ lra_copy_live_range_list (lra_reg_info[first2].live_ranges)));
+- if (partial_subreg_p (lra_reg_info[first].biggest_mode,
+- lra_reg_info[first2].biggest_mode))
+- lra_reg_info[first].biggest_mode = lra_reg_info[first2].biggest_mode;
++ lra_update_biggest_mode (first, lra_reg_info[first2].biggest_mode);
+ }
+
+ /* Change pseudos in *LOC on their coalescing group
+diff --git a/gcc/lra-int.h b/gcc/lra-int.h
+index 04baefef3..040e87d11 100644
+--- a/gcc/lra-int.h
++++ b/gcc/lra-int.h
+@@ -525,4 +525,19 @@ lra_assign_reg_val (int from, int to)
+ lra_reg_info[to].offset = lra_reg_info[from].offset;
+ }
+
++/* Update REGNO's biggest recorded mode so that it includes a reference
++ in mode MODE. */
++inline void
++lra_update_biggest_mode (int regno, machine_mode mode)
++{
++ if (!ordered_p (GET_MODE_SIZE (lra_reg_info[regno].biggest_mode),
++ GET_MODE_SIZE (mode)))
++ {
++ gcc_checking_assert (HARD_REGISTER_NUM_P (regno));
++ lra_reg_info[regno].biggest_mode = reg_raw_mode[regno];
++ }
++ else if (partial_subreg_p (lra_reg_info[regno].biggest_mode, mode))
++ lra_reg_info[regno].biggest_mode = mode;
++}
++
+ #endif /* GCC_LRA_INT_H */
+diff --git a/gcc/lra-lives.cc b/gcc/lra-lives.cc
+index a755464ee..fb4a12304 100644
+--- a/gcc/lra-lives.cc
++++ b/gcc/lra-lives.cc
+@@ -770,9 +770,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
+ {
+ int regno = reg->regno;
+
+- if (partial_subreg_p (lra_reg_info[regno].biggest_mode,
+- reg->biggest_mode))
+- lra_reg_info[regno].biggest_mode = reg->biggest_mode;
++ lra_update_biggest_mode (regno, reg->biggest_mode);
+ if (HARD_REGISTER_NUM_P (regno))
+ lra_hard_reg_usage[regno] += freq;
+ }
+diff --git a/gcc/lra.cc b/gcc/lra.cc
+index 1444cb759..8fda432f1 100644
+--- a/gcc/lra.cc
++++ b/gcc/lra.cc
+@@ -559,9 +559,8 @@ new_insn_reg (rtx_insn *insn, int regno, enum op_type type,
+ lra_insn_reg *ir = lra_insn_reg_pool.allocate ();
+ ir->type = type;
+ ir->biggest_mode = mode;
+- if (NONDEBUG_INSN_P (insn)
+- && partial_subreg_p (lra_reg_info[regno].biggest_mode, mode))
+- lra_reg_info[regno].biggest_mode = mode;
++ if (NONDEBUG_INSN_P (insn))
++ lra_update_biggest_mode (regno, mode);
+ ir->subreg_p = subreg_p;
+ ir->early_clobber_alts = early_clobber_alts;
+ ir->regno = regno;
+diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr112278.c b/gcc/testsuite/gcc.target/aarch64/sve/pr112278.c
+new file mode 100644
+index 000000000..4f56add2b
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/aarch64/sve/pr112278.c
+@@ -0,0 +1,15 @@
++#include <arm_neon.h>
++#include <arm_sve.h>
++
++void
++f (void)
++{
++ {
++ register svint8_t v0 asm ("z0");
++ asm volatile ("" : "=w" (v0));
++ }
++ {
++ register int8x8x4_t v0 asm ("v0");
++ asm volatile ("" : "=w" (v0));
++ }
++}
+--
+2.33.0
+