public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Tamar Christina <Tamar.Christina@arm.com>
To: Richard Earnshaw <Richard.Earnshaw@foss.arm.com>,
	"gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>
Cc: nd <nd@arm.com>, "rguenther@suse.de" <rguenther@suse.de>
Subject: RE: [PATCH]middle-end convert negate + right shift into compare greater.
Date: Tue, 5 Oct 2021 13:49:57 +0000	[thread overview]
Message-ID: <AM0PR08MB5316A0743F080EE148D1F62FFFAF9@AM0PR08MB5316.eurprd08.prod.outlook.com> (raw)
In-Reply-To: <e6c816e6-501c-6173-9f64-7b73c3b3853c@foss.arm.com>

> -----Original Message-----
> From: Richard Earnshaw <Richard.Earnshaw@foss.arm.com>
> Sent: Tuesday, October 5, 2021 2:34 PM
> To: Tamar Christina <Tamar.Christina@arm.com>; gcc-patches@gcc.gnu.org
> Cc: nd <nd@arm.com>; rguenther@suse.de
> Subject: Re: [PATCH]middle-end convert negate + right shift into compare
> greater.
> 
> 
> 
> On 05/10/2021 14:30, Tamar Christina wrote:
> >
> >
> >> -----Original Message-----
> >> From: Richard Earnshaw <Richard.Earnshaw@foss.arm.com>
> >> Sent: Tuesday, October 5, 2021 1:56 PM
> >> To: Tamar Christina <Tamar.Christina@arm.com>;
> >> gcc-patches@gcc.gnu.org
> >> Cc: nd <nd@arm.com>; rguenther@suse.de
> >> Subject: Re: [PATCH]middle-end convert negate + right shift into
> >> compare greater.
> >>
> >>
> >>
> >> On 05/10/2021 13:50, Tamar Christina via Gcc-patches wrote:
> >>> Hi All,
> >>>
> >>> This turns an inversion of the sign bit + arithmetic right shift
> >>> into a comparison with 0.
> >>>
> >>> i.e.
> >>>
> >>> void fun1(int32_t *x, int n)
> >>> {
> >>>       for (int i = 0; i < (n & -16); i++)
> >>>         x[i] = (-x[i]) >> 31;
> >>> }
> >>>
> >> Notwithstanding that I think shifting a negative value right is
> >> unspecified behaviour, I don't think this generates the same result
> >> when x[i] is INT_MIN either, although negating that is also
> >> unspecified since it can't be represented in an int.
> >>
> >
> > You're right that they are implementation defined, but I think most
> > ISAs do have a sane Implementation of these two cases. At least both
> > x86 and AArch64 just replicate the signbit and for negate do two
> complement negation. So INT_MIN works as expected and results in 0.
> 
> Which is not what the original code produces if you have wrapping ints,
> because -INT_MIN is INT_MIN, and thus still negative.
> 

True, but then you have a signed overflow which is undefined behaviour and not implementation defined

" If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined."

So it should still be acceptable to do in this case.

