optimization/10593: -O2 dead-code optimization removes the wrong code

bkuschak@yahoo.com bkuschak@yahoo.com
Fri May 2 00:26:00 GMT 2003


>Number:         10593
>Category:       optimization
>Synopsis:       -O2 dead-code optimization removes the wrong code
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Fri May 02 00:26:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Brian Kuschak
>Release:        2.95.3
>Organization:
>Environment:
Linux x86 to powerpc cross compiler gcc 2.95.3, binutils 2.11.  Also occurs on Solaris to powerpc cross.
>Description:
-O2 or -Os dead code optimization generates the wrong code for powerpc-linux.  Some instructions which should be removed are not removed, and some instructions which should remain, are removed.  With -O1, code generation is correct.  See example in How-To-Repeat section.
>How-To-Repeat:
#include <stdio.h>
static void func(int a, int b)
{
    int err;
    unsigned int port;

    switch (b) {
        case 0:
        case 1:
                err = 1;
                break;
        case 2:
        case 3:
                err = 2;
                break;
        case 4:
        default:
                err = 3;
    }

    for (port = 0; port < 5; port++) 
        printf("port: %d\n", port);
} 

With -O2, broken:
static void func(int a, int b)
{
   0:   94 21 ff f0     stwu    r1,-16(r1)
   4:   7c 08 02 a6     mflr    r0
   8:   93 e1 00 0c     stw     r31,12(r1)
   c:   90 01 00 14     stw     r0,20(r1)
    int err;
    unsigned int port;

    switch (b) {
  10:   28 04 00 04     cmplwi  r4,4    <=== should be removed
        case 0:
        case 1:
                err = 1;
                break;
        case 2:
        case 3:
                err = 2;
                break;
        case 4:
        default:
                err = 3;
    }

    for (port = 0; port < 5; port++) 
 <=== the loop count (r31) initialization is missing here
        printf("port: %d\n", port);
  14:   3c 60 00 00     lis     r3,0
  18:   7f e4 fb 78     mr      r4,r31
  1c:   38 63 00 00     addi    r3,r3,0
  20:   48 00 00 01     bl      20 <func+0x20>
  24:   3b ff 00 01     addi    r31,r31,1
  28:   28 1f 00 04     cmplwi  r31,4
  2c:   40 81 ff e8     ble     14 <func+0x14>
} 
  30:   80 01 00 14     lwz     r0,20(r1)
  34:   7c 08 03 a6     mtlr    r0
  38:   83 e1 00 0c     lwz     r31,12(r1)
  3c:   38 21 00 10     addi    r1,r1,16
  40:   4e 80 00 20     blr

With -O1:

static void func(int a, int b)
{
   0:   94 21 ff f0     stwu    r1,-16(r1)
   4:   7c 08 02 a6     mflr    r0
   8:   93 c1 00 08     stw     r30,8(r1)
   c:   93 e1 00 0c     stw     r31,12(r1)
  10:   90 01 00 14     stw     r0,20(r1)
    int err;
    unsigned int port;

    switch (b) {
  14:   28 04 00 04     cmplwi  r4,4
  18:   41 81 00 28     bgt     40 <func+0x40>
  1c:   3d 20 00 00     lis     r9,0
  20:   39 29 00 10     addi    r9,r9,16
  24:   54 80 10 3a     rlwinm  r0,r4,2,0,29
  28:   7c 09 00 2e     lwzx    r0,r9,r0
  2c:   3d 20 00 00     lis     r9,0
  30:   39 29 00 10     addi    r9,r9,16
  34:   7c 00 4a 14     add     r0,r0,r9
  38:   7c 09 03 a6     mtctr   r0
  3c:   48 00 00 04     b       40 <func+0x40>
        case 0:
        case 1:
                err = 1;
                break;
        case 2:
        case 3:
                err = 2;
                break;
        case 4:
        default:
                err = 3;
    }

    for (port = 0; port < 5; port++) 
  40:   3b e0 00 00     li      r31,0
  44:   3f c0 00 00     lis     r30,0
        printf("port: %d\n", port);
  48:   38 7e 00 00     addi    r3,r30,0
  4c:   7f e4 fb 78     mr      r4,r31
  50:   48 00 00 01     bl      50 <func+0x50>
  54:   3b ff 00 01     addi    r31,r31,1
  58:   28 1f 00 04     cmplwi  r31,4
  5c:   40 81 ff ec     ble     48 <func+0x48>
} 
  60:   80 01 00 14     lwz     r0,20(r1)
  64:   7c 08 03 a6     mtlr    r0
  68:   83 c1 00 08     lwz     r30,8(r1)
  6c:   83 e1 00 0c     lwz     r31,12(r1)
  70:   38 21 00 10     addi    r1,r1,16
  74:   4e 80 00 20     blr
>Fix:
Problem does not occur with gcc-3.2.  But I really want to fix this in 2.95.3.
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the Gcc-bugs mailing list