From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1923) id 3E9AE3895FF7; Tue, 15 Nov 2022 14:01:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3E9AE3895FF7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1668520888; bh=Y91lREchB6UTclYgy8iPwXFE5MLkrdpZddQPtc2ahhQ=; h=From:To:Subject:Date:From; b=NM4qKbf2w7ZOyxapUsapcYkTrZ8vSnewumxDD1O3gWIInp+C4LiyNCH5pDPiXtWlq eeafjN1BtjoRXZutbLSJ2mHNnrE429CJBz1McTQ/Nhkyq/IdhVAPYlc3OmvPBcSF4m BvgLWQyJUae1UUxKkfWUn2US5CW6YpQ8iurmB5P8= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Philipp Tomsich To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/vrull/heads/for-upstream)] RISC-V: Optimize masking with two clear bits not a SMALL_OPERAND X-Act-Checkin: gcc X-Git-Author: Philipp Tomsich X-Git-Refname: refs/vendors/vrull/heads/for-upstream X-Git-Oldrev: 424802e8d833c2e9c768b75144239fc22436f784 X-Git-Newrev: f1836d0cb2448f0905365bfb1592dafb08273fd9 Message-Id: <20221115140128.3E9AE3895FF7@sourceware.org> Date: Tue, 15 Nov 2022 14:01:28 +0000 (GMT) List-Id: https://gcc.gnu.org/g:f1836d0cb2448f0905365bfb1592dafb08273fd9 commit f1836d0cb2448f0905365bfb1592dafb08273fd9 Author: Philipp Tomsich Date: Thu Oct 13 10:55:41 2022 +0200 RISC-V: Optimize masking with two clear bits not a SMALL_OPERAND Add a split for cases where we can use two bclri (or one bclri and an andi) to clear two bits. gcc/ChangeLog: * config/riscv/bitmanip.md (*bclri_nottwobits): New pattern. (*bclridisi_nottwobits): New pattern, handling the sign-bit. * config/riscv/predicates.md (const_nottwobits_operand): New predicate. gcc/testsuite/ChangeLog: * gcc.target/riscv/zbs-bclri.c: New test. Series-to: gcc-patches@gcc.gnu.org Series-cc: Palmer Dabbelt Series-cc: Vineet Gupta Series-cc: Christoph Muellner Series-cc: Kito Cheng Series-cc: Jeff Law Diff: --- gcc/config/riscv/bitmanip.md | 38 ++++++++++++++++++++++++++++++ gcc/config/riscv/predicates.md | 5 ++++ gcc/testsuite/gcc.target/riscv/zbs-bclri.c | 12 ++++++++++ 3 files changed, 55 insertions(+) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 65f938d15fb..06bf6b42dbd 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -568,6 +568,44 @@ "bclri\t%0,%1,%T2" [(set_attr "type" "bitmanip")]) +;; In case we have "val & ~IMM" where ~IMM has 2 bits set. +(define_insn_and_split "*bclri_nottwobits" + [(set (match_operand:X 0 "register_operand" "=r") + (and:X (match_operand:X 1 "register_operand" "r") + (match_operand:X 2 "const_nottwobits_operand" "i")))] + "TARGET_ZBS && !paradoxical_subreg_p (operands[1])" + "#" + "&& reload_completed" + [(set (match_dup 0) (and:X (match_dup 1) (match_dup 3))) + (set (match_dup 0) (and:X (match_dup 0) (match_dup 4)))] +{ + unsigned HOST_WIDE_INT bits = ~UINTVAL (operands[2]); + unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits); + + operands[3] = GEN_INT (~bits | topbit); + operands[4] = GEN_INT (~topbit); +}) + +;; In case of a paradoxical subreg, the sign bit and the high bits are +;; not allowed to be changed +(define_insn_and_split "*bclridisi_nottwobits" + [(set (match_operand:DI 0 "register_operand" "=r") + (and:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "const_nottwobits_operand" "i")))] + "TARGET_64BIT && TARGET_ZBS + && clz_hwi (~UINTVAL (operands[2])) > 33" + "#" + "&& reload_completed" + [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3))) + (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))] +{ + unsigned HOST_WIDE_INT bits = ~UINTVAL (operands[2]); + unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits); + + operands[3] = GEN_INT (~bits | topbit); + operands[4] = GEN_INT (~topbit); +}) + (define_insn "*binv" [(set (match_operand:X 0 "register_operand" "=r") (xor:X (ashift:X (const_int 1) diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 6de9b39e39b..b368c11c930 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -304,6 +304,11 @@ (match_test "ctz_hwi (INTVAL (op)) > 0") (match_test "SMALL_OPERAND (INTVAL (op) >> ctz_hwi (INTVAL (op)))"))) +;; A CONST_INT operand that has exactly two bits cleared. +(define_predicate "const_nottwobits_operand" + (and (match_code "const_int") + (match_test "popcount_hwi (~UINTVAL (op)) == 2"))) + ;; A CONST_INT operand that fits into the unsigned half of a ;; signed-immediate after the top bit has been cleared. (define_predicate "uimm_extra_bit_operand" diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bclri.c b/gcc/testsuite/gcc.target/riscv/zbs-bclri.c new file mode 100644 index 00000000000..12e2063436c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbs-bclri.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +/* bclri + bclri */ +long long f5 (long long a) +{ + return a & ~0x11000; +} + +/* { dg-final { scan-assembler-times "bclri\t" 2 } } */ +