From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7924) id DE5403858C35; Wed, 6 Dec 2023 14:36:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DE5403858C35 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1701873367; bh=4W2sa1IqkDZc5ll6FQIvXYyU8fSOP1EPKj8I6CmUqa8=; h=From:To:Subject:Date:From; b=nH0qGbMvVJO6kwbFIKfdJpDU1EzKgbC+O33v3TBz5hQB/wSEI0kDreqW8ALYpo9K8 azoSNR6aTGnbHIl6LfUsErCaX34WuxUee3Xnl9X1n+aFURF85iykU4U5zmeYPjKg46 8Jp24deCwuepSA2aVSiKARfvO03RsdBr5NUCBiTQ= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Pan Li To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-6222] RISC-V: Fix VSETVL PASS bug X-Act-Checkin: gcc X-Git-Author: Juzhe-Zhong X-Git-Refname: refs/heads/master X-Git-Oldrev: c1e54c82a9e1855499ef7bb8827540e6a097532b X-Git-Newrev: c9d5b46a25547035e381b0246de5cb553ca8b02d Message-Id: <20231206143607.DE5403858C35@sourceware.org> Date: Wed, 6 Dec 2023 14:36:07 +0000 (GMT) List-Id: https://gcc.gnu.org/g:c9d5b46a25547035e381b0246de5cb553ca8b02d commit r14-6222-gc9d5b46a25547035e381b0246de5cb553ca8b02d Author: Juzhe-Zhong Date: Wed Dec 6 22:26:46 2023 +0800 RISC-V: Fix VSETVL PASS bug As PR112855 mentioned, the VSETVL PASS insert vsetvli in unexpected location. Due to 2 reasons: 1. incorrect transparant computation LCM data. We need to check VL operand defs and uses. 2. incorrect fusion of unrelated edge which is the edge never reach the vsetvl expression. PR target/112855 gcc/ChangeLog: * config/riscv/riscv-vsetvl.cc (pre_vsetvl::compute_lcm_local_properties): Fix transparant LCM data. (pre_vsetvl::earliest_fuse_vsetvl_info): Disable earliest fusion for unrelated edge. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr112855.c: New test. Diff: --- gcc/config/riscv/riscv-vsetvl.cc | 66 +++++++++++++++++++++- .../gcc.target/riscv/rvv/autovec/pr112855.c | 26 +++++++++ 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 484a8b3a514..68f0be7e81d 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -2034,7 +2034,7 @@ private: gcc_unreachable (); } - bool anticpatable_exp_p (const vsetvl_info &header_info) + bool anticipated_exp_p (const vsetvl_info &header_info) { if (!header_info.has_nonvlmax_reg_avl () && !header_info.has_vl ()) return true; @@ -2645,7 +2645,7 @@ pre_vsetvl::compute_lcm_local_properties () } } - for (const insn_info *insn : bb->real_nondebug_insns ()) + for (insn_info *insn : bb->real_nondebug_insns ()) { if (info.has_nonvlmax_reg_avl () && find_access (insn->defs (), REGNO (info.get_avl ()))) @@ -2653,6 +2653,59 @@ pre_vsetvl::compute_lcm_local_properties () bitmap_clear_bit (m_transp[bb_index], i); break; } + + if (info.has_vl () + && reg_mentioned_p (info.get_vl (), insn->rtl ())) + { + if (find_access (insn->defs (), REGNO (info.get_vl ()))) + /* We can't fuse vsetvl into the blocks that modify the + VL operand since successors of such blocks will need + the value of those blocks are defining. + + bb 4: def a5 + / \ + bb 5:use a5 bb 6:vsetvl a5, 5 + + The example above shows that we can't fuse vsetvl + from bb 6 into bb 4 since the successor bb 5 is using + the value defined in bb 4. */ + ; + else + { + /* We can't fuse vsetvl into the blocks that use the + VL operand which has different value from the + vsetvl info. + + bb 4: def a5 + | + bb 5: use a5 + | + bb 6: def a5 + | + bb 7: use a5 + + The example above shows that we can't fuse vsetvl + from bb 6 into bb 5 since their value is different. + */ + resource_info resource + = full_register (REGNO (info.get_vl ())); + def_lookup dl = crtl->ssa->find_def (resource, insn); + def_info *def + = dl.matching_set_or_last_def_of_prev_group (); + gcc_assert (def); + insn_info *def_insn = extract_single_source ( + dyn_cast (def)); + if (def_insn && vsetvl_insn_p (def_insn->rtl ())) + { + vsetvl_info def_info = vsetvl_info (def_insn); + if (m_dem.compatible_p (def_info, info)) + continue; + } + } + + bitmap_clear_bit (m_transp[bb_index], i); + break; + } } } @@ -2663,7 +2716,7 @@ pre_vsetvl::compute_lcm_local_properties () vsetvl_info &footer_info = block_info.get_exit_info (); if (header_info.valid_p () - && (anticpatable_exp_p (header_info) || block_info.full_available)) + && (anticipated_exp_p (header_info) || block_info.full_available)) bitmap_set_bit (m_antloc[bb_index], get_expr_index (m_exprs, header_info)); @@ -2920,6 +2973,13 @@ pre_vsetvl::earliest_fuse_vsetvl_info () || eg->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)) continue; + /* When multiple set bits in earliest edge, such edge may + have infinite loop in preds or succs or multiple conflict + vsetvl expression which make such edge is unrelated. We + don't perform fusion for such situation. */ + if (bitmap_count_bits (e) != 1) + continue; + vsetvl_block_info &src_block_info = get_block_info (eg->src); vsetvl_block_info &dest_block_info = get_block_info (eg->dest); diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112855.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112855.c new file mode 100644 index 00000000000..f1fa6693d2d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112855.c @@ -0,0 +1,26 @@ +/* { dg-do run } */ +/* { dg-options "-O3" } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-require-effective-target riscv_v } */ + +#include +int a; +int b = 100; +int c[25]; +int d; +int main() { + int e; + d = 0; + for (; d < 5; d++) { + e = 0; + for (; e < 5; e++) + c[d * 5 + e] = 0; + } + if (b) + if (a) + for (;;) + ; + b++; + int volatile f = *c; + assert(b == 101); +}