From patchwork Wed Jul 19 10:11:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Zeng X-Patchwork-Id: 1809792 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R5WqH0BF5z20FK for ; Wed, 19 Jul 2023 20:13:14 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E01CD3884526 for ; Wed, 19 Jul 2023 10:12:55 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from sgoci-sdnproxy-4.icoremail.net (sgoci-sdnproxy-4.icoremail.net [129.150.39.64]) by sourceware.org (Postfix) with ESMTP id DF2F638582BD for ; Wed, 19 Jul 2023 10:12:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DF2F638582BD Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=eswincomputing.com Received: from localhost.localdomain (unknown [10.12.130.38]) by app1 (Coremail) with SMTP id EwgMCgDHZMTttrdkrKE0AA--.63411S5; Wed, 19 Jul 2023 18:12:03 +0800 (CST) From: Xiao Zeng To: gcc-patches@gcc.gnu.org Cc: jeffreyalaw@gmail.com, research_trasio@irq.a4lg.com, kito.cheng@gmail.com, zhengyu@eswincomputing.com, eri-sw-toolchain@eswincomputing.com, Xiao Zeng Subject: [PATCH 1/5] [RISC-V] Recognize Zicond extension Date: Wed, 19 Jul 2023 18:11:52 +0800 Message-Id: <20230719101156.21771-2-zengxiao@eswincomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230719101156.21771-1-zengxiao@eswincomputing.com> References: <20230719101156.21771-1-zengxiao@eswincomputing.com> X-CM-TRANSID: EwgMCgDHZMTttrdkrKE0AA--.63411S5 X-Coremail-Antispam: 1UD129KBjvJXoWxuF4DKFy3CFykGw1kWFyxuFg_yoW5ur1kpa 1kG3yYvw4FqFn2gan7KFW3X3W5Cwsagry5uwn7Cr17A3yUX397JFykKw13GrsxXF4UCrnF 9w47uw4Yv3yYgrDanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUB214x267AKxVW5JVWrJwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jr4l82xGYIkIc2 x26xkF7I0E14v26r1I6r4UM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCY02Avz4vE-syl42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s02 6x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF0x vE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE 42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6x kF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjfUOtC7UUUUU X-CM-SenderInfo: p2hqw5xldrqvxvzl0uprps33xlqjhudrp/ X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This patch is the minimal support for Zicond extension, include the extension name, mask and target defination. gcc/ChangeLog: * common/config/riscv/riscv-common.cc: New extension. * config/riscv/riscv-opts.h (MASK_ZICOND): New mask. (TARGET_ZICOND): New target. gcc/testsuite/ChangeLog: * gcc.target/riscv/attribute-20.c: New test. * gcc.target/riscv/attribute-21.c: New test. --- gcc/common/config/riscv/riscv-common.cc | 3 +++ gcc/config/riscv/riscv-opts.h | 3 +++ gcc/testsuite/gcc.target/riscv/attribute-20.c | 6 ++++++ gcc/testsuite/gcc.target/riscv/attribute-21.c | 6 ++++++ 4 files changed, 18 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-20.c create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-21.c diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 6091d8f281b..8460d83b0f1 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -183,6 +183,8 @@ static const struct riscv_ext_version riscv_ext_version_table[] = {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0}, {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0}, + {"zicond", ISA_SPEC_CLASS_NONE, 1, 0}, + {"zawrs", ISA_SPEC_CLASS_NONE, 1, 0}, {"zba", ISA_SPEC_CLASS_NONE, 1, 0}, @@ -1243,6 +1245,7 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {"zicsr", &gcc_options::x_riscv_zi_subext, MASK_ZICSR}, {"zifencei", &gcc_options::x_riscv_zi_subext, MASK_ZIFENCEI}, + {"zicond", &gcc_options::x_riscv_zi_subext, MASK_ZICOND}, {"zawrs", &gcc_options::x_riscv_za_subext, MASK_ZAWRS}, diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h index cfcf608ea62..cecaee7d200 100644 --- a/gcc/config/riscv/riscv-opts.h +++ b/gcc/config/riscv/riscv-opts.h @@ -236,6 +236,9 @@ enum riscv_entity #define TARGET_ZICBOM ((riscv_zicmo_subext & MASK_ZICBOM) != 0) #define TARGET_ZICBOP ((riscv_zicmo_subext & MASK_ZICBOP) != 0) +#define MASK_ZICOND (1 << 2) +#define TARGET_ZICOND ((riscv_zi_subext & MASK_ZICOND) != 0) + #define MASK_ZFHMIN (1 << 0) #define MASK_ZFH (1 << 1) #define MASK_ZVFHMIN (1 << 2) diff --git a/gcc/testsuite/gcc.target/riscv/attribute-20.c b/gcc/testsuite/gcc.target/riscv/attribute-20.c new file mode 100644 index 00000000000..b69c36cf4f1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-20.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv32i_zicond -mabi=ilp32" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_zicond1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-21.c b/gcc/testsuite/gcc.target/riscv/attribute-21.c new file mode 100644 index 00000000000..160312a0d48 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-21.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv64i_zicond -mabi=lp64" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_zicond1p0\"" } } */ From patchwork Wed Jul 19 10:11:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Zeng X-Patchwork-Id: 1809789 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R5WpS6gk6z20FK for ; Wed, 19 Jul 2023 20:12:32 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 56776385DC1C for ; Wed, 19 Jul 2023 10:12:30 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from zg8tmtu5ljg5lje1ms4xmtka.icoremail.net (zg8tmtu5ljg5lje1ms4xmtka.icoremail.net [159.89.151.119]) by sourceware.org (Postfix) with ESMTP id 979C53856DC6 for ; Wed, 19 Jul 2023 10:12:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 979C53856DC6 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=eswincomputing.com Received: from localhost.localdomain (unknown [10.12.130.38]) by app1 (Coremail) with SMTP id EwgMCgDHZMTttrdkrKE0AA--.63411S6; Wed, 19 Jul 2023 18:12:05 +0800 (CST) From: Xiao Zeng To: gcc-patches@gcc.gnu.org Cc: jeffreyalaw@gmail.com, research_trasio@irq.a4lg.com, kito.cheng@gmail.com, zhengyu@eswincomputing.com, eri-sw-toolchain@eswincomputing.com, Xiao Zeng Subject: [PATCH 2/5] [RISC-V] Generate Zicond instruction for basic semantics Date: Wed, 19 Jul 2023 18:11:53 +0800 Message-Id: <20230719101156.21771-3-zengxiao@eswincomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230719101156.21771-1-zengxiao@eswincomputing.com> References: <20230719101156.21771-1-zengxiao@eswincomputing.com> X-CM-TRANSID: EwgMCgDHZMTttrdkrKE0AA--.63411S6 X-Coremail-Antispam: 1UD129KBjvJXoW3Gw4fGF45Xr43uF4xJrWDurg_yoWxJw1kp3 yDC3yakry8XFZ3G3s3KFW8tw1Ykr1fKayY9r97Gr9FyrWDZ34xK3Wvkryaqrn8Aa1fXr43 XayI9r15u3yUK3DanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUB214x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jryl82xGYIkIc2 x26xkF7I0E14v26r4j6ryUM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCY02Avz4vE-syl42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s02 6x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF0x vE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE 42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6x kF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjfUe1v3UUUUU X-CM-SenderInfo: p2hqw5xldrqvxvzl0uprps33xlqjhudrp/ X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_NONE, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This patch completes the recognition of the basic semantics defined in the spec, namely: Conditional zero, if condition is equal to zero rd = (rs2 == 0) ? 0 : rs1 Conditional zero, if condition is non zero rd = (rs2 != 0) ? 0 : rs1 gcc/ChangeLog: * config/riscv/riscv.md: Include zicond.md * config/riscv/zicond.md: New file. gcc/testsuite/ChangeLog: * gcc.target/riscv/zicond-primitiveSemantics.c: New test. --- gcc/config/riscv/riscv.md | 1 + gcc/config/riscv/zicond.md | 84 +++++++++++++++++++ .../riscv/zicond-primitiveSemantics.c | 49 +++++++++++ 3 files changed, 134 insertions(+) create mode 100644 gcc/config/riscv/zicond.md create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics.c diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index d63b584a4c1..6b8c2e8e268 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3317,3 +3317,4 @@ (include "sifive-7.md") (include "thead.md") (include "vector.md") +(include "zicond.md") diff --git a/gcc/config/riscv/zicond.md b/gcc/config/riscv/zicond.md new file mode 100644 index 00000000000..1cf28589c87 --- /dev/null +++ b/gcc/config/riscv/zicond.md @@ -0,0 +1,84 @@ +;; Machine description for the RISC-V Zicond extension +;; Copyright (C) 2022-23 Free Software Foundation, Inc. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_code_iterator eq_or_ne [eq ne]) +(define_code_attr eqz [(eq "nez") (ne "eqz")]) +(define_code_attr nez [(eq "eqz") (ne "nez")]) + +;; Zicond +(define_insn "*czero.." + [(set (match_operand:GPR 0 "register_operand" "=r") + (if_then_else:GPR (eq_or_ne (match_operand:ANYI 1 "register_operand" "r") + (const_int 0)) + (match_operand:GPR 2 "register_operand" "r") + (const_int 0)))] + "TARGET_ZICOND" + "czero.\t%0,%2,%1" +) + +(define_insn "*czero.." + [(set (match_operand:GPR 0 "register_operand" "=r") + (if_then_else:GPR (eq_or_ne (match_operand:ANYI 1 "register_operand" "r") + (const_int 0)) + (const_int 0) + (match_operand:GPR 2 "register_operand" "r")))] + "TARGET_ZICOND" + "czero.\t%0,%2,%1" +) + +;; Special optimization under eq/ne in primitive semantics +(define_insn "*czero.eqz..opt1" + [(set (match_operand:GPR 0 "register_operand" "=r") + (if_then_else:GPR (eq (match_operand:ANYI 1 "register_operand" "r") + (const_int 0)) + (match_operand:GPR 2 "register_operand" "1") + (match_operand:GPR 3 "register_operand" "r")))] + "TARGET_ZICOND && operands[1] == operands[2]" + "czero.eqz\t%0,%3,%1" +) + +(define_insn "*czero.eqz..opt2" + [(set (match_operand:GPR 0 "register_operand" "=r") + (if_then_else:GPR (eq (match_operand:ANYI 1 "register_operand" "r") + (const_int 0)) + (match_operand:GPR 2 "register_operand" "r") + (match_operand:GPR 3 "register_operand" "1")))] + "TARGET_ZICOND && operands[1] == operands[3]" + "czero.nez\t%0,%2,%1" +) + +(define_insn "*czero.nez..opt3" + [(set (match_operand:GPR 0 "register_operand" "=r") + (if_then_else:GPR (ne (match_operand:ANYI 1 "register_operand" "r") + (const_int 0)) + (match_operand:GPR 2 "register_operand" "r") + (match_operand:GPR 3 "register_operand" "1")))] + "TARGET_ZICOND && operands[1] == operands[3]" + "czero.eqz\t%0,%2,%1" +) + +(define_insn "*czero.nez..opt4" + [(set (match_operand:GPR 0 "register_operand" "=r") + (if_then_else:GPR (ne (match_operand:ANYI 1 "register_operand" "r") + (const_int 0)) + (match_operand:GPR 2 "register_operand" "1") + (match_operand:GPR 3 "register_operand" "r")))] + "TARGET_ZICOND && operands[1] == operands[2]" + "czero.nez\t%0,%3,%1" +) diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics.c new file mode 100644 index 00000000000..76c5019a992 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0"} } */ + +long primitiveSemantics_00(long a, long b) { return a == 0 ? 0 : b; } + +long primitiveSemantics_01(long a, long b) { return a != 0 ? 0 : b; } + +long primitiveSemantics_02(long a, long b) { return a == 0 ? b : 0; } + +long primitiveSemantics_03(long a, long b) { return a != 0 ? b : 0; } + +long primitiveSemantics_04(long a, long b) { + if (a) + b = 0; + return b; +} + +long primitiveSemantics_05(long a, long b) { + if (!a) + b = 0; + return b; +} + +int primitiveSemantics_06(int a, int b) { return a == 0 ? 0 : b; } + +int primitiveSemantics_07(int a, int b) { return a != 0 ? 0 : b; } + +int primitiveSemantics_08(int a, int b) { return a == 0 ? b : 0; } + +int primitiveSemantics_09(int a, int b) { return a != 0 ? b : 0; } + +int primitiveSemantics_10(int a, int b) { + if (a) + b = 0; + return b; +} + +int primitiveSemantics_11(int a, int b) { + if (!a) + b = 0; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 6 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ From patchwork Wed Jul 19 10:11:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Zeng X-Patchwork-Id: 1809793 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R5WqY4Tbnz20FK for ; Wed, 19 Jul 2023 20:13:29 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B37083889E28 for ; Wed, 19 Jul 2023 10:13:06 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from zg8tmja2lje4os4yms4ymjma.icoremail.net (zg8tmja2lje4os4yms4ymjma.icoremail.net [206.189.21.223]) by sourceware.org (Postfix) with ESMTP id ED192385735D for ; Wed, 19 Jul 2023 10:12:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org ED192385735D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=eswincomputing.com Received: from localhost.localdomain (unknown [10.12.130.38]) by app1 (Coremail) with SMTP id EwgMCgDHZMTttrdkrKE0AA--.63411S7; Wed, 19 Jul 2023 18:12:08 +0800 (CST) From: Xiao Zeng To: gcc-patches@gcc.gnu.org Cc: jeffreyalaw@gmail.com, research_trasio@irq.a4lg.com, kito.cheng@gmail.com, zhengyu@eswincomputing.com, eri-sw-toolchain@eswincomputing.com, Xiao Zeng Subject: [PATCH 3/5] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to 0 Date: Wed, 19 Jul 2023 18:11:54 +0800 Message-Id: <20230719101156.21771-4-zengxiao@eswincomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230719101156.21771-1-zengxiao@eswincomputing.com> References: <20230719101156.21771-1-zengxiao@eswincomputing.com> X-CM-TRANSID: EwgMCgDHZMTttrdkrKE0AA--.63411S7 X-Coremail-Antispam: 1UD129KBjvAXoWfGFyfXF47urW7KFWkZF1UWrg_yoW8Xr1kCo ZY9F4rA3WrJr13ur17Ww17Kr17XFW8urs7Ja98Kw4jkFnrJwnY9ws7K3WDA34jvrn3XrWj vrWFgFWxXa97Jrn8n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUYA7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r1rM28IrcIa0x kI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84AC jcxK6xIIjxv20xvE14v26w1j6s0DM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4UJVWxJr 1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE3s1l e2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI 8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwAC jcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc2xSY4AK6svPMxAIw28Icx kI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2Iq xVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42 IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY 6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aV CY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7VU1VOJ5UUUUU== X-CM-SenderInfo: p2hqw5xldrqvxvzl0uprps33xlqjhudrp/ X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_NUMSUBJECT, KAM_SHORT, SPF_HELO_NONE, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This patch completes the recognition of Zicond when the select pattern with condition eq or neq to 0 (using equality as an example), namely: 1 rd = (rs2 == 0) ? non-imm : 0 2 rd = (rs2 == 0) ? non-imm : non-imm 3 rd = (rs2 == 0) ? reg : non-imm 4 rd = (rs2 == 0) ? reg : reg gcc/ChangeLog: * config/riscv/riscv.cc (riscv_rtx_costs): IF_THEN_ELSE costs in Zicond. (riscv_expand_conditional_move): Recognize Zicond. * config/riscv/riscv.md: Zicond patterns. gcc/testsuite/ChangeLog: * gcc.target/riscv/zicond-primitiveSemantics_return_0_imm.c: New test. * gcc.target/riscv/zicond-primitiveSemantics_return_imm_imm.c: New test. * gcc.target/riscv/zicond-primitiveSemantics_return_imm_reg.c: New test. * gcc.target/riscv/zicond-primitiveSemantics_return_reg_reg.c: New test. --- gcc/config/riscv/riscv.cc | 125 ++++++++++++++++++ gcc/config/riscv/riscv.md | 2 +- .../zicond-primitiveSemantics_return_0_imm.c | 65 +++++++++ ...zicond-primitiveSemantics_return_imm_imm.c | 73 ++++++++++ ...zicond-primitiveSemantics_return_imm_reg.c | 65 +++++++++ ...zicond-primitiveSemantics_return_reg_reg.c | 65 +++++++++ 6 files changed, 394 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_0_imm.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_imm.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_reg.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_reg_reg.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 38d8eb2fcf5..7e6b24bd232 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2448,6 +2448,17 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN *total = COSTS_N_INSNS (1); return true; } + else if (TARGET_ZICOND && outer_code == SET && + ((GET_CODE (XEXP (x, 1)) == REG && XEXP (x, 2) == const0_rtx) || + (GET_CODE (XEXP (x, 2)) == REG && XEXP (x, 1) == const0_rtx) || + (GET_CODE (XEXP (x, 1)) == REG && GET_CODE (XEXP (x, 2)) && + XEXP (x, 1) == XEXP (XEXP (x, 0), 0)) || + (GET_CODE (XEXP (x, 1)) == REG && GET_CODE (XEXP (x, 2)) && + XEXP (x, 2) == XEXP (XEXP (x, 0), 0)))) + { + *total = 0; + return true; + } else if (LABEL_REF_P (XEXP (x, 1)) && XEXP (x, 2) == pc_rtx) { if (equality_operator (XEXP (x, 0), mode) @@ -3501,6 +3512,120 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt) cond, cons, alt))); return true; } + else if (TARGET_ZICOND + && (code == EQ || code == NE) + && GET_MODE_CLASS (mode) == MODE_INT) + { + need_eq_ne_p = true; + /* 0 + imm */ + if (GET_CODE (cons) == CONST_INT && cons == const0_rtx + && GET_CODE (alt) == CONST_INT && alt != const0_rtx) + { + riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p); + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + alt = force_reg (mode, alt); + emit_insn (gen_rtx_SET (dest, + gen_rtx_IF_THEN_ELSE (mode, cond, + cons, alt))); + return true; + } + /* imm + imm */ + else if (GET_CODE (cons) == CONST_INT && cons != const0_rtx + && GET_CODE (alt) == CONST_INT && alt != const0_rtx) + { + riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p); + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + alt = force_reg (mode, alt); + rtx temp1 = gen_reg_rtx (mode); + rtx temp2 = GEN_INT(-1 * INTVAL (cons)); + riscv_emit_binary(PLUS, temp1, alt, temp2); + emit_insn (gen_rtx_SET (dest, + gen_rtx_IF_THEN_ELSE (mode, cond, + const0_rtx, alt))); + riscv_emit_binary(PLUS, dest, dest, cons); + return true; + } + /* imm + reg */ + else if (GET_CODE (cons) == CONST_INT && cons != const0_rtx + && GET_CODE (alt) == REG) + { + /* Optimize for register value of 0. */ + if (op0 == alt && op1 == const0_rtx) + { + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + cons = force_reg (mode, cons); + emit_insn (gen_rtx_SET (dest, + gen_rtx_IF_THEN_ELSE (mode, cond, + cons, alt))); + return true; + } + riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p); + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + rtx temp1 = gen_reg_rtx (mode); + rtx temp2 = GEN_INT(-1 * INTVAL (cons)); + riscv_emit_binary(PLUS, temp1, alt, temp2); + emit_insn (gen_rtx_SET (dest, + gen_rtx_IF_THEN_ELSE (mode, cond, + const0_rtx, alt))); + riscv_emit_binary(PLUS, dest, dest, cons); + return true; + } + /* imm + 0 */ + else if (GET_CODE (cons) == CONST_INT && cons != const0_rtx + && GET_CODE (alt) == CONST_INT && alt == const0_rtx) + { + riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p); + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + cons = force_reg (mode, cons); + emit_insn (gen_rtx_SET (dest, + gen_rtx_IF_THEN_ELSE (mode, cond, + cons, alt))); + return true; + } + /* reg + imm */ + else if (GET_CODE (cons) == REG + && GET_CODE (alt) == CONST_INT && alt != const0_rtx) + { + /* Optimize for register value of 0. */ + if (op0 == cons && op1 == const0_rtx) + { + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + alt = force_reg (mode, alt); + emit_insn (gen_rtx_SET (dest, + gen_rtx_IF_THEN_ELSE (mode, cond, + cons, alt))); + return true; + } + riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p); + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + rtx temp1 = gen_reg_rtx (mode); + rtx temp2 = GEN_INT(-1 * INTVAL (alt)); + riscv_emit_binary(PLUS, temp1, cons, temp2); + emit_insn (gen_rtx_SET (dest, + gen_rtx_IF_THEN_ELSE (mode, cond, + temp1, const0_rtx))); + riscv_emit_binary(PLUS, dest, dest, alt); + return true; + } + /* reg + reg */ + else if (GET_CODE (cons) == REG && GET_CODE (alt) == REG) + { + rtx reg1 = gen_reg_rtx (mode); + rtx reg2 = gen_reg_rtx (mode); + riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p); + rtx cond1 = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + rtx cond2 = gen_rtx_fmt_ee (code == NE ? EQ : NE, + GET_MODE (op0), op0, op1); + emit_insn (gen_rtx_SET (reg2, + gen_rtx_IF_THEN_ELSE (mode, cond2, + const0_rtx, cons))); + emit_insn (gen_rtx_SET (reg1, + gen_rtx_IF_THEN_ELSE (mode, cond1, + const0_rtx, alt))); + riscv_emit_binary(IOR, dest, reg1, reg2); + return true; + } + } return false; } diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 6b8c2e8e268..b4147c7a79c 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -2484,7 +2484,7 @@ (if_then_else:GPR (match_operand 1 "comparison_operator") (match_operand:GPR 2 "reg_or_0_operand") (match_operand:GPR 3 "sfb_alu_operand")))] - "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV" + "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND" { if (riscv_expand_conditional_move (operands[0], operands[1], operands[2], operands[3])) diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_0_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_0_imm.c new file mode 100644 index 00000000000..4948558a187 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_0_imm.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0"} } */ + +long primitiveSemantics_return_0_imm_00(long a, long b) { + return a == 0 ? 0 : 3; +} + +long primitiveSemantics_return_0_imm_01(long a, long b) { + return a != 0 ? 0 : 3; +} + +long primitiveSemantics_return_0_imm_02(long a, long b) { + return a == 0 ? 3 : 0; +} + +long primitiveSemantics_return_0_imm_03(long a, long b) { + return a != 0 ? 3 : 0; +} + +long primitiveSemantics_return_0_imm_04(long a, long b) { + if (a) + b = 0; + else + b = 3; + return b; +} + +long primitiveSemantics_return_0_imm_05(long a, long b) { + if (!a) + b = 0; + else + b = 3; + return b; +} + +int primitiveSemantics_return_0_imm_06(int a, int b) { return a == 0 ? 0 : 3; } + +int primitiveSemantics_return_0_imm_07(int a, int b) { return a != 0 ? 0 : 3; } + +int primitiveSemantics_return_0_imm_08(int a, int b) { return a == 0 ? 3 : 0; } + +int primitiveSemantics_return_0_imm_09(int a, int b) { return a != 0 ? 3 : 0; } + +int primitiveSemantics_return_0_imm_10(int a, int b) { + if (a) + b = 0; + else + b = 3; + return b; +} + +int primitiveSemantics_return_0_imm_11(int a, int b) { + if (!a) + b = 0; + else + b = 3; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 6 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_imm.c new file mode 100644 index 00000000000..ebdca521373 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_imm.c @@ -0,0 +1,73 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */ + +long primitiveSemantics_return_imm_imm_00(long a, long b) { + return a == 0 ? 4 : 6; +} + +long primitiveSemantics_return_imm_imm_01(long a, long b) { + return a != 0 ? 4 : 6; +} + +long primitiveSemantics_return_imm_imm_02(long a, long b) { + return a == 0 ? 6 : 4; +} + +long primitiveSemantics_return_imm_imm_03(long a, long b) { + return a != 0 ? 6 : 4; +} + +long primitiveSemantics_return_imm_imm_04(long a, long b) { + if (a) + b = 4; + else + b = 6; + return b; +} + +long primitiveSemantics_return_imm_imm_05(long a, long b) { + if (!a) + b = 4; + else + b = 6; + return b; +} + +int primitiveSemantics_return_imm_imm_06(int a, int b) { + return a == 0 ? 4 : 6; +} + +int primitiveSemantics_return_imm_imm_07(int a, int b) { + return a != 0 ? 4 : 6; +} + +int primitiveSemantics_return_imm_imm_08(int a, int b) { + return a == 0 ? 6 : 4; +} + +int primitiveSemantics_return_imm_imm_09(int a, int b) { + return a != 0 ? 6 : 4; +} + +int primitiveSemantics_return_imm_imm_10(int a, int b) { + if (a) + b = 4; + else + b = 6; + return b; +} + +int primitiveSemantics_return_imm_imm_11(int a, int b) { + if (!a) + b = 4; + else + b = 6; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 6 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_reg.c new file mode 100644 index 00000000000..12c351dbc16 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_reg.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */ + +long primitiveSemantics_return_imm_reg_00(long a, long b) { + return a == 0 ? 1 : b; +} + +long primitiveSemantics_return_imm_reg_01(long a, long b) { + return a != 0 ? 1 : b; +} + +long primitiveSemantics_return_imm_reg_02(long a, long b) { + return a == 0 ? b : 1; +} + +long primitiveSemantics_return_imm_reg_03(long a, long b) { + return a != 0 ? b : 1; +} + +long primitiveSemantics_return_imm_reg_04(long a, long b) { + if (a) + b = 1; + return b; +} + +long primitiveSemantics_return_imm_reg_05(long a, long b) { + if (!a) + b = 1; + return b; +} + +int primitiveSemantics_return_imm_reg_06(int a, int b) { + return a == 0 ? 1 : b; +} + +int primitiveSemantics_return_imm_reg_07(int a, int b) { + return a != 0 ? 1 : b; +} + +int primitiveSemantics_return_imm_reg_08(int a, int b) { + return a == 0 ? b : 1; +} + +int primitiveSemantics_return_imm_reg_09(int a, int b) { + return a != 0 ? b : 1; +} + +int primitiveSemantics_return_imm_reg_10(int a, int b) { + if (a) + b = 1; + return b; +} + +int primitiveSemantics_return_imm_reg_11(int a, int b) { + if (!a) + b = 1; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 6 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_reg_reg.c new file mode 100644 index 00000000000..4708afa645b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_reg_reg.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */ + +long primitiveSemantics_return_reg_reg_00(long a, long b, long c) { + return a == 0 ? c : b; +} + +long primitiveSemantics_return_reg_reg_01(long a, long b, long c) { + return a != 0 ? c : b; +} + +long primitiveSemantics_return_reg_reg_02(long a, long b, long c) { + return a == 0 ? b : c; +} + +long primitiveSemantics_return_reg_reg_03(long a, long b, long c) { + return a != 0 ? b : c; +} + +long primitiveSemantics_return_reg_reg_04(long a, long b, long c) { + if (a) + b = c; + return b; +} + +long primitiveSemantics_return_reg_reg_05(long a, long b, long c) { + if (!a) + b = c; + return b; +} + +int primitiveSemantics_return_reg_reg_06(int a, int b, int c) { + return a == 0 ? c : b; +} + +int primitiveSemantics_return_reg_reg_07(int a, int b, int c) { + return a != 0 ? c : b; +} + +int primitiveSemantics_return_reg_reg_08(int a, int b, int c) { + return a == 0 ? b : c; +} + +int primitiveSemantics_return_reg_reg_09(int a, int b, int c) { + return a != 0 ? b : c; +} + +int primitiveSemantics_return_reg_reg_10(int a, int b, int c) { + if (a) + b = c; + return b; +} + +int primitiveSemantics_return_reg_reg_11(int a, int b, int c) { + if (!a) + b = c; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 12 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 12 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ From patchwork Wed Jul 19 10:11:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Zeng X-Patchwork-Id: 1809790 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R5Wpp12bWz20FK for ; Wed, 19 Jul 2023 20:12:50 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D756A3860764 for ; Wed, 19 Jul 2023 10:12:39 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from zg8tmja2lje4os4yms4ymjma.icoremail.net (zg8tmja2lje4os4yms4ymjma.icoremail.net [206.189.21.223]) by sourceware.org (Postfix) with ESMTP id 28E6D385AFA3 for ; Wed, 19 Jul 2023 10:12:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 28E6D385AFA3 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=eswincomputing.com Received: from localhost.localdomain (unknown [10.12.130.38]) by app1 (Coremail) with SMTP id EwgMCgDHZMTttrdkrKE0AA--.63411S8; Wed, 19 Jul 2023 18:12:10 +0800 (CST) From: Xiao Zeng To: gcc-patches@gcc.gnu.org Cc: jeffreyalaw@gmail.com, research_trasio@irq.a4lg.com, kito.cheng@gmail.com, zhengyu@eswincomputing.com, eri-sw-toolchain@eswincomputing.com, Xiao Zeng Subject: [PATCH 4/5] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to non-zero Date: Wed, 19 Jul 2023 18:11:55 +0800 Message-Id: <20230719101156.21771-5-zengxiao@eswincomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230719101156.21771-1-zengxiao@eswincomputing.com> References: <20230719101156.21771-1-zengxiao@eswincomputing.com> X-CM-TRANSID: EwgMCgDHZMTttrdkrKE0AA--.63411S8 X-Coremail-Antispam: 1UD129KBjvAXoWftryUXw1rWw47CryfWr13XFb_yoW5Gry8Zo Z5KF1rt3WrCrnrZr15Ww17KF17XFW8Can7Xa98K3yjkFy7Jwn3uw4Ikw18ta4Uur1Iqr48 ZF4FgayIqa98Jrnxn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUYu7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l 84ACjcxK6xIIjxv20xvE14v26w1j6s0DM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4UJV WxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE 3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2I x0cI8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8 JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc2xSY4AK6svPMxAIw2 8IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4l x2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrw CI42IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI 42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z2 80aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7VU17GYJUUUUU== X-CM-SenderInfo: p2hqw5xldrqvxvzl0uprps33xlqjhudrp/ X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_NONE, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This patch completes the recognition of Zicond when the select pattern with condition eq or neq to non-zero (using equality as an example), namely: 1 rd = (rs2 == non-imm) ? 0 : rs1 2 rd = (rs2 == reg) ? 0 : rs1 At the same time, more Zicond non basic semantic test cases have been added. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_expand_conditional_move): Recognize Zicond. gcc/testsuite/ChangeLog: * gcc.target/riscv/zicond-primitiveSemantics_compare_imm.c: New test. * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_0_imm.c: New test. * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c: New test. * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c: New test. * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c: New test. * gcc.target/riscv/zicond-primitiveSemantics_compare_reg.c: New test. * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_0_imm.c: New test. * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c: New test. * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c: New test. * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c: New test. --- gcc/config/riscv/riscv.cc | 16 ++++ .../zicond-primitiveSemantics_compare_imm.c | 57 ++++++++++++++ ...mitiveSemantics_compare_imm_return_0_imm.c | 73 ++++++++++++++++++ ...tiveSemantics_compare_imm_return_imm_imm.c | 73 ++++++++++++++++++ ...tiveSemantics_compare_imm_return_imm_reg.c | 65 ++++++++++++++++ ...tiveSemantics_compare_imm_return_reg_reg.c | 65 ++++++++++++++++ .../zicond-primitiveSemantics_compare_reg.c | 65 ++++++++++++++++ ...mitiveSemantics_compare_reg_return_0_imm.c | 73 ++++++++++++++++++ ...tiveSemantics_compare_reg_return_imm_imm.c | 73 ++++++++++++++++++ ...tiveSemantics_compare_reg_return_imm_reg.c | 65 ++++++++++++++++ ...tiveSemantics_compare_reg_return_reg_reg.c | 77 +++++++++++++++++++ 11 files changed, 702 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_0_imm.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_0_imm.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 7e6b24bd232..9450457e613 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -3625,6 +3625,22 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt) riscv_emit_binary(IOR, dest, reg1, reg2); return true; } + /* For complex semantics of comparison value. + reg + 0 or 0 + reg */ + else if ((GET_CODE (cons) == REG && + GET_CODE (alt) == CONST_INT && + alt == const0_rtx) + || (GET_CODE (alt) == REG && + GET_CODE (cons) == CONST_INT && + cons == const0_rtx)) + { + riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p); + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); + emit_insn (gen_rtx_SET (dest, + gen_rtx_IF_THEN_ELSE (mode, cond, + cons, alt))); + return true; + } } return false; diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm.c new file mode 100644 index 00000000000..6de50039c31 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm.c @@ -0,0 +1,57 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0"} } */ + +long primitiveSemantics_compare_imm_00(long a, long b) { + return a == 2 ? 0 : b; +} + +long primitiveSemantics_compare_imm_01(long a, long b) { + return a != 2 ? 0 : b; +} + +long primitiveSemantics_compare_imm_02(long a, long b) { + return a == 2 ? b : 0; +} + +long primitiveSemantics_compare_imm_03(long a, long b) { + return a != 2 ? b : 0; +} + +long primitiveSemantics_compare_imm_04(long a, long b) { + if (a == 2) + b = 0; + return b; +} + +long primitiveSemantics_compare_imm_05(long a, long b) { + if (!(a == 2)) + b = 0; + return b; +} + +int primitiveSemantics_compare_imm_06(int a, int b) { return a == 2 ? 0 : b; } + +int primitiveSemantics_compare_imm_07(int a, int b) { return a != 2 ? 0 : b; } + +int primitiveSemantics_compare_imm_08(int a, int b) { return a == 2 ? b : 0; } + +int primitiveSemantics_compare_imm_09(int a, int b) { return a != 2 ? b : 0; } + +int primitiveSemantics_compare_imm_10(int a, int b) { + if ((a == 2)) + b = 0; + return b; +} + +int primitiveSemantics_compare_imm_11(int a, int b) { + if (!(a == 2)) + b = 0; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 6 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_0_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_0_imm.c new file mode 100644 index 00000000000..b1e7359e802 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_0_imm.c @@ -0,0 +1,73 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */ + +long primitiveSemantics_compare_imm_return_0_imm_00(long a, long b) { + return a == 2 ? 0 : 5; +} + +long primitiveSemantics_compare_imm_return_0_imm_01(long a, long b) { + return a != 2 ? 0 : 5; +} + +long primitiveSemantics_compare_imm_return_0_imm_02(long a, long b) { + return a == 2 ? 5 : 0; +} + +long primitiveSemantics_compare_imm_return_0_imm_03(long a, long b) { + return a != 2 ? 5 : 0; +} + +long primitiveSemantics_compare_imm_return_0_imm_04(long a, long b) { + if (a == 2) + b = 0; + else + b = 5; + return b; +} + +long primitiveSemantics_compare_imm_return_0_imm_05(long a, long b) { + if (!(a == 2)) + b = 0; + else + b = 5; + return b; +} + +int primitiveSemantics_compare_imm_return_0_imm_06(int a, int b) { + return a == 2 ? 0 : 5; +} + +int primitiveSemantics_compare_imm_return_0_imm_07(int a, int b) { + return a != 2 ? 0 : 5; +} + +int primitiveSemantics_compare_imm_return_0_imm_08(int a, int b) { + return a == 2 ? 5 : 0; +} + +int primitiveSemantics_compare_imm_return_0_imm_09(int a, int b) { + return a != 2 ? 5 : 0; +} + +int primitiveSemantics_compare_imm_return_0_imm_10(int a, int b) { + if ((a == 2)) + b = 0; + else + b = 5; + return b; +} + +int primitiveSemantics_compare_imm_return_0_imm_11(int a, int b) { + if (!(a == 2)) + b = 0; + else + b = 5; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 6 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c new file mode 100644 index 00000000000..bc503e6eafb --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c @@ -0,0 +1,73 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */ + +long primitiveSemantics_compare_imm_return_imm_imm_00(long a, long b) { + return a == 2 ? 7 : 4; +} + +long primitiveSemantics_compare_imm_return_imm_imm_01(long a, long b) { + return a != 2 ? 7 : 4; +} + +long primitiveSemantics_compare_imm_return_imm_imm_02(long a, long b) { + return a == 2 ? 7 : 4; +} + +long primitiveSemantics_compare_imm_return_imm_imm_03(long a, long b) { + return a != 2 ? 7 : 4; +} + +long primitiveSemantics_compare_imm_return_imm_imm_04(long a, long b) { + if (a == 2) + b = 7; + else + b = 4; + return b; +} + +long primitiveSemantics_compare_imm_return_imm_imm_05(long a, long b) { + if (!(a == 2)) + b = 7; + else + b = 4; + return b; +} + +int primitiveSemantics_compare_imm_return_imm_imm_06(int a, int b) { + return a == 2 ? 7 : 4; +} + +int primitiveSemantics_compare_imm_return_imm_imm_07(int a, int b) { + return a != 2 ? 7 : 4; +} + +int primitiveSemantics_compare_imm_return_imm_imm_08(int a, int b) { + return a == 2 ? 7 : 4; +} + +int primitiveSemantics_compare_imm_return_imm_imm_09(int a, int b) { + return a != 2 ? 7 : 4; +} + +int primitiveSemantics_compare_imm_return_imm_imm_10(int a, int b) { + if ((a == 2)) + b = 7; + else + b = 4; + return b; +} + +int primitiveSemantics_compare_imm_return_imm_imm_11(int a, int b) { + if (!(a == 2)) + b = 7; + else + b = 4; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 6 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c new file mode 100644 index 00000000000..2bcad7a51d1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */ + +long primitiveSemantics_compare_imm_return_imm_reg_00(long a, long b) { + return a == 2 ? 3 : b; +} + +long primitiveSemantics_compare_imm_return_imm_reg_01(long a, long b) { + return a != 2 ? 3 : b; +} + +long primitiveSemantics_compare_imm_return_imm_reg_02(long a, long b) { + return a == 2 ? b : 3; +} + +long primitiveSemantics_compare_imm_return_imm_reg_03(long a, long b) { + return a != 2 ? b : 3; +} + +long primitiveSemantics_compare_imm_return_imm_reg_04(long a, long b) { + if (a == 2) + b = 3; + return b; +} + +long primitiveSemantics_compare_imm_return_imm_reg_05(long a, long b) { + if (!(a == 2)) + b = 3; + return b; +} + +int primitiveSemantics_compare_imm_return_imm_reg_06(int a, int b) { + return a == 2 ? 3 : b; +} + +int primitiveSemantics_compare_imm_return_imm_reg_07(int a, int b) { + return a != 2 ? 3 : b; +} + +int primitiveSemantics_compare_imm_return_imm_reg_08(int a, int b) { + return a == 2 ? b : 3; +} + +int primitiveSemantics_compare_imm_return_imm_reg_09(int a, int b) { + return a != 2 ? b : 3; +} + +int primitiveSemantics_compare_imm_return_imm_reg_10(int a, int b) { + if ((a == 2)) + b = 3; + return b; +} + +int primitiveSemantics_compare_imm_return_imm_reg_11(int a, int b) { + if (!(a == 2)) + b = 3; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 6 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c new file mode 100644 index 00000000000..e5d12992dc7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */ + +long primitiveSemantics_compare_imm_return_reg_reg_00(long a, long b, long c) { + return a == 2 ? c : b; +} + +long primitiveSemantics_compare_imm_return_reg_reg_01(long a, long b, long c) { + return a != 2 ? c : b; +} + +long primitiveSemantics_compare_imm_return_reg_reg_02(long a, long b, long c) { + return a == 2 ? b : c; +} + +long primitiveSemantics_compare_imm_return_reg_reg_03(long a, long b, long c) { + return a != 2 ? b : c; +} + +long primitiveSemantics_compare_imm_return_reg_reg_04(long a, long b, long c) { + if (a == 2) + b = c; + return b; +} + +long primitiveSemantics_compare_imm_return_reg_reg_05(long a, long b, long c) { + if (!(a == 2)) + b = c; + return b; +} + +int primitiveSemantics_compare_imm_return_reg_reg_06(int a, int b, int c) { + return a == 2 ? c : b; +} + +int primitiveSemantics_compare_imm_return_reg_reg_07(int a, int b, int c) { + return a != 2 ? c : b; +} + +int primitiveSemantics_compare_imm_return_reg_reg_08(int a, int b, int c) { + return a == 2 ? b : c; +} + +int primitiveSemantics_compare_imm_return_reg_reg_09(int a, int b, int c) { + return a != 2 ? b : c; +} + +int primitiveSemantics_compare_imm_return_reg_reg_10(int a, int b, int c) { + if ((a == 2)) + b = c; + return b; +} + +int primitiveSemantics_compare_imm_return_reg_reg_11(int a, int b, int c) { + if (!(a == 2)) + b = c; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 12 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 12 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg.c new file mode 100644 index 00000000000..072ae2a26ba --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0"} } */ + +long primitiveSemantics_compare_reg_00(long a, long b, long c) { + return a == c ? 0 : b; +} + +long primitiveSemantics_compare_reg_01(long a, long b, long c) { + return a != c ? 0 : b; +} + +long primitiveSemantics_compare_reg_02(long a, long b, long c) { + return a == c ? b : 0; +} + +long primitiveSemantics_compare_reg_03(long a, long b, long c) { + return a != c ? b : 0; +} + +long primitiveSemantics_compare_reg_04(long a, long b, long c) { + if (a == c) + b = 0; + return b; +} + +long primitiveSemantics_compare_reg_05(long a, long b, long c) { + if (!(a == c)) + b = 0; + return b; +} + +int primitiveSemantics_compare_reg_06(int a, int b, int c) { + return a == c ? 0 : b; +} + +int primitiveSemantics_compare_reg_07(int a, int b, int c) { + return a != c ? 0 : b; +} + +int primitiveSemantics_compare_reg_08(int a, int b, int c) { + return a == c ? b : 0; +} + +int primitiveSemantics_compare_reg_09(int a, int b, int c) { + return a != c ? b : 0; +} + +int primitiveSemantics_compare_reg_10(int a, int b, int c) { + if ((a == c)) + b = 0; + return b; +} + +int primitiveSemantics_compare_reg_11(int a, int b, int c) { + if (!(a == c)) + b = 0; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 6 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_0_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_0_imm.c new file mode 100644 index 00000000000..66c7bcb9067 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_0_imm.c @@ -0,0 +1,73 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */ + +long primitiveSemantics_compare_reg_return_0_imm_00(long a, long b, long c) { + return a == c ? 0 : 9; +} + +long primitiveSemantics_compare_reg_return_0_imm_01(long a, long b, long c) { + return a != c ? 0 : 9; +} + +long primitiveSemantics_compare_reg_return_0_imm_02(long a, long b, long c) { + return a == c ? 9 : 0; +} + +long primitiveSemantics_compare_reg_return_0_imm_03(long a, long b, long c) { + return a != c ? 9 : 0; +} + +long primitiveSemantics_compare_reg_return_0_imm_04(long a, long b, long c) { + if (a == c) + b = 0; + else + b = 9; + return b; +} + +long primitiveSemantics_compare_reg_return_0_imm_05(long a, long b, long c) { + if (!(a == c)) + b = 0; + else + b = 9; + return b; +} + +int primitiveSemantics_compare_reg_return_0_imm_06(int a, int b, int c) { + return a == c ? 0 : 9; +} + +int primitiveSemantics_compare_reg_return_0_imm_07(int a, int b, int c) { + return a != c ? 0 : 9; +} + +int primitiveSemantics_compare_reg_return_0_imm_08(int a, int b, int c) { + return a == c ? 9 : 0; +} + +int primitiveSemantics_compare_reg_return_0_imm_09(int a, int b, int c) { + return a != c ? 9 : 0; +} + +int primitiveSemantics_compare_reg_return_0_imm_10(int a, int b, int c) { + if ((a == c)) + b = 0; + else + b = 9; + return b; +} + +int primitiveSemantics_compare_reg_return_0_imm_11(int a, int b, int c) { + if (!(a == c)) + b = 0; + else + b = 9; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 6 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c new file mode 100644 index 00000000000..055ca4833e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c @@ -0,0 +1,73 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */ + +long primitiveSemantics_compare_reg_return_imm_imm_00(long a, long b, long c) { + return a == c ? 7 : 4; +} + +long primitiveSemantics_compare_reg_return_imm_imm_01(long a, long b, long c) { + return a != c ? 7 : 4; +} + +long primitiveSemantics_compare_reg_return_imm_imm_02(long a, long b, long c) { + return a == c ? 7 : 4; +} + +long primitiveSemantics_compare_reg_return_imm_imm_03(long a, long b, long c) { + return a != c ? 7 : 4; +} + +long primitiveSemantics_compare_reg_return_imm_imm_04(long a, long b, long c) { + if (a == c) + b = 7; + else + b = 4; + return b; +} + +long primitiveSemantics_compare_reg_return_imm_imm_05(long a, long b, long c) { + if (!(a == c)) + b = 7; + else + b = 4; + return b; +} + +int primitiveSemantics_compare_reg_return_imm_imm_06(int a, int b, int c) { + return a == c ? 7 : 4; +} + +int primitiveSemantics_compare_reg_return_imm_imm_07(int a, int b, int c) { + return a != c ? 7 : 4; +} + +int primitiveSemantics_compare_reg_return_imm_imm_08(int a, int b, int c) { + return a == c ? 7 : 4; +} + +int primitiveSemantics_compare_reg_return_imm_imm_09(int a, int b, int c) { + return a != c ? 7 : 4; +} + +int primitiveSemantics_compare_reg_return_imm_imm_10(int a, int b, int c) { + if ((a == c)) + b = 7; + else + b = 4; + return b; +} + +int primitiveSemantics_compare_reg_return_imm_imm_11(int a, int b, int c) { + if (!(a == c)) + b = 7; + else + b = 4; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 6 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c new file mode 100644 index 00000000000..85a68bd946f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */ + +long primitiveSemantics_compare_reg_return_imm_reg_00(long a, long b, long c) { + return a == c ? 10 : b; +} + +long primitiveSemantics_compare_reg_return_imm_reg_01(long a, long b, long c) { + return a != c ? 10 : b; +} + +long primitiveSemantics_compare_reg_return_imm_reg_02(long a, long b, long c) { + return a == c ? b : 10; +} + +long primitiveSemantics_compare_reg_return_imm_reg_03(long a, long b, long c) { + return a != c ? b : 10; +} + +long primitiveSemantics_compare_reg_return_imm_reg_04(long a, long b, long c) { + if (a == c) + b = 10; + return b; +} + +long primitiveSemantics_compare_reg_return_imm_reg_05(long a, long b, long c) { + if (!(a == c)) + b = 10; + return b; +} + +int primitiveSemantics_compare_reg_return_imm_reg_06(int a, int b, int c) { + return a == c ? 10 : b; +} + +int primitiveSemantics_compare_reg_return_imm_reg_07(int a, int b, int c) { + return a != c ? 10 : b; +} + +int primitiveSemantics_compare_reg_return_imm_reg_08(int a, int b, int c) { + return a == c ? b : 10; +} + +int primitiveSemantics_compare_reg_return_imm_reg_09(int a, int b, int c) { + return a != c ? b : 10; +} + +int primitiveSemantics_compare_reg_return_imm_reg_10(int a, int b, int c) { + if ((a == c)) + b = 10; + return b; +} + +int primitiveSemantics_compare_reg_return_imm_reg_11(int a, int b, int c) { + if (!(a == c)) + b = 10; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 6 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c new file mode 100644 index 00000000000..d6d5d9e7bfa --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c @@ -0,0 +1,77 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */ + +long primitiveSemantics_compare_reg_return_reg_reg_00(long a, long b, long c, + long d) { + return a == c ? d : b; +} + +long primitiveSemantics_compare_reg_return_reg_reg_01(long a, long b, long c, + long d) { + return a != c ? d : b; +} + +long primitiveSemantics_compare_reg_return_reg_reg_02(long a, long b, long c, + long d) { + return a == c ? b : d; +} + +long primitiveSemantics_compare_reg_return_reg_reg_03(long a, long b, long c, + long d) { + return a != c ? b : d; +} + +long primitiveSemantics_compare_reg_return_reg_reg_04(long a, long b, long c, + long d) { + if (a == c) + b = d; + return b; +} + +long primitiveSemantics_compare_reg_return_reg_reg_05(long a, long b, long c, + long d) { + if (!(a == c)) + b = d; + return b; +} + +int primitiveSemantics_compare_reg_return_reg_reg_06(int a, int b, int c, + int d) { + return a == c ? d : b; +} + +int primitiveSemantics_compare_reg_return_reg_reg_07(int a, int b, int c, + int d) { + return a != c ? d : b; +} + +int primitiveSemantics_compare_reg_return_reg_reg_08(int a, int b, int c, + int d) { + return a == c ? b : d; +} + +int primitiveSemantics_compare_reg_return_reg_reg_09(int a, int b, int c, + int d) { + return a != c ? b : d; +} + +int primitiveSemantics_compare_reg_return_reg_reg_10(int a, int b, int c, + int d) { + if ((a == c)) + b = d; + return b; +} + +int primitiveSemantics_compare_reg_return_reg_reg_11(int a, int b, int c, + int d) { + if (!(a == c)) + b = d; + return b; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 12 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 12 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ From patchwork Wed Jul 19 10:11:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Zeng X-Patchwork-Id: 1809791 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R5Wq04Mn3z20FK for ; Wed, 19 Jul 2023 20:13:00 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 53D4B388203C for ; Wed, 19 Jul 2023 10:12:47 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from azure-sdnproxy.icoremail.net (azure-sdnproxy.icoremail.net [207.46.229.174]) by sourceware.org (Postfix) with ESMTP id CF500385702B for ; Wed, 19 Jul 2023 10:12:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CF500385702B Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=eswincomputing.com Received: from localhost.localdomain (unknown [10.12.130.38]) by app1 (Coremail) with SMTP id EwgMCgDHZMTttrdkrKE0AA--.63411S9; Wed, 19 Jul 2023 18:12:11 +0800 (CST) From: Xiao Zeng To: gcc-patches@gcc.gnu.org Cc: jeffreyalaw@gmail.com, research_trasio@irq.a4lg.com, kito.cheng@gmail.com, zhengyu@eswincomputing.com, eri-sw-toolchain@eswincomputing.com, Xiao Zeng Subject: [PATCH 5/5] [RISC-V] Generate Zicond instruction for conditional execution Date: Wed, 19 Jul 2023 18:11:56 +0800 Message-Id: <20230719101156.21771-6-zengxiao@eswincomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230719101156.21771-1-zengxiao@eswincomputing.com> References: <20230719101156.21771-1-zengxiao@eswincomputing.com> X-CM-TRANSID: EwgMCgDHZMTttrdkrKE0AA--.63411S9 X-Coremail-Antispam: 1UD129KBjvAXoWDCr1DKrWDCryDKFyrAryftFb_yoW7tF18to Wfuw4DJan5Ar17ZFn7Jr1xWFn2vFy0v3Z5ua15XFsFya1UCFy09w4Utws2ya4UWr45tFWU GF4fX34xJ39rAasxn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUOY7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l 84ACjcxK6xIIjxv20xvE14v26w1j6s0DM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4UJV WxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE 3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2I x0cI8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8 JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc2xSY4AK6svPMxAIw2 8IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMxCIbckI1I0E14v26r1Y6r17MI8I 3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxV WUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1I6r4UMIIF0xvE2Ix0cI8I cVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aV AFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZE Xa7VU17GYJUUUUU== X-CM-SenderInfo: p2hqw5xldrqvxvzl0uprps33xlqjhudrp/ X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This patch completes the recognition of conditional execution (using equality as an example), namely: 1 rd = (rc == 0) ? (rs1 arith_op rs2) : rs1 Here, arith_op represents the arithmetic operation symbol, which has 8 possibilities: + - | ^ << >>(Shift Right Arithmetic) >>(Shift Right Logical) & At the same time, more Zicond non basic conditional execution test cases have also been added, namely: 2 rd = (rc == 0) ? (rs1 arith_op non-imm) : rs1 3 rd = (rc == non-imm) ? (rs1 arith_op rs2) : rs1 4 rd = (rc == non-imm) ? (rs1 arith_op non-imm) : rs1 5 rd = (rc == reg) ? (rs1 arith_op rs2) : rs1 6 rd = (rc == reg) ? (rs1 arith_op non-imm) : rs1 gcc/ChangeLog: * ifcvt.cc (noce_emit_condzero_arith): Helper function for noce_emit_condzero_arith. (noce_try_condzero_arith): Recognize Zicond patterns. (noce_process_if_block): Add noce_try_condzero_arith function. gcc/testsuite/ChangeLog: * gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_imm_reg.c: New test. * gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_reg_reg.c: New test. * gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_imm_reg.c: New test. * gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_reg_reg.c: New test. * gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_imm_reg.c: New test. * gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_reg_reg.c: New test. --- gcc/ifcvt.cc | 251 ++++++++ ...ionalArithmetic_compare_0_return_imm_reg.c | 553 +++++++++++++++++ ...ionalArithmetic_compare_0_return_reg_reg.c | 585 ++++++++++++++++++ ...nalArithmetic_compare_imm_return_imm_reg.c | 297 +++++++++ ...nalArithmetic_compare_imm_return_reg_reg.c | 297 +++++++++ ...nalArithmetic_compare_reg_return_imm_reg.c | 297 +++++++++ ...nalArithmetic_compare_reg_return_reg_reg.c | 329 ++++++++++ 7 files changed, 2609 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_imm_reg.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_reg_reg.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_imm_reg.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_reg_reg.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_imm_reg.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_reg_reg.c diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc index 0b180b4568f..0261d2f1673 100644 --- a/gcc/ifcvt.cc +++ b/gcc/ifcvt.cc @@ -781,12 +781,15 @@ static int noce_try_store_flag_constants (struct noce_if_info *); static int noce_try_store_flag_mask (struct noce_if_info *); static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx, rtx, rtx, rtx, rtx = NULL, rtx = NULL); +static rtx noce_emit_condzero_arith (struct noce_if_info *, rtx, enum rtx_code, rtx, + rtx, rtx, rtx); static int noce_try_cmove (struct noce_if_info *); static int noce_try_cmove_arith (struct noce_if_info *); static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx_insn **); static int noce_try_minmax (struct noce_if_info *); static int noce_try_abs (struct noce_if_info *); static int noce_try_sign_mask (struct noce_if_info *); +static int noce_try_condzero_arith (struct noce_if_info *); /* Return the comparison code for reversed condition for IF_INFO, or UNKNOWN if reversing the condition is not possible. */ @@ -1830,6 +1833,60 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code, return NULL_RTX; } +/* Helper function for noce_emit_condzero_arith. */ + +static rtx +noce_emit_condzero_arith (struct noce_if_info *if_info, rtx x, enum rtx_code code, + rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue) +{ + rtx cond = NULL; + + /* Standard form of conditional comparison. */ + if (GET_CODE(cmp_a) == REG && cmp_b == const0_rtx) + cond = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b); + + /* Register and non-zero immediate comparison. */ + else if (GET_CODE(cmp_a) == REG && GET_CODE(cmp_b) == CONST_INT && + cmp_b != const0_rtx) + { + rtx temp1 = gen_reg_rtx (GET_MODE(cmp_a)); + rtx temp2 = GEN_INT(-1 * INTVAL (cmp_b)); + rtx src = gen_rtx_fmt_ee (PLUS, GET_MODE (cmp_a), cmp_a, temp2); + emit_insn (gen_rtx_SET (temp1, src)); + cond = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), temp1, const0_rtx); + } + + /* Register and Register comparison. */ + else if (GET_CODE(cmp_a) == REG && GET_CODE(cmp_b) == REG) + { + rtx temp1 = gen_reg_rtx (GET_MODE(cmp_a)); + rtx src = gen_rtx_fmt_ee (MINUS, GET_MODE (cmp_a), cmp_a, cmp_b); + emit_insn (gen_rtx_SET (temp1, src)); + cond = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), temp1, const0_rtx); + } + else + return NULL_RTX; + + rtx if_then_else = gen_rtx_IF_THEN_ELSE (GET_MODE (x), cond, vtrue, vfalse); + rtx set = gen_rtx_SET (x, if_then_else); + + start_sequence (); + rtx_insn *insn = emit_insn (set); + + if (recog_memoized (insn) >= 0) + { + rtx_insn *seq = get_insns (); + end_sequence (); + emit_insn (seq); + + return x; + } + + end_sequence (); + + return NULL_RTX; +} + /* Try only simple constants and registers here. More complex cases are handled in noce_try_cmove_arith after noce_try_store_flag_arith has had a go at it. */ @@ -2879,6 +2936,197 @@ noce_try_sign_mask (struct noce_if_info *if_info) return TRUE; } +/* Convert "if (cond) x = x arith_code y; return x;" to a branchless + sequence using the canonical form for a conditional-zero. */ + +static int +noce_try_condzero_arith (struct noce_if_info *if_info) +{ + rtx target; + rtx_insn *seq; + + rtx first_pattern = NULL; + rtx last_pattern = NULL; + rtx else_pattern = NULL; + rtx *arith, *ref_arith_op0, *ref_arith_op1; + rtx arith_op0, arith_op1; + rtx_code arith_code; + rtx_code cond_code = GET_CODE (if_info->cond); + + machine_mode arith_mode = GET_MODE (if_info->a); + machine_mode cmp_mode = GET_MODE (XEXP(if_info->cond, 0)); + if (GET_MODE_CLASS (arith_mode) != MODE_INT || + GET_MODE_CLASS (cmp_mode) != MODE_INT) + return FALSE; + + /* we shall create new pseudos. */ + if (reload_completed) + return FALSE; + + /* Check for cond_code. */ + if (cond_code != EQ && cond_code != NE) + return FALSE; + + /* Check for else_bb. */ + if (if_info->else_bb && + !(count_bb_insns(if_info->else_bb) == 1 && + !JUMP_P (BB_END (if_info->then_bb)) && + (else_pattern = single_set (first_active_insn (if_info->else_bb))) && + GET_CODE (else_pattern) == SET && + rtx_equal_p (if_info->x, XEXP(else_pattern, 0)))) + return FALSE; + + /* count_bb_insns ignores JUMP_INSN. */ + if (JUMP_P (BB_END (if_info->then_bb))) + return FALSE; + + if (count_bb_insns(if_info->then_bb) > 2) + return FALSE; + + /* Optimize for sign-extension. */ + if (count_bb_insns(if_info->then_bb) == 2) + { + last_pattern = copy_rtx (PATTERN (last_active_insn (if_info->then_bb, + FALSE))); + /* Just processing SET insn, not including other situations + in the single_set function. */ + if (GET_CODE (last_pattern) != SET) + return FALSE; + + rtx_code last_code = GET_CODE (XEXP (last_pattern, 1)); + + if (last_code != SIGN_EXTEND && last_code != REG) + return FALSE; + } + + first_pattern = copy_rtx (PATTERN (first_active_insn (if_info->then_bb))); + if (GET_CODE (first_pattern) != SET) + return FALSE; + + arith = &XEXP (first_pattern, 1); + arith_code = GET_CODE (*arith); + + if (arith_code == SIGN_EXTEND) + { + arith = &XEXP (*arith, 0); + arith_code = GET_CODE (*arith); + } + /* When shift right logical a non-zero immediate to unsigned integer, + zero_extend and sign_extend are equal. + In risc-v, using zero_extend to represent shift right logical is + a non-canonical form, as shown in riscv.md. */ + else if (arith_code == ZERO_EXTEND) + { + rtx *temp = arith; + arith = &XEXP (*arith, 0); + arith_code = GET_CODE (*arith); + if (arith_code != LSHIFTRT) + return FALSE; + /* Modify the code to sign_extend for easy subsequent recognition. */ + PUT_CODE(*temp, SIGN_EXTEND); + } + + if (arith_code != PLUS && arith_code != MINUS && arith_code != IOR && + arith_code != XOR && arith_code != AND && arith_code != ASHIFTRT && + arith_code != LSHIFTRT && arith_code != ASHIFT) + return FALSE; + + /* Obtain the arithmetic calculation components: arith_op0 and arith_op1. */ + arith_op0 = XEXP (*arith, 0); + arith_op1 = XEXP (*arith, 1); + ref_arith_op0 = &XEXP (*arith, 0); + ref_arith_op1 = &XEXP (*arith, 1); + + if (GET_CODE (arith_op0) == SUBREG) + arith_op0 = SUBREG_REG(arith_op0); + if (GET_CODE (arith_op1) == SUBREG) + arith_op1 = SUBREG_REG(arith_op1); + + /* The arithmetic calculation pattern that can only be processed + in insn pattern are as follows: + (set (reg/v:DI 137 [ rs1 ]) + (ashiftrt:DI (reg/v:DI 137 [ rs1 ]) + (subreg:QI (reg/v:DI 138 [ rs2 ]) 0))) */ + if (!else_pattern && !rtx_equal_p (if_info->x, arith_op0)) + return FALSE; + + /* If else_bb is not empty. */ + if (else_pattern && !rtx_equal_p (if_info->x, XEXP(first_pattern, 0)) && + !rtx_equal_p (arith_op0, XEXP(else_pattern, 1))) + return FALSE; + + start_sequence (); + + if (arith_code == AND) + { + rtx reg1 = gen_reg_rtx (arith_mode); + rtx temp = gen_rtx_fmt_ee (arith_code, arith_mode, arith_op0, arith_op1); + emit_insn (gen_rtx_SET (reg1, temp)); + + rtx reg2 = gen_reg_rtx (arith_mode); + target = noce_emit_condzero_arith (if_info, reg2, cond_code, + XEXP (if_info->cond, 0), + XEXP (if_info->cond, 1), + const0_rtx, arith_op0); + if (!target) + { + end_sequence (); + return FALSE; + } + rtx ior = gen_rtx_fmt_ee (IOR, arith_mode, reg1, target); + emit_insn (gen_rtx_SET (if_info->x, ior)); + } + else + { + /* In CONST_INT case, force arith_op1 to register. */ + if (GET_CODE(arith_op1) == CONST_INT) + { + rtx reg = gen_reg_rtx (arith_mode); + emit_insn (gen_rtx_SET (reg, arith_op1)); + arith_op1 = reg; + } + + /* Apply for a reg as the return register for condezero. */ + rtx reg = gen_reg_rtx (arith_mode); + target = noce_emit_condzero_arith (if_info, reg, cond_code, + XEXP (if_info->cond, 0), + XEXP (if_info->cond, 1), + arith_op1, const0_rtx); + if (!target) + { + end_sequence (); + return FALSE; + } + + /* Update arithmetic operand in first_pattern. */ + + /* Shift a register. */ + if (arith_code == ASHIFT || arith_code == ASHIFTRT || + arith_code == LSHIFTRT) + *ref_arith_op1 = gen_rtx_SUBREG (E_QImode, target, 0); + else if (GET_CODE (*ref_arith_op0) == SUBREG) + *ref_arith_op1 = gen_rtx_SUBREG (GET_MODE (*ref_arith_op0), target, 0); + else + *ref_arith_op1 = target; + + emit_insn (first_pattern); + + /* Adding last_pattern to the insn chain. */ + if (last_pattern) + emit_insn (last_pattern); + } + + seq = end_ifcvt_sequence (if_info); + + if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info)) + return FALSE; + + emit_insn_before_setloc (seq, if_info->jump, + INSN_LOCATION (if_info->insn_a)); + if_info->transform_name = "noce_try_condzero_arith"; + + return TRUE; +} /* Optimize away "if (x & C) x |= C" and similar bit manipulation transformations. */ @@ -3973,6 +4221,9 @@ noce_process_if_block (struct noce_if_info *if_info) goto success; if (noce_try_store_flag_mask (if_info)) goto success; + if (HAVE_conditional_move + && noce_try_condzero_arith(if_info)) + goto success; if (HAVE_conditional_move && noce_try_cmove_arith (if_info)) goto success; diff --git a/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_imm_reg.c new file mode 100644 index 00000000000..282e8a8e492 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_imm_reg.c @@ -0,0 +1,553 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os"} } */ + +long conditionalArithmetic_compare_0_return_imm_reg_00(long rd, long rs1, + long rc) { + if (rc == 0) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_01(long rd, long rs1, + long rc) { + if (rc != 0) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_02(long rd, long rs1, + long rc) { + if (rc) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_03(long rd, long rs1, + long rc) { + if (!rc) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_04(long rd, long rs1, + long rc) { + if (rc == 0) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_05(long rd, long rs1, + long rc) { + if (rc != 0) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_06(long rd, long rs1, + long rc) { + if (rc) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_07(long rd, long rs1, + long rc) { + if (!rc) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_08(long rd, long rs1, + long rc) { + if (rc == 0) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_09(long rd, long rs1, + long rc) { + if (rc != 0) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_10(long rd, long rs1, + long rc) { + if (rc) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_11(long rd, long rs1, + long rc) { + if (!rc) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_12(long rd, long rs1, + long rc) { + if (rc == 0) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_13(long rd, long rs1, + long rc) { + if (rc != 0) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_14(long rd, long rs1, + long rc) { + if (rc) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_15(long rd, long rs1, + long rc) { + if (!rc) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_16(long rd, long rs1, + long rc) { + if (rc == 0) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_17(long rd, long rs1, + long rc) { + if (rc != 0) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_18(long rd, long rs1, + long rc) { + if (rc) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_19(long rd, long rs1, + long rc) { + if (!rc) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_20(long rd, long rs1, + long rc) { + if (rc == 0) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_21(long rd, long rs1, + long rc) { + if (rc != 0) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_22(long rd, long rs1, + long rc) { + if (rc) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_23(long rd, long rs1, + long rc) { + if (!rc) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_24(long rd, long rs1, + long rc) { + if (rc == 0) + rd = ((unsigned long)rs1) >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_25(long rd, long rs1, + long rc) { + if (rc != 0) + rd = ((unsigned long)rs1) >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_26(long rd, long rs1, + long rc) { + if (rc) + rd = ((unsigned long)rs1) >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_27(long rd, long rs1, + long rc) { + if (!rc) + rd = ((unsigned long)rs1) >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_28(long rd, long rs1, + long rc) { + if (rc == 0) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_29(long rd, long rs1, + long rc) { + if (rc != 0) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_30(long rd, long rs1, + long rc) { + if (rc) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_imm_reg_31(long rd, long rs1, + long rc) { + if (!rc) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_32(int rd, int rs1, int rc) { + if (rc == 0) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_33(int rd, int rs1, int rc) { + if (rc != 0) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_34(int rd, int rs1, int rc) { + if (rc) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_35(int rd, int rs1, int rc) { + if (!rc) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_36(int rd, int rs1, int rc) { + if (rc == 0) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_37(int rd, int rs1, int rc) { + if (rc != 0) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_38(int rd, int rs1, int rc) { + if (rc) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_39(int rd, int rs1, int rc) { + if (!rc) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_40(int rd, int rs1, int rc) { + if (rc == 0) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_41(int rd, int rs1, int rc) { + if (rc != 0) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_42(int rd, int rs1, int rc) { + if (rc) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_43(int rd, int rs1, int rc) { + if (!rc) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_44(int rd, int rs1, int rc) { + if (rc == 0) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_45(int rd, int rs1, int rc) { + if (rc != 0) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_46(int rd, int rs1, int rc) { + if (rc) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_47(int rd, int rs1, int rc) { + if (!rc) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_48(int rd, int rs1, int rc) { + if (rc == 0) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_49(int rd, int rs1, int rc) { + if (rc != 0) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_50(int rd, int rs1, int rc) { + if (rc) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_51(int rd, int rs1, int rc) { + if (!rc) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_52(int rd, int rs1, int rc) { + if (rc == 0) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_53(int rd, int rs1, int rc) { + if (rc != 0) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_54(int rd, int rs1, int rc) { + if (rc) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_55(int rd, int rs1, int rc) { + if (!rc) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_56(int rd, int rs1, int rc) { + if (rc == 0) + rd = ((unsigned int)rs1) >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_57(int rd, int rs1, int rc) { + if (rc != 0) + rd = ((unsigned int)rs1) >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_58(int rd, int rs1, int rc) { + if (rc) + rd = ((unsigned int)rs1) >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_59(int rd, int rs1, int rc) { + if (!rc) + rd = ((unsigned int)rs1) >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_60(int rd, int rs1, int rc) { + if (rc == 0) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_61(int rd, int rs1, int rc) { + if (rc != 0) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_62(int rd, int rs1, int rc) { + if (rc) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_imm_reg_63(int rd, int rs1, int rc) { + if (!rc) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 32 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 32 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_reg_reg.c new file mode 100644 index 00000000000..15efcf538e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_reg_reg.c @@ -0,0 +1,585 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os"} } */ + +long conditionalArithmetic_compare_0_return_reg_reg_00(long rd, long rs1, + long rs2, long rc) { + if (rc == 0) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_01(long rd, long rs1, + long rs2, long rc) { + if (rc != 0) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_02(long rd, long rs1, + long rs2, long rc) { + if (rc) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_03(long rd, long rs1, + long rs2, long rc) { + if (!rc) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_04(long rd, long rs1, + long rs2, long rc) { + if (rc == 0) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_05(long rd, long rs1, + long rs2, long rc) { + if (rc != 0) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_06(long rd, long rs1, + long rs2, long rc) { + if (rc) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_07(long rd, long rs1, + long rs2, long rc) { + if (!rc) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_08(long rd, long rs1, + long rs2, long rc) { + if (rc == 0) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_09(long rd, long rs1, + long rs2, long rc) { + if (rc != 0) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_10(long rd, long rs1, + long rs2, long rc) { + if (rc) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_11(long rd, long rs1, + long rs2, long rc) { + if (!rc) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_12(long rd, long rs1, + long rs2, long rc) { + if (rc == 0) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_13(long rd, long rs1, + long rs2, long rc) { + if (rc != 0) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_14(long rd, long rs1, + long rs2, long rc) { + if (rc) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_15(long rd, long rs1, + long rs2, long rc) { + if (!rc) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_16(long rd, long rs1, + long rs2, long rc) { + if (rc == 0) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_17(long rd, long rs1, + long rs2, long rc) { + if (rc != 0) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_18(long rd, long rs1, + long rs2, long rc) { + if (rc) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_19(long rd, long rs1, + long rs2, long rc) { + if (!rc) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_20(long rd, long rs1, + long rs2, long rc) { + if (rc == 0) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_21(long rd, long rs1, + long rs2, long rc) { + if (rc != 0) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_22(long rd, long rs1, + long rs2, long rc) { + if (rc) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_23(long rd, long rs1, + long rs2, long rc) { + if (!rc) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_24(long rd, long rs1, + long rs2, long rc) { + if (rc == 0) + rd = ((unsigned long)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_25(long rd, long rs1, + long rs2, long rc) { + if (rc != 0) + rd = ((unsigned long)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_26(long rd, long rs1, + long rs2, long rc) { + if (rc) + rd = ((unsigned long)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_27(long rd, long rs1, + long rs2, long rc) { + if (!rc) + rd = ((unsigned long)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_28(long rd, long rs1, + long rs2, long rc) { + if (rc == 0) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_29(long rd, long rs1, + long rs2, long rc) { + if (rc != 0) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_30(long rd, long rs1, + long rs2, long rc) { + if (rc) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_0_return_reg_reg_31(long rd, long rs1, + long rs2, long rc) { + if (!rc) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_32(int rd, int rs1, int rs2, + int rc) { + if (rc == 0) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_33(int rd, int rs1, int rs2, + int rc) { + if (rc != 0) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_34(int rd, int rs1, int rs2, + int rc) { + if (rc) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_35(int rd, int rs1, int rs2, + int rc) { + if (!rc) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_36(int rd, int rs1, int rs2, + int rc) { + if (rc == 0) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_37(int rd, int rs1, int rs2, + int rc) { + if (rc != 0) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_38(int rd, int rs1, int rs2, + int rc) { + if (rc) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_39(int rd, int rs1, int rs2, + int rc) { + if (!rc) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_40(int rd, int rs1, int rs2, + int rc) { + if (rc == 0) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_41(int rd, int rs1, int rs2, + int rc) { + if (rc != 0) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_42(int rd, int rs1, int rs2, + int rc) { + if (rc) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_43(int rd, int rs1, int rs2, + int rc) { + if (!rc) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_44(int rd, int rs1, int rs2, + int rc) { + if (rc == 0) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_45(int rd, int rs1, int rs2, + int rc) { + if (rc != 0) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_46(int rd, int rs1, int rs2, + int rc) { + if (rc) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_47(int rd, int rs1, int rs2, + int rc) { + if (!rc) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_48(int rd, int rs1, int rs2, + int rc) { + if (rc == 0) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_49(int rd, int rs1, int rs2, + int rc) { + if (rc != 0) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_50(int rd, int rs1, int rs2, + int rc) { + if (rc) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_51(int rd, int rs1, int rs2, + int rc) { + if (!rc) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_52(int rd, int rs1, int rs2, + int rc) { + if (rc == 0) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_53(int rd, int rs1, int rs2, + int rc) { + if (rc != 0) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_54(int rd, int rs1, int rs2, + int rc) { + if (rc) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_55(int rd, int rs1, int rs2, + int rc) { + if (!rc) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_56(int rd, int rs1, int rs2, + int rc) { + if (rc == 0) + rd = ((unsigned int)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_57(int rd, int rs1, int rs2, + int rc) { + if (rc != 0) + rd = ((unsigned int)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_58(int rd, int rs1, int rs2, + int rc) { + if (rc) + rd = ((unsigned int)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_59(int rd, int rs1, int rs2, + int rc) { + if (!rc) + rd = ((unsigned int)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_60(int rd, int rs1, int rs2, + int rc) { + if (rc == 0) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_61(int rd, int rs1, int rs2, + int rc) { + if (rc != 0) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_62(int rd, int rs1, int rs2, + int rc) { + if (rc) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_0_return_reg_reg_63(int rd, int rs1, int rs2, + int rc) { + if (!rc) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 32 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 32 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_imm_reg.c new file mode 100644 index 00000000000..6647640acf8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_imm_reg.c @@ -0,0 +1,297 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os"} } */ + +long conditionalArithmetic_compare_imm_return_imm_reg_00(long rd, long rs1, + long rc) { + if (rc == 10) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_01(long rd, long rs1, + long rc) { + if (rc != 10) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_02(long rd, long rs1, + long rc) { + if (rc == 10) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_03(long rd, long rs1, + long rc) { + if (rc != 10) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_04(long rd, long rs1, + long rc) { + if (rc == 10) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_05(long rd, long rs1, + long rc) { + if (rc != 10) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_06(long rd, long rs1, + long rc) { + if (rc == 10) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_07(long rd, long rs1, + long rc) { + if (rc != 10) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_08(long rd, long rs1, + long rc) { + if (rc == 10) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_09(long rd, long rs1, + long rc) { + if (rc != 10) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_10(long rd, long rs1, + long rc) { + if (rc == 10) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_11(long rd, long rs1, + long rc) { + if (rc != 10) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_12(long rd, long rs1, + long rc) { + if (rc == 10) + rd = ((unsigned long)rs1) >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_13(long rd, long rs1, + long rc) { + if (rc != 10) + rd = ((unsigned long)rs1) >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_14(long rd, long rs1, + long rc) { + if (rc == 10) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_imm_reg_15(long rd, long rs1, + long rc) { + if (rc != 10) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_16(int rd, int rs1, + int rc) { + if (rc == 10) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_17(int rd, int rs1, + int rc) { + if (rc != 10) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_18(int rd, int rs1, + int rc) { + if (rc == 10) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_19(int rd, int rs1, + int rc) { + if (rc != 10) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_20(int rd, int rs1, + int rc) { + if (rc == 10) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_21(int rd, int rs1, + int rc) { + if (rc != 10) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_22(int rd, int rs1, + int rc) { + if (rc == 10) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_23(int rd, int rs1, + int rc) { + if (rc != 10) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_24(int rd, int rs1, + int rc) { + if (rc == 10) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_25(int rd, int rs1, + int rc) { + if (rc != 10) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_26(int rd, int rs1, + int rc) { + if (rc == 10) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_27(int rd, int rs1, + int rc) { + if (rc != 10) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_28(int rd, int rs1, + int rc) { + if (rc == 10) + rd = ((unsigned int)rs1) >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_29(int rd, int rs1, + int rc) { + if (rc != 10) + rd = ((unsigned int)rs1) >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_30(int rd, int rs1, + int rc) { + if (rc == 10) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_imm_reg_31(int rd, int rs1, + int rc) { + if (rc != 10) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 16 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 16 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_reg_reg.c new file mode 100644 index 00000000000..859639c1676 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_reg_reg.c @@ -0,0 +1,297 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os"} } */ + +long conditionalArithmetic_compare_imm_return_reg_reg_00(long rd, long rs1, + long rs2, long rc) { + if (rc == 10) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_01(long rd, long rs1, + long rs2, long rc) { + if (rc != 10) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_02(long rd, long rs1, + long rs2, long rc) { + if (rc == 10) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_03(long rd, long rs1, + long rs2, long rc) { + if (rc != 10) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_04(long rd, long rs1, + long rs2, long rc) { + if (rc == 10) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_05(long rd, long rs1, + long rs2, long rc) { + if (rc != 10) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_06(long rd, long rs1, + long rs2, long rc) { + if (rc == 10) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_07(long rd, long rs1, + long rs2, long rc) { + if (rc != 10) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_08(long rd, long rs1, + long rs2, long rc) { + if (rc == 10) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_09(long rd, long rs1, + long rs2, long rc) { + if (rc != 10) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_10(long rd, long rs1, + long rs2, long rc) { + if (rc == 10) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_11(long rd, long rs1, + long rs2, long rc) { + if (rc != 10) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_12(long rd, long rs1, + long rs2, long rc) { + if (rc == 10) + rd = ((unsigned long)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_13(long rd, long rs1, + long rs2, long rc) { + if (rc != 10) + rd = ((unsigned long)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_14(long rd, long rs1, + long rs2, long rc) { + if (rc == 10) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_imm_return_reg_reg_15(long rd, long rs1, + long rs2, long rc) { + if (rc != 10) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_16(int rd, int rs1, + int rs2, int rc) { + if (rc == 10) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_17(int rd, int rs1, + int rs2, int rc) { + if (rc != 10) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_18(int rd, int rs1, + int rs2, int rc) { + if (rc == 10) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_19(int rd, int rs1, + int rs2, int rc) { + if (rc != 10) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_20(int rd, int rs1, + int rs2, int rc) { + if (rc == 10) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_21(int rd, int rs1, + int rs2, int rc) { + if (rc != 10) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_22(int rd, int rs1, + int rs2, int rc) { + if (rc == 10) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_23(int rd, int rs1, + int rs2, int rc) { + if (rc != 10) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_24(int rd, int rs1, + int rs2, int rc) { + if (rc == 10) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_25(int rd, int rs1, + int rs2, int rc) { + if (rc != 10) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_26(int rd, int rs1, + int rs2, int rc) { + if (rc == 10) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_27(int rd, int rs1, + int rs2, int rc) { + if (rc != 10) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_28(int rd, int rs1, + int rs2, int rc) { + if (rc == 10) + rd = ((unsigned int)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_29(int rd, int rs1, + int rs2, int rc) { + if (rc != 10) + rd = ((unsigned int)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_30(int rd, int rs1, + int rs2, int rc) { + if (rc == 10) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_imm_return_reg_reg_31(int rd, int rs1, + int rs2, int rc) { + if (rc != 10) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 16 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 16 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_imm_reg.c new file mode 100644 index 00000000000..7affe1d9baa --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_imm_reg.c @@ -0,0 +1,297 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os"} } */ + +long conditionalArithmetic_compare_reg_return_imm_reg_00(long rd, long rs1, + long rc1, long rc2) { + if (rc1 == rc2) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_01(long rd, long rs1, + long rc1, long rc2) { + if (rc1 != rc2) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_02(long rd, long rs1, + long rc1, long rc2) { + if (rc1 == rc2) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_03(long rd, long rs1, + long rc1, long rc2) { + if (rc1 != rc2) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_04(long rd, long rs1, + long rc1, long rc2) { + if (rc1 == rc2) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_05(long rd, long rs1, + long rc1, long rc2) { + if (rc1 != rc2) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_06(long rd, long rs1, + long rc1, long rc2) { + if (rc1 == rc2) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_07(long rd, long rs1, + long rc1, long rc2) { + if (rc1 != rc2) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_08(long rd, long rs1, + long rc1, long rc2) { + if (rc1 == rc2) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_09(long rd, long rs1, + long rc1, long rc2) { + if (rc1 != rc2) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_10(long rd, long rs1, + long rc1, long rc2) { + if (rc1 == rc2) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_11(long rd, long rs1, + long rc1, long rc2) { + if (rc1 != rc2) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_12(long rd, long rs1, + long rc1, long rc2) { + if (rc1 == rc2) + rd = ((unsigned long)rs1) >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_13(long rd, long rs1, + long rc1, long rc2) { + if (rc1 != rc2) + rd = ((unsigned long)rs1) >> 2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_14(long rd, long rs1, + long rc1, long rc2) { + if (rc1 == rc2) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_imm_reg_15(long rd, long rs1, + long rc1, long rc2) { + if (rc1 != rc2) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_16(int rd, int rs1, + int rc1, int rc2) { + if (rc1 == rc2) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_17(int rd, int rs1, + int rc1, int rc2) { + if (rc1 != rc2) + rd = rs1 + 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_18(int rd, int rs1, + int rc1, int rc2) { + if (rc1 == rc2) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_19(int rd, int rs1, + int rc1, int rc2) { + if (rc1 != rc2) + rd = rs1 - 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_20(int rd, int rs1, + int rc1, int rc2) { + if (rc1 == rc2) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_21(int rd, int rs1, + int rc1, int rc2) { + if (rc1 != rc2) + rd = rs1 | 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_22(int rd, int rs1, + int rc1, int rc2) { + if (rc1 == rc2) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_23(int rd, int rs1, + int rc1, int rc2) { + if (rc1 != rc2) + rd = rs1 ^ 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_24(int rd, int rs1, + int rc1, int rc2) { + if (rc1 == rc2) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_25(int rd, int rs1, + int rc1, int rc2) { + if (rc1 != rc2) + rd = rs1 << 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_26(int rd, int rs1, + int rc1, int rc2) { + if (rc1 == rc2) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_27(int rd, int rs1, + int rc1, int rc2) { + if (rc1 != rc2) + rd = rs1 >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_28(int rd, int rs1, + int rc1, int rc2) { + if (rc1 == rc2) + rd = ((unsigned int)rs1) >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_29(int rd, int rs1, + int rc1, int rc2) { + if (rc1 != rc2) + rd = ((unsigned int)rs1) >> 2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_30(int rd, int rs1, + int rc1, int rc2) { + if (rc1 == rc2) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_imm_reg_31(int rd, int rs1, + int rc1, int rc2) { + if (rc1 != rc2) + rd = rs1 & 20; + else + rd = rs1; + return rd; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 16 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 16 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_reg_reg.c new file mode 100644 index 00000000000..8b0959e534b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_reg_reg.c @@ -0,0 +1,329 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os"} } */ + +long conditionalArithmetic_compare_reg_return_reg_reg_00(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 == rc2) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_01(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 != rc2) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_02(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 == rc2) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_03(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 != rc2) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_04(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 == rc2) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_05(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 != rc2) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_06(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 == rc2) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_07(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 != rc2) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_08(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 == rc2) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_09(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 != rc2) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_10(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 == rc2) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_11(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 != rc2) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_12(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 == rc2) + rd = ((unsigned long)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_13(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 != rc2) + rd = ((unsigned long)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_14(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 == rc2) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +long conditionalArithmetic_compare_reg_return_reg_reg_15(long rd, long rs1, + long rs2, long rc1, + long rc2) { + if (rc1 != rc2) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_16(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 == rc2) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_17(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 != rc2) + rd = rs1 + rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_18(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 == rc2) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_19(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 != rc2) + rd = rs1 - rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_20(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 == rc2) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_21(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 != rc2) + rd = rs1 | rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_22(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 == rc2) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_23(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 != rc2) + rd = rs1 ^ rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_24(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 == rc2) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_25(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 != rc2) + rd = rs1 << rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_26(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 == rc2) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_27(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 != rc2) + rd = rs1 >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_28(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 == rc2) + rd = ((unsigned int)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_29(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 != rc2) + rd = ((unsigned int)rs1) >> rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_30(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 == rc2) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +int conditionalArithmetic_compare_reg_return_reg_reg_31(int rd, int rs1, + int rs2, int rc1, + int rc2) { + if (rc1 != rc2) + rd = rs1 & rs2; + else + rd = rs1; + return rd; +} + +/* { dg-final { scan-assembler-times "czero.eqz" 16 } } */ +/* { dg-final { scan-assembler-times "czero.nez" 16 } } */ +/* { dg-final { scan-assembler-not "beq" } } */ +/* { dg-final { scan-assembler-not "bne" } } */