From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpbgbr1.qq.com (smtpbgbr1.qq.com [54.207.19.206]) by sourceware.org (Postfix) with ESMTPS id AE3093861806 for ; Wed, 20 Dec 2023 06:50:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AE3093861806 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=rivai.ai Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=rivai.ai ARC-Filter: OpenARC Filter v1.0.0 sourceware.org AE3093861806 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=54.207.19.206 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1703055025; cv=none; b=x0xHvpVqr+YFj84vwbVbRLvsiFL0twTNVBbKotnW/rCPOy0ou+Z7omjGMfrkruop1qUBePgJsPzo8ip2PLxifiUZ8LL1t8dxHbKN2cz+AlGZW/fWoxQpN0W30Z836w74kV4EWMQVZnypP54FNat8Ey/42w3WQYi4d8IUamo/gV8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1703055025; c=relaxed/simple; bh=qPod2cOX80E/sT6Z95s2YEPrqhUm6s4wZBi+Xnf52yA=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=rtKVr4sabg9m0ugRz3UbHS1I/fEocYSQRUm2juVP53e3dQUjeoEAFr+N2quT/5q0rICsuW4RihDvNMVSH/R4IwPhewZqF663rPW2+d+fta9dOmLbTch2USKioPwD5oMninf+bKsZJIN0+1ytrMbsItRi/YfSld4CSrJP747JCsg= ARC-Authentication-Results: i=1; server2.sourceware.org X-QQ-mid: bizesmtp65t1703055013tlaohky7 Received: from rios-cad121.hadoop.rioslab.org ( [58.60.1.9]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 20 Dec 2023 14:50:12 +0800 (CST) X-QQ-SSF: 01400000000000G0V000000A0000000 X-QQ-FEAT: cvpDInk2tjW/kP6rK4Co9cgIyNZYac4dG0dbtOKy0sL+FntKFoGl3c4OogXkI iEHt3MT0R9znTyEqVkPWwy/MSvXBYtGa4f4WzCyL/vqUslkLpwr6W3oruujqaKXTR0GRrHS QGIVoEOTGI/4joqT8o5dUJ+2B7Ssms0x8ji1Ndb8bjzF8CJOqlMwlBlCXsKLub+H3GJBxDR ueJBKUfsqn/fsjgrcUvIcBVKzio+xe6Q//9am6EDfT9HKqEwfZrBixVfVKmdz998DsIxf8v Wxlmr4MxyDbMF6zoSCMKgQsplAjiKOdhnwZTiMllmUoZJfCfNuyO2oD+qKbS012EIicw0Aa JoG0S2/Jql3mx8Lr3dqq31o8Jir/B/YEhvFRaDFbxEsuPvWnTm7YXpNgwjpjNuE3LdQcUbo yqM2NEZGvho= X-QQ-GoodBg: 2 X-BIZMAIL-ID: 12284277938912589088 From: Juzhe-Zhong To: gcc-patches@gcc.gnu.org Cc: kito.cheng@gmail.com, kito.cheng@sifive.com, jeffreyalaw@gmail.com, rdapp.gcc@gmail.com, Juzhe-Zhong Subject: [PATCH] RISC-V: Fix bug of VSETVL fusion Date: Wed, 20 Dec 2023 14:50:11 +0800 Message-Id: <20231220065011.2696544-1-juzhe.zhong@rivai.ai> X-Mailer: git-send-email 2.36.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:rivai.ai:qybglogicsvrgz:qybglogicsvrgz7a-one-0 X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00,GIT_PATCH_0,KAM_DMARC_STATUS,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This patch fixes bugs in the fusion of this following case: li a5,-1 vmv.s.x v0,a5 -> demand any non-zero AVL vsetvli a5, ... Incorrect fusion after VSETVL PASS: li a5,-1 vsetvli a5... vmv.s.x v0, a5 --> a5 is modified as incorrect value. We disallow this incorrect fusion above. Full coverage testing of RV64 and RV32 no regression. PR target/113087 gcc/ChangeLog: * config/riscv/riscv-vsetvl.cc: Disallow fusion when VL modification pollutes non AVL use. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr113087-1.c: New test. --- gcc/config/riscv/riscv-vsetvl.cc | 41 ++++++++++++- .../gcc.target/riscv/rvv/autovec/pr113087-1.c | 60 +++++++++++++++++++ 2 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113087-1.c diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 6af8d8429ab..eabaef80f89 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -1128,6 +1128,27 @@ public: return gen_vsetvl_discard_result (Pmode, avl, sew, vlmul, ta, ma); } + /* Return true that the non-AVL operands of THIS will be modified + if we fuse the VL modification from OTHER into THIS. */ + bool vl_modify_non_avl_op_p (const vsetvl_info &other) const + { + /* We don't need to worry about any operands from THIS be + modified by OTHER vsetvl since we OTHER vsetvl doesn't + modify any operand. */ + if (!other.has_vl ()) + return false; + + /* THIS VL operand always preempt OTHER VL operand. */ + if (this->has_vl ()) + return false; + + /* If THIS has non IMM AVL and THIS is AVL compatible with + OTHER, the AVL value of THIS is same as VL value of OTHER. */ + if (!this->has_imm_avl ()) + return false; + return find_access (this->get_insn ()->uses (), REGNO (other.get_vl ())); + } + bool operator== (const vsetvl_info &other) const { gcc_assert (!uninit_p () && !other.uninit_p () @@ -1896,6 +1917,20 @@ public: gcc_unreachable (); } + bool vl_not_in_conflict_p (const vsetvl_info &prev, const vsetvl_info &next) + { + /* We don't fuse this following case: + + li a5, -1 + vmv.s.x v0, a5 -- PREV + vsetvli a5, ... -- NEXT + + Don't fuse NEXT into PREV. + */ + return !prev.vl_modify_non_avl_op_p (next) + && !next.vl_modify_non_avl_op_p (prev); + } + bool avl_compatible_p (const vsetvl_info &prev, const vsetvl_info &next) { gcc_assert (prev.valid_p () && next.valid_p ()); @@ -1953,7 +1988,8 @@ public: { bool compatible_p = sew_lmul_compatible_p (prev, next) && policy_compatible_p (prev, next) - && avl_compatible_p (prev, next); + && avl_compatible_p (prev, next) + && vl_not_in_conflict_p (prev, next); return compatible_p; } @@ -1961,7 +1997,8 @@ public: { bool available_p = sew_lmul_available_p (prev, next) && policy_available_p (prev, next) - && avl_available_p (prev, next); + && avl_available_p (prev, next) + && vl_not_in_conflict_p (prev, next); gcc_assert (!available_p || compatible_p (prev, next)); return available_p; } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113087-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113087-1.c new file mode 100644 index 00000000000..7b743effc79 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113087-1.c @@ -0,0 +1,60 @@ +/* { dg-do run } */ +/* { dg-options "-O3" } */ +/* { dg-require-effective-target riscv_v } */ + +#include +int (e) (int g, int h) { return h > 0x10 || g > 0xFFFFFFFF >> h ? g : g << h; } +struct i +{ + int j; + int l : 1; +}; +struct m +{ + char k; + int n; +}; +char o; +char p; +short s; +int q; +struct m r; +int v; +int t; +short z; +long ac; +int ad; +int ae; + +static void +ai (struct i bf) +{ + for (; v; v++) + r.k = 0; + do + ac ^= bf.j; + while (bf.j < 0); + s = 0; + if (bf.l) + q |= 0x800; +} + +int +main () +{ + struct i aw = {0xE00, 1}; + o = 4; + s = p; + ai (aw); + t = 1; + ++p; + for (; t <= 7; t++) + { + ad &= 1; + (o &= 1 - e (0x40000012, ++ae)) & (z |= 1); + } + for (; r.n;) + ; + assert (o == 4); + return 0; +} -- 2.36.3