From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21797 invoked by alias); 23 Apr 2012 12:16:10 -0000 Received: (qmail 21751 invoked by uid 22791); 23 Apr 2012 12:16:06 -0000 X-SWARE-Spam-Status: No, hits=-3.9 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,KHOP_RCVD_TRUST,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE,TW_BG,TW_LW,TW_PL X-Spam-Check-By: sourceware.org Received: from mail-yw0-f47.google.com (HELO mail-yw0-f47.google.com) (209.85.213.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 23 Apr 2012 12:15:47 +0000 Received: by yhjj56 with SMTP id j56so6471559yhj.20 for ; Mon, 23 Apr 2012 05:15:46 -0700 (PDT) MIME-Version: 1.0 Received: by 10.236.154.2 with SMTP id g2mr14487153yhk.103.1335183346429; Mon, 23 Apr 2012 05:15:46 -0700 (PDT) Received: by 10.101.118.15 with HTTP; Mon, 23 Apr 2012 05:15:46 -0700 (PDT) Date: Mon, 23 Apr 2012 12:16:00 -0000 Message-ID: Subject: A case where PHI-OPT pessimizes the code From: Steven Bosscher To: GCC Mailing List Cc: Richard Guenther , Alan Modra Content-Type: text/plain; charset=ISO-8859-1 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org X-SW-Source: 2012-04/txt/msg00781.txt.bz2 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) , case 0 ... 5: , case 19 ... 23: , case 26 ... 27: > 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; : D.2013_3 = *a_2(D); D.2019_5 = D.2013_3 > 27; if (D.2019_5 != 0) goto (); else goto ; : 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 (); else goto ; : : # D.2014_1 = PHI <1(5), 0(3)> : 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; : D.2013_3 = *a_2(D); if (D.2013_3 > 27) goto (); else goto ; : 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 // modified PHI node : 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.