From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1012) id 4CED23858C3A; Thu, 14 Oct 2021 16:11:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4CED23858C3A MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Vladimir Makarov To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-9154] [PR102627] Use at least natural mode during splitting hard reg live range X-Act-Checkin: gcc X-Git-Author: Vladimir N. Makarov X-Git-Refname: refs/heads/releases/gcc-11 X-Git-Oldrev: 3bf56cdf5ec5e07ea34e6be0110ab8fc76641d87 X-Git-Newrev: 99d21577f8a00196f3133fe1066de6e3e7d180c1 Message-Id: <20211014161150.4CED23858C3A@sourceware.org> Date: Thu, 14 Oct 2021 16:11:50 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Oct 2021 16:11:50 -0000 https://gcc.gnu.org/g:99d21577f8a00196f3133fe1066de6e3e7d180c1 commit r11-9154-g99d21577f8a00196f3133fe1066de6e3e7d180c1 Author: Vladimir N. Makarov Date: Fri Oct 8 10:16:09 2021 -0400 [PR102627] Use at least natural mode during splitting hard reg live range In the PR test case SImode was used to split live range of cx on x86-64 because it was the biggest mode for this hard reg in the function. But all 64-bits of cx contain structure members. We need always to use at least natural mode of hard reg in splitting to fix this problem. gcc/ChangeLog: PR rtl-optimization/102627 * lra-constraints.c (split_reg): Use at least natural mode of hard reg. gcc/testsuite/ChangeLog: PR rtl-optimization/102627 * gcc.target/i386/pr102627.c: New test. Diff: --- gcc/lra-constraints.c | 5 ++-- gcc/testsuite/gcc.target/i386/pr102627.c | 41 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 5c2a2d7ce9c..aaacc4eabed 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -5805,11 +5805,12 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn, 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. */ + the biggest access in the function or to the natural mode at least. */ if (mode == VOIDmode || !ordered_p (GET_MODE_PRECISION (mode), GET_MODE_PRECISION (reg_rtx_mode)) - || paradoxical_subreg_p (mode, reg_rtx_mode)) + || paradoxical_subreg_p (mode, reg_rtx_mode) + || maybe_gt (GET_MODE_PRECISION (reg_rtx_mode), GET_MODE_PRECISION (mode))) { original_reg = regno_reg_rtx[hard_regno]; mode = reg_rtx_mode; diff --git a/gcc/testsuite/gcc.target/i386/pr102627.c b/gcc/testsuite/gcc.target/i386/pr102627.c new file mode 100644 index 00000000000..8ab9acaf002 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr102627.c @@ -0,0 +1,41 @@ +/* PR rtl-optimization/102627 */ +/* { dg-do run } */ +/* { dg-options "-O1" } */ + +int a, f, l, m, q, c, d, g; +long b, e; +struct g { + signed h; + signed i; + unsigned j; + unsigned k; +}; +unsigned n; +char o; +int *p = &m; +long r(int s) { return s && b ?: b; } +long __attribute__((noipa)) v() { + l = 0 || r(n & o); + return q; +} +void w(int, unsigned, struct g x) { + c ?: a; + for (; d < 2; d++) + *p = x.k; +} +struct g __attribute__((noipa)) y() { + struct g h = {3, 908, 1, 20}; + for (; g; g++) + ; + return h; +} +int main() { + long t; + struct g u = y(); + t = e << f; + w(0, t, u); + v(0, 4, 4, 4); + if (m != 20) + __builtin_abort (); + return 0; +}