Bug 33315 - If condition not getting eliminated
If condition not getting eliminated
Status: NEW
Product: gcc
Classification: Unclassified
Component: middle-end
4.3.0
: P2 enhancement
: ---
Assigned To: Not yet assigned to anyone
: missed-optimization
Depends on: 23286 30905
Blocks:
  Show dependency treegraph
 
Reported: 2007-09-05 18:53 UTC by Pranav Bhandarkar
Modified: 2012-02-04 02:33 UTC (History)
8 users (show)

See Also:
Host:
Target: arm-none-eabi
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-09-05 20:34:09


Attachments
Sample Testcase (274 bytes, text/x-csrc)
2007-09-05 19:03 UTC, Pranav Bhandarkar
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Pranav Bhandarkar 2007-09-05 18:53:36 UTC
if ( x == 8 ) statement1
if ( x != 8 ) statement1
if ( x == 9 ) statement2
if ( x != 9 ) statement2
should be replaced by

statement1
statement2

However this doesnt happen and compare and jumps do get generated.
Comment 1 Pranav Bhandarkar 2007-09-05 19:03:05 UTC
Created attachment 14158 [details]
Sample Testcase
Comment 2 Richard Biener 2007-09-05 20:34:07 UTC
This is related to PR32306 and to the fact that we don't have a code hoisting pass.  And related to PR30905 because cross-jumping fixes this up on the
rtl-level for both gcc 4.1 and 4.2:

test:
        pushl   %ebp
        movl    %esp, %ebp
        popl    %ebp
        movl    $0, a
        movl    $0, a+4
        movl    $0, a+8
        ret
Comment 3 Steven Bosscher 2007-11-10 00:27:07 UTC
As a missed optimization, this bug adds new information.  But as a regression, this is a dup of bug 30905.
Comment 4 Joerg Wunsch 2007-11-23 10:57:45 UTC
Is the missed optimization in the following code the same?

volatile unsigned char *reg_a = (unsigned char *)42;
volatile unsigned char *reg_b = (unsigned char *)34;

extern void a(void);
extern void b(void);
extern void c(void);

void
decide(void)
{
        signed char diff;

        diff = *reg_a - *reg_b;

        if (diff < 0)
                a();
        else if (diff == 0)
                b();
        else if (diff > 0)
                c();
}

The third "if" statement is partially executed: it apparently remembered
that diff could not be less than 0, but it still tests against 0 even
though that test has just been done before.  Verified on both, the AVR
and i386 target.

Interestingly, by just reordering the code, the third condition will
be eliminated by GCC 4.x (but not by GCC 3.x):

volatile unsigned char *reg_a = (unsigned char *)42;
volatile unsigned char *reg_b = (unsigned char *)34;

extern void a(void);
extern void b(void);
extern void c(void);

void
decide(void)
{
        signed char diff;

        diff = *reg_a - *reg_b;

        if (diff < 0)
                a();
        else if (diff > 0)
                c();
        else if (diff == 0)
                b();
}

If someone thinks that's an entirely different thing than the subject of this
bug, please tell me so, and I'll submit a separate one.
Comment 5 Dave Edwards 2008-10-21 08:28:43 UTC
Subject: RE:  If condition not getting eliminated


Hi Ramana,

Please could you add sdkteam-gnu@icerasemi.com - then we all get to see
it ;-)

Cheers,


-----Original Message-----
From: ramana at icerasemi dot com [mailto:gcc-bugzilla@gcc.gnu.org] 
Sent: 21 October 2008 08:04
To: Dave Edwards
Subject: [Bug middle-end/33315] If condition not getting eliminated



-- 

ramana at icerasemi dot com changed:

           What    |Removed                     |Added
------------------------------------------------------------------------
----
                 CC|                            |ramana at icerasemi dot
com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33315

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
Comment 6 Andrew Pinski 2012-02-04 02:33:16 UTC
tail merge should be able to do this.  It currently does not though for the provided testcase in comment #1 but that is PR 52009.
Also note cselim should be able to do it too.