From: Jakub Jelinek <jakub@redhat.com>
To: gcc-patches@gcc.gnu.org, Jonathan Wakely <jwakely@redhat.com>,
Richard Biener <rguenther@suse.de>
Subject: Re: [PATCH] phiopt: Optimize (x <=> y) cmp z [PR94589]
Date: Thu, 6 May 2021 12:22:30 +0200 [thread overview]
Message-ID: <20210506102230.GY1179226@tucnak> (raw)
In-Reply-To: <20210505165227.GT1179226@tucnak>
On Wed, May 05, 2021 at 06:52:27PM +0200, Jakub Jelinek via Gcc-patches wrote:
> On Wed, May 05, 2021 at 01:45:29PM +0200, Marc Glisse wrote:
> > On Tue, 4 May 2021, Jakub Jelinek via Gcc-patches wrote:
> >
> > > 2) the pr94589-2.C testcase should be matching just 12 times each, but runs
> > > into operator>=(strong_ordering, unspecified) being defined as
> > > (_M_value&1)==_M_value
> > > rather than _M_value>=0. When not honoring NaNs, the 2 case should be
> > > unreachable and so (_M_value&1)==_M_value is then equivalent to _M_value>=0,
> > > but is not a single use but two uses. I'll need to pattern match that case
> > > specially.
> >
> > Somewhere in RTL (_M_value&1)==_M_value is turned into (_M_value&-2)==0,
> > that could be worth doing already in GIMPLE.
>
> Apparently it is
> /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
> constant folding if x/y is a constant. */
> if ((code == EQ || code == NE)
> && (op0code == AND || op0code == IOR)
> && !side_effects_p (op1)
> && op1 != CONST0_RTX (cmp_mode))
> {
> /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
> (eq/ne (and (not y) x) 0). */
> ...
> /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
> (eq/ne (and (not x) y) 0). */
> Yes, doing that on GIMPLE for the case where the not argument is constant
> would simplify the phiopt follow-up (it would be single imm use then).
Though, (x&1) == x is equivalent to both (x&~1)==0 and to x < 2U
and from the latter two it isn't obvious which one is better/more canonical.
On aarch64 I don't see differences in number of insns nor in their size:
10: 13001c00 sxtb w0, w0
14: 721f781f tst w0, #0xfffffffe
18: 1a9f17e0 cset w0, eq // eq = none
1c: d65f03c0 ret
vs.
20: 12001c00 and w0, w0, #0xff
24: 7100041f cmp w0, #0x1
28: 1a9f87e0 cset w0, ls // ls = plast
2c: d65f03c0 ret
On x86_64 same number of insns, but the comparison is shorter (note, the
spaceship result is a struct with signed char based enum):
10: 31 c0 xor %eax,%eax
12: 81 e7 fe 00 00 00 and $0xfe,%edi
18: 0f 94 c0 sete %al
1b: c3 retq
1c: 0f 1f 40 00 nopl 0x0(%rax)
vs.
20: 31 c0 xor %eax,%eax
22: 40 80 ff 01 cmp $0x1,%dil
26: 0f 96 c0 setbe %al
29: c3 retq
Generally, I'd think that the comparison should be better because it
will be most common in user code that way and VRP will be able to do the
best thing for it.
Before we decide how to optimize it, can't we change libstdc++
to use the more efficient implementation?
I.e. either following, or { return (__v._M_value & ~1) == 0; } ?
2021-05-06 Jakub Jelinek <jakub@redhat.com>
* compare (operator>=(partial_ordering, __cmp_cat::__unspec),
operator<=(__cmp_cat::__unspec, partial_ordering)): Simplify to
(unsigned char) __v._M_value < 2.
--- gcc/compare.jj 2021-03-10 17:36:41.288491012 +0100
+++ gcc/compare 2021-05-06 11:44:37.519553192 +0200
@@ -107,7 +107,7 @@ namespace std
friend constexpr bool
operator>=(partial_ordering __v, __cmp_cat::__unspec) noexcept
- { return __cmp_cat::type(__v._M_value & 1) == __v._M_value; }
+ { return static_cast<unsigned char>(__v._M_value) < 2; }
friend constexpr bool
operator< (__cmp_cat::__unspec, partial_ordering __v) noexcept
@@ -119,7 +119,7 @@ namespace std
friend constexpr bool
operator<=(__cmp_cat::__unspec, partial_ordering __v) noexcept
- { return __cmp_cat::type(__v._M_value & 1) == __v._M_value; }
+ { return static_cast<unsigned char>(__v._M_value) < 2; }
friend constexpr bool
operator>=(__cmp_cat::__unspec, partial_ordering __v) noexcept
Jakub
next prev parent reply other threads:[~2021-05-06 10:22 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-04 7:44 Jakub Jelinek
2021-05-04 9:42 ` Jonathan Wakely
2021-05-04 9:56 ` Jakub Jelinek
2021-05-05 11:39 ` Richard Biener
2021-05-05 13:18 ` [PATCH] phiopt, v2: " Jakub Jelinek
2021-05-05 14:17 ` Richard Biener
2021-05-05 11:45 ` [PATCH] phiopt: " Marc Glisse
2021-05-05 16:52 ` Jakub Jelinek
2021-05-06 10:22 ` Jakub Jelinek [this message]
2021-05-06 19:42 ` Marc Glisse
2021-05-11 7:34 ` [PATCH] match.pd: Optimize (x & y) == x into (x & ~y) == 0 [PR94589] Jakub Jelinek
2021-05-11 8:11 ` Marc Glisse
2021-05-11 8:20 ` Richard Biener
2021-05-14 17:26 ` [PATCH] phiopt: Optimize (x <=> y) cmp z [PR94589] Jakub Jelinek
2021-05-15 10:09 ` Marc Glisse
2021-05-05 15:45 ` Martin Sebor
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=20210506102230.GY1179226@tucnak \
--to=jakub@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jwakely@redhat.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).