From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1923) id 1C86B3AA8CBE; Thu, 17 Nov 2022 15:36:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1C86B3AA8CBE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1668699388; bh=7LG+Dmws/vMxRwPcEFeCexCOoE+CrB/mVCd2+8+tptY=; h=From:To:Subject:Date:From; b=mFAIbsr57qtzsrjPDeo+NskNYLc7sKAUnhq4MCAnTK35Od1kw7vhGXo8waRIT0enz EynuPUMQ0JakOIsqu7NItArR/D6rQ8GsfHm1q7JcafM73r1Ht99rTVEIPEKcjrMQFD haXVWrScmA3dFjwqyzd06O6KEItIRNE8h6XYzv/U= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Philipp Tomsich To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-4129] 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/heads/master X-Git-Oldrev: 1957bedf29a1b2cc231972aba680fe80199d5498 X-Git-Newrev: 0045d254c010bf5eac55903780c67f725192cfb3 Message-Id: <20221117153628.1C86B3AA8CBE@sourceware.org> Date: Thu, 17 Nov 2022 15:36:28 +0000 (GMT) List-Id: https://gcc.gnu.org/g:0045d254c010bf5eac55903780c67f725192cfb3 commit r13-4129-g0045d254c010bf5eac55903780c67f725192cfb3 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. 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 0dd6ebbdd0b..2175c626ee5 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -367,6 +367,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 c2ff41bb0fd..ffb3fca2ac3 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -285,3 +285,8 @@ (ior (match_operand 0 "register_operand") (match_test "GET_CODE (op) == UNSPEC && (XINT (op, 1) == UNSPEC_VUNDEF)")))) + +;; 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"))) 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 } } */ +