> R.
> 
> >
> > But I'm happy to guard this behind some sort of target guard.
> >
> > Regards,
> > Tamar
> >
> >> R.
> >>
> >>> now generates:
> >>>
> >>> .L3:
> >>>           ldr     q0, [x0]
> >>>           cmgt    v0.4s, v0.4s, #0
> >>>           str     q0, [x0], 16
> >>>           cmp     x0, x1
> >>>           bne     .L3
> >>>
> >>> instead of:
> >>>
> >>> .L3:
> >>>           ldr     q0, [x0]
> >>>           neg     v0.4s, v0.4s
> >>>           sshr    v0.4s, v0.4s, 31
> >>>           str     q0, [x0], 16
> >>>           cmp     x0, x1
> >>>           bne     .L3
> >>>
> >>> Bootstrapped Regtested on aarch64-none-linux-gnu,
> >>> x86_64-pc-linux-gnu and no regressions.
> >>>
> >>> Ok for master?
> >>>
> >>> Thanks,
> >>> Tamar
> >>>
> >>> gcc/ChangeLog:
> >>>
> >>> 	* match.pd: New negate+shift pattern.
> >>>
> >>> gcc/testsuite/ChangeLog:
> >>>
> >>> 	* gcc.dg/signbit-2.c: New test.
> >>> 	* gcc.dg/signbit-3.c: New test.
> >>> 	* gcc.target/aarch64/signbit-1.c: New test.
> >>>
> >>> --- inline copy of patch --
> >>> diff --git a/gcc/match.pd b/gcc/match.pd index
> >>
> 7d2a24dbc5e9644a09968f877e12a824d8ba1caa..581436fe36dbacdcb0c2720b7
> >> 190c96d14398143 100644
> >>> --- a/gcc/match.pd
> >>> +++ b/gcc/match.pd
> >>> @@ -826,6 +826,37 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >>>        { tree utype = unsigned_type_for (type); }
> >>>        (convert (rshift (lshift (convert:utype @0) @2) @3))))))
> >>>
> >>> +/* Fold (-x >> C) into x > 0 where C = precision(type) - 1.  */
> >>> +(for cst (INTEGER_CST VECTOR_CST)  (simplify
> >>> +  (rshift (negate:s @0) cst@1)
> >>> +   (with { tree ctype = TREE_TYPE (@0);
> >>> +	   tree stype = TREE_TYPE (@1);
> >>> +	   tree bt = truth_type_for (ctype); }
> >>> +    (switch
> >>> +     /* Handle scalar case.  */
> >>> +     (if (INTEGRAL_TYPE_P (ctype)
> >>> +	  && !VECTOR_TYPE_P (ctype)
> >>> +	  && !TYPE_UNSIGNED (ctype)
> >>> +	  && canonicalize_math_after_vectorization_p ()
> >>> +	  && wi::eq_p (wi::to_wide (@1), TYPE_PRECISION (stype) - 1))
> >>> +      (convert:bt (gt:bt @0 { build_zero_cst (stype); })))
> >>> +     /* Handle vector case with a scalar immediate.  */
> >>> +     (if (VECTOR_INTEGER_TYPE_P (ctype)
> >>> +	  && !VECTOR_TYPE_P (stype)
> >>> +	  && !TYPE_UNSIGNED (ctype)
> >>> +          && wi::eq_p (wi::to_wide (@1), TYPE_PRECISION (stype) - 1))
> >>> +      (convert:bt (gt:bt @0 { build_zero_cst (ctype); })))
> >>> +     /* Handle vector case with a vector immediate.   */
> >>> +     (if (VECTOR_INTEGER_TYPE_P (ctype)
> >>> +	  && VECTOR_TYPE_P (stype)
> >>> +	  && !TYPE_UNSIGNED (ctype)
> >>> +	  && uniform_vector_p (@1))
> >>> +      (with { tree cst = vector_cst_elt (@1, 0);
> >>> +	      tree t = TREE_TYPE (cst); }
> >>> +       (if (wi::eq_p (wi::to_wide (cst), TYPE_PRECISION (t) - 1))
> >>> +        (convert:bt (gt:bt @0 { build_zero_cst (ctype); })))))))))
> >>> +
> >>>    /* Fold (C1/X)*C2 into (C1*C2)/X.  */
> >>>    (simplify
> >>>     (mult (rdiv@3 REAL_CST@0 @1) REAL_CST@2) diff --git
> >>> a/gcc/testsuite/gcc.dg/signbit-2.c b/gcc/testsuite/gcc.dg/signbit-
> >> 2.c
> >>> new file mode 100644
> >>> index
> >>
> 0000000000000000000000000000000000000000..fc0157cbc5c7996b481f2998bc
> >> 30176c96a669bb
> >>> --- /dev/null
> >>> +++ b/gcc/testsuite/gcc.dg/signbit-2.c
> >>> @@ -0,0 +1,19 @@
> >>> +/* { dg-do assemble } */
> >>> +/* { dg-options "-O3 --save-temps -fdump-tree-optimized" } */
> >>> +
> >>> +#include <stdint.h>
> >>> +
> >>> +void fun1(int32_t *x, int n)
> >>> +{
> >>> +    for (int i = 0; i < (n & -16); i++)
> >>> +      x[i] = (-x[i]) >> 31;
> >>> +}
> >>> +
> >>> +void fun2(int32_t *x, int n)
> >>> +{
> >>> +    for (int i = 0; i < (n & -16); i++)
> >>> +      x[i] = (-x[i]) >> 30;
> >>> +}
> >>> +
> >>> +/* { dg-final { scan-tree-dump-times {\s+>\s+\{ 0, 0, 0, 0 \}} 1
> >>> +optimized } }
> >> */
> >>> +/* { dg-final { scan-tree-dump-not {\s+>>\s+31} optimized } } */
> >>> diff --git a/gcc/testsuite/gcc.dg/signbit-3.c
> >>> b/gcc/testsuite/gcc.dg/signbit-
> >> 3.c
> >>> new file mode 100644
> >>> index
> >>
> 0000000000000000000000000000000000000000..19e9c06c349b3287610f817628
> >> f00938ece60bf7
> >>> --- /dev/null
> >>> +++ b/gcc/testsuite/gcc.dg/signbit-3.c
> >>> @@ -0,0 +1,13 @@
> >>> +/* { dg-do assemble } */
> >>> +/* { dg-options "-O1 --save-temps -fdump-tree-optimized" } */
> >>> +
> >>> +#include <stdint.h>
> >>> +
> >>> +void fun1(int32_t *x, int n)
> >>> +{
> >>> +    for (int i = 0; i < (n & -16); i++)
> >>> +      x[i] = (-x[i]) >> 31;
> >>> +}
> >>> +
> >>> +/* { dg-final { scan-tree-dump-times {\s+>\s+0;} 1 optimized } } */
> >>> +/* { dg-final { scan-tree-dump-not {\s+>>\s+31} optimized } } */
> >>> diff --git a/gcc/testsuite/gcc.target/aarch64/signbit-1.c
> >> b/gcc/testsuite/gcc.target/aarch64/signbit-1.c
> >>> new file mode 100644
> >>> index
> >>
> 0000000000000000000000000000000000000000..3ebfb0586f37de29cf58635b27
> >> fe48503714447e
> >>> --- /dev/null
> >>> +++ b/gcc/testsuite/gcc.target/aarch64/signbit-1.c
> >>> @@ -0,0 +1,18 @@
> >>> +/* { dg-do assemble } */
> >>> +/* { dg-options "-O3 --save-temps" } */
> >>> +
> >>> +#include <stdint.h>
> >>> +
> >>> +void fun1(int32_t *x, int n)
> >>> +{
> >>> +    for (int i = 0; i < (n & -16); i++)
> >>> +      x[i] = (-x[i]) >> 31;
> >>> +}
> >>> +
> >>> +void fun2(int32_t *x, int n)
> >>> +{
> >>> +    for (int i = 0; i < (n & -16); i++)
> >>> +      x[i] = (-x[i]) >> 30;
> >>> +}
> >>> +
> >>> +/* { dg-final { scan-assembler-times {\tcmgt\t} 1 } } */
> >>>
> >>>

  reply	other threads:[~2021-10-05 13:50 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-05 12:50 Tamar Christina
2021-10-05 12:56 ` Richard Earnshaw
2021-10-05 13:30   ` Tamar Christina
2021-10-05 13:34     ` Richard Earnshaw
2021-10-05 13:49       ` Tamar Christina [this message]
2021-10-05 13:51         ` Richard Earnshaw
2021-10-05 13:56           ` Tamar Christina
2021-10-07 12:46             ` Richard Earnshaw
2021-10-11 11:36               ` Tamar Christina
2021-10-13 12:11                 ` Richard Biener
2021-10-15  7:48                   ` Tamar Christina
2021-10-15  9:06                     ` Richard Biener
2021-10-15 10:36                       ` Richard Earnshaw
2021-10-15 10:57                         ` Richard Biener
2021-10-15 11:55                       ` Tamar Christina
     [not found]                         ` <VI1PR08MB5325D87574F2D09568EF5C40FF849@VI1PR08MB5325.eurprd08.prod.outlook.com>
     [not found]                           ` <34p8433-751p-2n5s-qp50-r8rss490npop@fhfr.qr>
2021-11-03 13:21                             ` Tamar Christina
2021-11-04 13:06                               ` Richard Biener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AM0PR08MB5316A0743F080EE148D1F62FFFAF9@AM0PR08MB5316.eurprd08.prod.outlook.com \
    --to=tamar.christina@arm.com \
    --cc=Richard.Earnshaw@foss.arm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=nd@arm.com \
    --cc=rguenther@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).