From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1130) id E99903858D28; Tue, 5 Dec 2023 09:21:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E99903858D28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1701768067; bh=UGeqAzNIG8BVcOrXNypnfzzhTI4+cXWPIPFxB7wmK5Q=; h=From:To:Subject:Date:From; b=XAJFLHc8/1WGO1RabyBMGQJl4i/b22NWtop0JSTkOT6b0bUPl0zurY8RMMayaXu1A jEesR4bMpIajC0PO49r+d+HS+BUZH6Kh2DzYW3KQjD+rvhRrQBgQWu8/08LeNqsQHe Et8AoNzCCVy55SDqz5wbLnp9qJNci5lb+2WgrTGk= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Richard Sandiford To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-6139] lra: Updates of biggest mode for hard regs [PR112278] X-Act-Checkin: gcc X-Git-Author: Richard Sandiford X-Git-Refname: refs/heads/trunk X-Git-Oldrev: 1a84af19cd18730477dbceaebc45466c3fd77b60 X-Git-Newrev: 6e2e0ce6795c863e295eb33559f8dc0500297da3 Message-Id: <20231205092107.E99903858D28@sourceware.org> Date: Tue, 5 Dec 2023 09:21:07 +0000 (GMT) List-Id: https://gcc.gnu.org/g:6e2e0ce6795c863e295eb33559f8dc0500297da3 commit r14-6139-g6e2e0ce6795c863e295eb33559f8dc0500297da3 Author: Richard Sandiford Date: Tue Dec 5 09:20:55 2023 +0000 lra: Updates of biggest mode for hard regs [PR112278] 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. Diff: --- 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(-) diff --git a/gcc/lra-coalesce.cc b/gcc/lra-coalesce.cc index 04a5bbd714b..d8ca096c35f 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 d7ec7c7dc7f..5cdf92be7fc 100644 --- a/gcc/lra-int.h +++ b/gcc/lra-int.h @@ -535,4 +535,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 f60e564da82..0b204232849 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 c917a1adee2..29e2a3506e1 100644 --- a/gcc/lra.cc +++ b/gcc/lra.cc @@ -581,9 +581,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 00000000000..4f56add2b0a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr112278.c @@ -0,0 +1,15 @@ +#include +#include + +void +f (void) +{ + { + register svint8_t v0 asm ("z0"); + asm volatile ("" : "=w" (v0)); + } + { + register int8x8x4_t v0 asm ("v0"); + asm volatile ("" : "=w" (v0)); + } +}