From patchwork Wed Aug 3 09:54:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 56517 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 2479F383602A for ; Wed, 3 Aug 2022 09:54:44 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by sourceware.org (Postfix) with ESMTPS id 3A27D3858292 for ; Wed, 3 Aug 2022 09:54:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3A27D3858292 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-wm1-x330.google.com with SMTP id v131-20020a1cac89000000b003a4bb3f786bso671498wme.0 for ; Wed, 03 Aug 2022 02:54:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=date:from:to:cc:subject:message-id:user-agent:mime-version; bh=vOtu2rWaBDCOibxksVDb11aBbxyFGQbizRDRp1uItMI=; b=eNrBQj4cnlWPBk1Ufr+gyCJT3aNltrvVCjGywaWdp/eDlPSXLSZmHe8BYWALhIWAXD sFG8jGs/gj9LQiuntN7vTSI7Sxm+Ad1GysagAFVCNkuy/+0nr6ewhIunpGFJdzlqsnFZ PZS7rBz1N4goBCj5Q+w0SIfxVFGprtK7PulWtLjQhnhUHfUCQFEq8tKPnBiUjwfCu57c 8iSRbAjElftRow2WjNCiwmgtJE+nmflVH9vLN21Qw/GD4spAOt7DLA6+IxgjqYlhT+Qx LM+bKp7DSSSiLYnf0QMlDEjS6Bd4PoyyerW6mh5DaQIhPzP+smMwA2Fc6PlTWOP1TCSb L5Bg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:user-agent :mime-version; bh=vOtu2rWaBDCOibxksVDb11aBbxyFGQbizRDRp1uItMI=; b=jDXJ0yPyPdJz7C3R08UnJay+S7LxP3Mfr9audHY0w35k26AHGeFQeL4vbotqyALpPX D4W9+lHiMoEu/TIP4uIvnc6Ae8Gy+Q4Uxc982KBDSKTZ7sIJ+aaOexlIDgp4HK/Pq7Ge v7WR/4LHAf92joUwczdK6z/6Hhk2neQQeXQbN6g+96CsYL6WXuK1MWmHPxOq3/0BZwWb +hYAyUoYWqibUP06R37YVCMIBHSw0k5HubfglQ3s1gZcFErcDN+rVGXZw+PMA1Yko+qA dFkGWD6pYXMJqIODiEjUoH+y2HWg5mfOTVu2gO+jLd+HQG/fdhmKRKXaR/YKYRweye2q EqRA== X-Gm-Message-State: ACgBeo07uEYK3zk8oy3q/8pzi6AQGHqOqyEkNljpQ6Z774YbpFNUeFW1 0ZkOrY9VMyZNBuJBO7BfttRkeH3Kk+9aP3hg X-Google-Smtp-Source: AA6agR6YxIQPsqQoTUuzGKziaNfp9YeFY2kkB6mWd+8huoQfZ59OHhP0zJpvVMG1kxEzlEPSvfKEFg== X-Received: by 2002:a05:600c:21d4:b0:3a3:10a0:cc4f with SMTP id x20-20020a05600c21d400b003a310a0cc4fmr2308724wmj.75.1659520449824; Wed, 03 Aug 2022 02:54:09 -0700 (PDT) Received: from [172.16.1.110] ([194.168.26.145]) by smtp.gmail.com with ESMTPSA id k12-20020a5d524c000000b002205ffe88edsm10400164wrc.31.2022.08.03.02.54.09 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 03 Aug 2022 02:54:09 -0700 (PDT) Date: Wed, 3 Aug 2022 10:54:08 +0100 (BST) From: "Maciej W. Rozycki" To: gcc-patches@gcc.gnu.org Subject: [PATCH] RISC-V: Avoid redundant sign-extension for SImode SGE, SGEU, SLE, SLEU Message-ID: User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 X-Spam-Status: No, score=-0.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK autolearn=no 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: , Cc: Andrew Waterman , Kito Cheng Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" We produce inefficient code for some synthesized SImode conditional set operations (i.e. ones that are not directly implemented in hardware) on RV64. For example a piece of C code like this: int sleu (unsigned int x, unsigned int y) { return x <= y; } gets compiled (at `-O2') to this: sleu: sgtu a0,a0,a1 # 9 [c=4 l=4] *sgtu_disi xori a0,a0,1 # 10 [c=4 l=4] *xorsi3_internal/1 sext.w a0,a0 # 16 [c=4 l=4] extendsidi2/0 ret # 25 [c=0 l=4] simple_return This is because the middle end expands a SLEU operation missing from RISC-V hardware into a sequence of a SImode SGTU operation followed by an explicit SImode XORI operation with immediate 1. And while the SGTU machine instruction (alias SLTU with the input operands swapped) gives a properly sign-extended 32-bit result which is valid both as a SImode or a DImode operand the middle end does not see that through a SImode XORI operation, because we tell the middle end that the RISC-V target (unlike MIPS) may hold values in DImode integer registers that are valid for SImode operations even if not properly sign-extended. However the RISC-V psABI requires that 32-bit function arguments and results passed in 64-bit integer registers be properly sign-extended, so this is explicitly done at the conclusion of the function. Fix this by making the backend use a sequence of a DImode SGTU operation followed by a SImode SEQZ operation instead. The latter operation is known by the middle end to produce a properly sign-extended 32-bit result and therefore combine gets rid of the sign-extension operation that follows and actually folds it into the very same XORI machine operation resulting in: sleu: sgtu a0,a0,a1 # 9 [c=4 l=4] *sgtu_didi xori a0,a0,1 # 16 [c=4 l=4] xordi3/1 ret # 25 [c=0 l=4] simple_return instead (although the SEQZ alias SLTIU against immediate 1 machine instruction would equally do and is actually retained at `-O0'). This is handled analogously for the remaining synthesized operations of this kind, i.e. `SLE', `SGEU', and `SGE'. gcc/ * config/riscv/riscv.cc (riscv_emit_int_order_test): Use EQ 0 rather that XOR 1 for LE and LEU operations. gcc/testsuite/ * gcc.target/riscv/sge.c: New test. * gcc.target/riscv/sgeu.c: New test. * gcc.target/riscv/sle.c: New test. * gcc.target/riscv/sleu.c: New test. --- Hi, Regression-tested with the `riscv64-linux-gnu' target. OK to apply? Maciej --- gcc/config/riscv/riscv.cc | 4 ++-- gcc/testsuite/gcc.target/riscv/sge.c | 11 +++++++++++ gcc/testsuite/gcc.target/riscv/sgeu.c | 11 +++++++++++ gcc/testsuite/gcc.target/riscv/sle.c | 11 +++++++++++ gcc/testsuite/gcc.target/riscv/sleu.c | 11 +++++++++++ 5 files changed, 46 insertions(+), 2 deletions(-) gcc-riscv-int-order-inv-seqz.diff Index: gcc/gcc/config/riscv/riscv.cc =================================================================== --- gcc.orig/gcc/config/riscv/riscv.cc +++ gcc/gcc/config/riscv/riscv.cc @@ -2500,9 +2500,9 @@ riscv_emit_int_order_test (enum rtx_code } else if (invert_ptr == 0) { - rtx inv_target = riscv_force_binary (GET_MODE (target), + rtx inv_target = riscv_force_binary (word_mode, inv_code, cmp0, cmp1); - riscv_emit_binary (XOR, target, inv_target, const1_rtx); + riscv_emit_binary (EQ, target, inv_target, const0_rtx); } else { Index: gcc/gcc/testsuite/gcc.target/riscv/sge.c =================================================================== --- /dev/null +++ gcc/gcc/testsuite/gcc.target/riscv/sge.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +int +sge (int x, int y) +{ + return x >= y; +} + +/* { dg-final { scan-assembler-not "sext\\.w" } } */ Index: gcc/gcc/testsuite/gcc.target/riscv/sgeu.c =================================================================== --- /dev/null +++ gcc/gcc/testsuite/gcc.target/riscv/sgeu.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +int +sgeu (unsigned int x, unsigned int y) +{ + return x >= y; +} + +/* { dg-final { scan-assembler-not "sext\\.w" } } */ Index: gcc/gcc/testsuite/gcc.target/riscv/sle.c =================================================================== --- /dev/null +++ gcc/gcc/testsuite/gcc.target/riscv/sle.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +int +sle (int x, int y) +{ + return x <= y; +} + +/* { dg-final { scan-assembler-not "sext\\.w" } } */ Index: gcc/gcc/testsuite/gcc.target/riscv/sleu.c =================================================================== --- /dev/null +++ gcc/gcc/testsuite/gcc.target/riscv/sleu.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +int +sleu (unsigned int x, unsigned int y) +{ + return x <= y; +} + +/* { dg-final { scan-assembler-not "sext\\.w" } } */