From patchwork Tue Nov 8 20:46:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Philipp Tomsich X-Patchwork-Id: 60234 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 085A3385829B for ; Tue, 8 Nov 2022 20:46:50 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-lj1-x232.google.com (mail-lj1-x232.google.com [IPv6:2a00:1450:4864:20::232]) by sourceware.org (Postfix) with ESMTPS id 416663858D3C for ; Tue, 8 Nov 2022 20:46:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 416663858D3C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu Received: by mail-lj1-x232.google.com with SMTP id l8so22871936ljh.13 for ; Tue, 08 Nov 2022 12:46:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=s1L0TyJJkJ3JNEjn3Tb68bjlIKftEgy724EKdtpPVTk=; b=Xa5/A0FRc+aH8lzHCpgwGE/unWQQbrOBVV6Rv/XTiOIYbHB5yBW5MF8jRQVTTHdgnN gmiC0TPkCHbL7vKcZz6ryYQmHchMLUWhVzEbW2sgNBYCkVup2sJHsnidIqCvcxDsUXjN ZvKuHzHRdCk4Lmx/8hvdnmV/hl3hclO3toXYQdnN2y6khl/IDFOz5f2KB/6u79zyByEY Ydy93BaWLyvZRP9/ydpZDrS3Dl+6zwB7kW4T5c9Pn7WBvsfIU9mJxfEyKrbEPTh2KUnT AD7Ft4ZAPgQ78p+kBoBjiUog1PM8KnurbeL12uVfd5D74unJS/skYMlYJnfk9NwG1LYg etJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=s1L0TyJJkJ3JNEjn3Tb68bjlIKftEgy724EKdtpPVTk=; b=2QAkKnzNeMVWjH3nglVvOIvgsurD5HOju3g0DTat+eJeDqtH4Bk6bWMUuet8JON30W oxMUfwCq87cbaxthEskLjxlROTdAGbri+oFRPUQ6bPyb8587vn/Zozns95V+4EyvxvlT t/4KNYQje+zqHCq4ES2duYlinZ34/dXC6fUdp0il4iKV2clC/g18ilPhug6I5Vt4aLBX NtMBrX8WotJxoz1P4yZaHDPKnXn45Hs/qDkc8530T0xo6l3dmGW0ITxr1EOw6H43mwIJ sPaN7PtxGupAy0jG3kBUeb4qqO1GVBjnJFlKDNi8drt/uxZ9I43VFqHsjfzAPacvVQPX ruiQ== X-Gm-Message-State: ACrzQf2aBbiAzTaLA6wPCFnUknmKxxe0LusAZMoejQL2E4kluV3hqPVZ nu3i0wyCpeGBJRhL/nkAlYE8b5Otsidrmui/ X-Google-Smtp-Source: AMsMyM6feNIwv3dxIv7kzAYRR5DfwXkOVxz1XukSTildPxzIc6GOTBELgALmFC/LA36ZAfXHEH6tMQ== X-Received: by 2002:a05:651c:1a0d:b0:277:113c:9e89 with SMTP id by13-20020a05651c1a0d00b00277113c9e89mr20291980ljb.245.1667940390239; Tue, 08 Nov 2022 12:46:30 -0800 (PST) Received: from ubuntu-focal.. ([2a01:4f9:3a:1e26::2]) by smtp.gmail.com with ESMTPSA id 7-20020ac25f07000000b0049735cec78dsm1926899lfq.67.2022.11.08.12.46.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Nov 2022 12:46:29 -0800 (PST) From: Philipp Tomsich To: gcc-patches@gcc.gnu.org Cc: Palmer Dabbelt , Christoph Muellner , Vineet Gupta , Jeff Law , Kito Cheng , Philipp Tomsich Subject: [PATCH] RISC-V: Optimize branches testing a bit-range or a shifted immediate Date: Tue, 8 Nov 2022 21:46:25 +0100 Message-Id: <20221108204625.2794920-1-philipp.tomsich@vrull.eu> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" gcc/ChangeLog: * config/riscv/predicates.md (shifted_const_arith_operand): (uimm_extra_bit_operand): * config/riscv/riscv.md (*branch_shiftedarith_equals_zero): (*branch_shiftedmask_equals_zero): gcc/testsuite/ChangeLog: * gcc.target/riscv/branch-1.c: New test. Signed-off-by: Philipp Tomsich --- gcc/config/riscv/predicates.md | 23 ++++++++++ gcc/config/riscv/riscv.md | 51 +++++++++++++++++++++++ gcc/testsuite/gcc.target/riscv/branch-1.c | 37 ++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/branch-1.c diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index c2ff41bb0fd..6772228e5b6 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -285,3 +285,26 @@ (ior (match_operand 0 "register_operand") (match_test "GET_CODE (op) == UNSPEC && (XINT (op, 1) == UNSPEC_VUNDEF)")))) + +;; A CONST_INT operand that consists of a single run of 32 consecutive +;; set bits. +(define_predicate "consecutive_bits32_operand" + (and (match_operand 0 "consecutive_bits_operand") + (match_test "popcount_hwi (UINTVAL (op)) == 32"))) + +;; A CONST_INT operand that, if shifted down to start with its least +;; significant non-zero bit, is a SMALL_OPERAND (suitable as an +;; immediate to logical and arithmetic instructions). +(define_predicate "shifted_const_arith_operand" + (and (match_code "const_int") + (match_test "ctz_hwi (INTVAL (op)) > 0") + (match_test "SMALL_OPERAND (INTVAL (op) >> ctz_hwi (INTVAL (op)))"))) + +;; 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" + (and (match_code "const_int") + (not (and (match_test "SMALL_OPERAND (INTVAL (op))") + (match_test "INTVAL (op) > 0"))) + (ior (match_test "SMALL_OPERAND (UINTVAL (op) & ~(HOST_WIDE_INT_1U << floor_log2 (UINTVAL (op))))") + (match_test "popcount_hwi (UINTVAL (op)) == 2")))) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 97f6ca37891..171a0cdced6 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -2205,6 +2205,57 @@ ;; Conditional branches +(define_insn_and_split "*branch_shiftedarith_equals_zero" + [(set (pc) + (if_then_else (match_operator 1 "equality_operator" + [(and:ANYI (match_operand:ANYI 2 "register_operand" "r") + (match_operand 3 "shifted_const_arith_operand" "i")) + (const_int 0)]) + (label_ref (match_operand 0 "" "")) + (pc))) + (clobber (match_scratch:ANYI 4 "=&r"))] + "INTVAL (operands[3]) >= 0 || !partial_subreg_p (operands[2])" + "#" + "&& reload_completed" + [(set (match_dup 4) (lshiftrt:ANYI (match_dup 2) (match_dup 6))) + (set (match_dup 4) (and:ANYI (match_dup 4) (match_dup 7))) + (set (pc) (if_then_else (match_op_dup 1 [(match_dup 4) (const_int 0)]) + (label_ref (match_dup 0)) (pc)))] +{ + HOST_WIDE_INT mask = INTVAL (operands[3]); + int trailing = ctz_hwi (mask); + + operands[6] = GEN_INT (trailing); + operands[7] = GEN_INT (mask >> trailing); +}) + +(define_insn_and_split "*branch_shiftedmask_equals_zero" + [(set (pc) + (if_then_else (match_operator 1 "equality_operator" + [(and:ANYI (match_operand:ANYI 2 "register_operand" "r") + (match_operand 3 "consecutive_bits_operand" "i")) + (const_int 0)]) + (label_ref (match_operand 0 "" "")) + (pc))) + (clobber (match_scratch:X 4 "=&r"))] + "(INTVAL (operands[3]) >= 0 || !partial_subreg_p (operands[2])) + && popcount_hwi (INTVAL (operands[3])) > 1 + && !SMALL_OPERAND (INTVAL (operands[3]))" + "#" + "&& reload_completed" + [(set (match_dup 4) (ashift:X (subreg:X (match_dup 2) 0) (match_dup 6))) + (set (match_dup 4) (lshiftrt:X (match_dup 4) (match_dup 7))) + (set (pc) (if_then_else (match_op_dup 1 [(match_dup 4) (const_int 0)]) + (label_ref (match_dup 0)) (pc)))] +{ + unsigned HOST_WIDE_INT mask = INTVAL (operands[3]); + int leading = clz_hwi (mask); + int trailing = ctz_hwi (mask); + + operands[6] = GEN_INT (leading); + operands[7] = GEN_INT (leading + trailing); +}) + (define_insn "*branch_equals_zero" [(set (pc) (if_then_else diff --git a/gcc/testsuite/gcc.target/riscv/branch-1.c b/gcc/testsuite/gcc.target/riscv/branch-1.c new file mode 100644 index 00000000000..b4a3a946379 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/branch-1.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */ + +void g(); + +void f(long long a) +{ + if (a & 0xff00) + g(); +} + +void f2(long long a) +{ + if (a & (-4ull << 3)) + g(); +} + +void f3(long long a) +{ + if (a & 0xffff00) + g(); +} + +void f4(long long a) +{ + if (a & 0x7ff800) + g(); +} + +/* { dg-final { scan-assembler-times "slli\t" 2 } } */ +/* { dg-final { scan-assembler-times "srli\t" 3 } } */ +/* { dg-final { scan-assembler-times "andi\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tli\t" 1 } } */ +/* { dg-final { scan-assembler-not "addi\t" } } */ +/* { dg-final { scan-assembler-not "and\t" } } */ +