From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ej1-x62c.google.com (mail-ej1-x62c.google.com [IPv6:2a00:1450:4864:20::62c]) by sourceware.org (Postfix) with ESMTPS id 9E4CF3857BA1 for ; Thu, 11 Aug 2022 03:26:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9E4CF3857BA1 Received: by mail-ej1-x62c.google.com with SMTP id y13so31186907ejp.13 for ; Wed, 10 Aug 2022 20:26:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc; bh=tjz4EMQXe2noEL9XY2sZrSEW/LzlBQfwu1pE3jvfvec=; b=lptxYe/dFuNrq7+WCVGakkvYnLtZPSQ6ojZ8gzSb3VwUyKuacAmzJxuPOwuHCmD17d W3CtYsB0rdHQywjPQJ5C7tzdMUAIGk+twi3Dqx8FpHhUpr1uYQshHpzGAI29OBRYNqgC LkmIQYHQmrZP7bLF/sUge67CpdoQvbBW8iJj3GaGCVxldznws3d6GeQC/5c9YOct3h4f Avp39ekEoO+iOHUw7h6eGAM7ZWe3RRrkUPRJxdQjVd7PpQBxAiGou+7Pc5j9uMlfzB/f I0czlpvttbC+RTnB5lOYenJcCrQXRecgOLKVcm+LaqIl9WGAZq4i2MIBo7CJ0IH98JxA /Bug== X-Gm-Message-State: ACgBeo0qYTjlZbJf4PpWIjUc44GNwhpOmlMP33AQk0QJ1hUzUolgCAVK 8B/J1HaAXP608wOUZHZuLoZZxHi/nA7+5qLjstA= X-Google-Smtp-Source: AA6agR5i9n5kkjq1zqneqwpsFnGEb5aa6nSezPQOebuUNGcGqojUdwnGp1gfeOh1giCpBmzpqyBKs5uq89TZRf2nV0Y= X-Received: by 2002:a17:907:d15:b0:731:179f:9245 with SMTP id gn21-20020a1709070d1500b00731179f9245mr16832005ejc.626.1660188385167; Wed, 10 Aug 2022 20:26:25 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Kito Cheng Date: Thu, 11 Aug 2022 11:26:13 +0800 Message-ID: Subject: Re: [PATCH] RISC-V: Avoid redundant sign-extension for SImode SGE, SGEU, SLE, SLEU To: "Maciej W. Rozycki" Cc: GCC Patches , Andrew Waterman Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, 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: , X-List-Received-Date: Thu, 11 Aug 2022 03:26:28 -0000 LGTM, but with a nit, I don't get set.w but get an andi like below, so maybe we should also scan-assembler-not andi? feel free to commit that directly with that fix ```asm sleu: sgtu a0,a0,a1 # 9 [c=4 l=4] *sgtu_disi xori a0,a0,1 # 10 [c=4 l=4] *xorsi3_internal/1 andi a0,a0,1 # 16 [c=4 l=4] anddi3/1 ret # 25 [c=0 l=4] simple_return ``` On Wed, Aug 3, 2022 at 5:54 PM Maciej W. Rozycki wrote: > > 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" } } */