From: Richard Guenther <richard.guenther@gmail.com>
To: Steven Bosscher <stevenb.gcc@gmail.com>
Cc: GCC Mailing List <gcc@gcc.gnu.org>,
Richard Guenther <rguenther@suse.de>,
Alan Modra <amodra@gmail.com>
Subject: Re: A case where PHI-OPT pessimizes the code
Date: Mon, 23 Apr 2012 12:27:00 -0000 [thread overview]
Message-ID: <CAFiYyc3ZdJG_F=LeAo5JpUT_S9Ku9wV7db15EP_ZOpapXf1crA@mail.gmail.com> (raw)
In-Reply-To: <CABu31nNyBhnWHyA1y2r8G8G--QjO2vd_=2Cb1=WqFKr8VpX0xQ@mail.gmail.com>
On Mon, Apr 23, 2012 at 2:15 PM, Steven Bosscher <stevenb.gcc@gmail.com> wrote:
> Hello,
>
> I ported the code to expand switch() statements with bit tests from
> stmt.c to GIMPLE, and looked at the resulting code to verify that the
> transformation applies correctly, when I noticed this strange PHI-OPT
> transformation that results in worse code for the test case of PR45830
> which looks like this:
>
> int
> foo (int *a)
> {
> switch (*a)
> {
> case 0: case 1: case 2: case 3: case 4: case 5:
> case 19: case 20: case 21: case 22: case 23:
> case 26: case 27:
> return 1;
> default:
> return 0;
> }
> }
>
>
> After transforming the switch() to a series of bit tests, the code
> looks like this:
>
>
> ;; Function foo (foo, funcdef_no=0, decl_uid=1996, cgraph_uid=0)
>
> beginning to process the following SWITCH statement (pr45830.c:8) : -------
> switch (D.2013_3) <default: <L13>, case 0 ... 5: <L15>, case 19 ...
> 23: <L15>, case 26 ... 27: <L15>>
>
> expanding as bit test is preferableSwitch converted
> --------------------------------
> foo (int * a)
> {
> _Bool D.2023;
> long unsigned int D.2022;
> long unsigned int D.2021;
> long unsigned int csui.1;
> _Bool D.2019;
> int D.2014;
> int D.2013;
>
> <bb 2>:
> D.2013_3 = *a_2(D);
> D.2019_5 = D.2013_3 > 27;
> if (D.2019_5 != 0)
> goto <bb 3> (<L13>);
> else
> goto <bb 5>;
>
> <bb 5>:
> D.2021_7 = (long unsigned int) D.2013_3;
> csui.1_4 = 1 << D.2021_7;
> D.2022_8 = csui.1_4 & 217579583;
> D.2023_9 = D.2022_8 != 0;
> if (D.2023_9 != 0)
> goto <bb 4> (<L15>);
> else
> goto <bb 6>;
>
> <bb 6>:
>
> <L13>:
>
> # D.2014_1 = PHI <1(5), 0(3)>
> <L15>:
> return D.2014_1;
>
> }
>
>
> This is the equivalent code of what the expander in stmt.c would
> generate. Unfortunately, the first PHI-OPT pass (phiopt1) changes the
> code as follows:
>
> ;; Function foo (foo, funcdef_no=0, decl_uid=1996, cgraph_uid=0)
>
> Removing basic block 4
> foo (int * a)
> {
> int D.2026;
> _Bool D.2025;
> long unsigned int D.2022;
> long unsigned int D.2021;
> long unsigned int csui.1;
> int D.2014;
> int D.2013;
>
> <bb 2>:
> D.2013_3 = *a_2(D);
> if (D.2013_3 > 27)
> goto <bb 4> (<L15>);
> else
> goto <bb 3>;
>
> <bb 3>:
> D.2021_7 = (long unsigned int) D.2013_3;
> csui.1_4 = 1 << D.2021_7;
> D.2022_8 = csui.1_4 & 217579583;
> D.2025_9 = D.2022_8 != 0;
> D.2026_5 = (int) D.2025_9; // new statement
>
> # D.2014_1 = PHI <D.2026_5(3), 0(2)> // modified PHI node
> <L15>:
> return D.2014_1;
>
> }
>
>
> This results in worse code on powerpc64:
>
> BEFORE AFTER
> foo: foo:
> lwz 9,0(3) lwz 9,0(3)
> cmplwi 7,9,27 | cmpwi 7,9,27
> bgt 7,.L4 | bgt 7,.L3
> li 8,1 | li 3,1
> lis 10,0xcf8 lis 10,0xcf8
> sld 9,8,9 | sld 9,3,9
> ori 10,10,63 ori 10,10,63
> and. 8,9,10 and. 8,9,10
> li 3,1 | mfcr 10
> bnelr 0 | rlwinm 10,10,3,1
> .L4: | xori 3,10,1
> > blr
> > .p2align 4,,15
> > .L3:
> li 3,0 li 3,0
> blr blr
>
> BEFORE is the code that results if stmt.c expands the switch to bit
> tests (i.e. PHI-OPT never gets to transform the code as shown), and
> AFTER is with my equivalent GIMPLE implementation. Apparently, the
> optimizers are unable to recover from the transformation PHI-OPT
> performs.
>
> I am not sure how to fix this problem. I am somewhat surprised by the
> code generated by the powerpc backend for "t=(int)(_Bool)some_bool",
> because I would have expected the type range for _Bool to be <0,1> so
> that the type conversion should be a single bit test. On the other
> hand, maybe PHI-OPT should recognize this pattern and reject the
> transformation???
>
> Your thoughts/comments/suggestions, please?
>
> Ciao!
> Steven
>
>
> P.S. Unfortunately I haven't been able to produce a test case that
> shows the problem without my switch conversion pass.
int foo (_Bool b)
{
if (b)
return 1;
else
return 0;
}
PHI-OPT tries to do conditional replacement, thus transform
bb0:
if (cond) goto bb2; else goto bb1;
bb1:
bb2:
x = PHI <0 (bb1), 1 (bb0), ...>;
to
bb0:
x' = cond;
goto bb2;
bb2:
x = PHI <x' (bb0), ...>;
trying to save a compare (assuming the target has a set-cc like instruction).
I think the ppc backend should be fixed here (if possible), or the generic
expansion of this kind of pattern needs to improve. On x86_64 we simply
do
(insn 7 6 8 (set (reg:SI 63 [ D.1715 ])
(zero_extend:SI (reg/v:QI 61 [ b ]))) t.c:4 -1
(nil))
Richard.
next prev parent reply other threads:[~2012-04-23 12:27 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-23 12:16 Steven Bosscher
2012-04-23 12:27 ` Richard Guenther [this message]
2012-04-23 12:50 ` Steven Bosscher
2012-04-23 14:43 ` Alan Modra
2012-04-23 16:08 ` Steven Bosscher
2012-04-24 0:19 ` Alan Modra
2012-04-23 17:00 ` Steven Bosscher
2012-04-23 15:14 ` Jeff Law
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='CAFiYyc3ZdJG_F=LeAo5JpUT_S9Ku9wV7db15EP_ZOpapXf1crA@mail.gmail.com' \
--to=richard.guenther@gmail.com \
--cc=amodra@gmail.com \
--cc=gcc@gcc.gnu.org \
--cc=rguenther@suse.de \
--cc=stevenb.gcc@gmail.com \
/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).