From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2153) id 8BA2B3AAA018; Tue, 20 Apr 2021 23:34:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8BA2B3AAA018 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jakub Jelinek To: gcc-cvs@gcc.gnu.org Subject: [gcc r9-9441] dse: Fix up hard reg conflict checking in replace_read [PR99863] X-Act-Checkin: gcc X-Git-Author: Jakub Jelinek X-Git-Refname: refs/heads/releases/gcc-9 X-Git-Oldrev: 41c21d0e51e82c8303a8ca03c69546f86caa1b92 X-Git-Newrev: e9d56fab891afa3d40ed2ad75264c09aee65ab88 Message-Id: <20210420233416.8BA2B3AAA018@sourceware.org> Date: Tue, 20 Apr 2021 23:34:16 +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: Tue, 20 Apr 2021 23:34:16 -0000 https://gcc.gnu.org/g:e9d56fab891afa3d40ed2ad75264c09aee65ab88 commit r9-9441-ge9d56fab891afa3d40ed2ad75264c09aee65ab88 Author: Jakub Jelinek Date: Sat Apr 3 10:07:09 2021 +0200 dse: Fix up hard reg conflict checking in replace_read [PR99863] Since PR37922 fix RTL DSE has hard register conflict checking in replace_read, so that if the replacement sequence sets (or typically just clobbers) some hard register (usually condition codes) we verify that hard register is not live. Unfortunately, it compares the hard reg set clobbered/set by the sequence (regs_set) against the currently live hard register set, but it then emits the insn sequence not at the current insn position, but before store_insn->insn. So, we should not compare against the current live hard register set, but against the hard register live set at the point of the store insn. Fortunately, we already have that remembered in store_insn->fixed_regs_live. In addition to bootstrapping/regtesting this patch on x86_64-linux and i686-linux, I've also added statistics gathering and it seems the only place where we end up rejecting the replace_read is the newly added testcase (the PR37922 is no longer effective at that) and fixed_regs_live has been always non-NULL at the if (store_insn->fixed_regs_live) spot. Rather than having there an assert, I chose to just keep regs_set as is, which means in that hypothetical case where fixed_regs_live wouldn't be computed for some store we'd still accept sequences that don't clobber/set any hard registers and just punt on those that clobber/set those. 2021-04-03 Jakub Jelinek PR rtl-optimization/99863 * dse.c (replace_read): Drop regs_live argument. Instead of regs_live, use store_insn->fixed_regs_live if non-NULL, otherwise punt if insns sequence clobbers or sets any hard registers. * gcc.target/i386/pr99863.c: New test. (cherry picked from commit 7a2f91d413eb7a3eb0ba52c7ac9618a35addd12a) Diff: --- gcc/dse.c | 11 +++++------ gcc/testsuite/gcc.target/i386/pr99863.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/gcc/dse.c b/gcc/dse.c index 4becdcf1cbb..a63890d8f60 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -1922,8 +1922,7 @@ get_stored_val (store_info *store_info, machine_mode read_mode, static bool replace_read (store_info *store_info, insn_info_t store_insn, - read_info_t read_info, insn_info_t read_insn, rtx *loc, - bitmap regs_live) + read_info_t read_info, insn_info_t read_insn, rtx *loc) { machine_mode store_mode = GET_MODE (store_info->mem); machine_mode read_mode = GET_MODE (read_info->mem); @@ -1978,7 +1977,8 @@ replace_read (store_info *store_info, insn_info_t store_insn, for (this_insn = insns; this_insn != NULL_RTX; this_insn = NEXT_INSN (this_insn)) note_stores (PATTERN (this_insn), look_for_hardregs, regs_set); - bitmap_and_into (regs_set, regs_live); + if (store_insn->fixed_regs_live) + bitmap_and_into (regs_set, store_insn->fixed_regs_live); if (!bitmap_empty_p (regs_set)) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -2206,7 +2206,7 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info) offset - store_info->offset, width) && replace_read (store_info, i_ptr, read_info, - insn_info, loc, bb_info->regs_live)) + insn_info, loc)) return; /* The bases are the same, just see if the offsets @@ -2272,8 +2272,7 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info) store_info->width) && all_positions_needed_p (store_info, offset - store_info->offset, width) - && replace_read (store_info, i_ptr, read_info, insn_info, loc, - bb_info->regs_live)) + && replace_read (store_info, i_ptr, read_info, insn_info, loc)) return; remove = canon_true_dependence (store_info->mem, diff --git a/gcc/testsuite/gcc.target/i386/pr99863.c b/gcc/testsuite/gcc.target/i386/pr99863.c new file mode 100644 index 00000000000..3d9d405391e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr99863.c @@ -0,0 +1,33 @@ +/* PR rtl-optimization/99863 */ +/* { dg-do run } */ +/* { dg-options "-O -fno-tree-forwprop -mno-sse2 -Wno-psabi" } */ + +typedef unsigned char __attribute__((__vector_size__ (8))) A; +typedef unsigned char __attribute__((__vector_size__ (32))) B; +typedef unsigned char __attribute__((__vector_size__ (64))) C; +typedef unsigned int __attribute__((__vector_size__ (32))) D; +typedef unsigned int __attribute__((__vector_size__ (64))) E; +typedef unsigned long long F; + +D a; +A b; + +A +foo (E x, F y) +{ + D c = (y <= 0) * a; + x *= (0 < y); + C d = (C) x; + B e = ((union { C a; B b[2];}) d).b[0] + (B) c; + A f = ((union { B a; A b[4];}) e).b[0] + (A) b; + return f; +} + +int +main () +{ + F x = (F) foo ((E) { 3 }, 5); + if (x != 3) + __builtin_abort (); + return 0; +}