Compiler bug, Pelles C V8.00 RC3 32-bit (simple example included)

Started by RichieL, May 07, 2014, 11:06:47 PM

Previous topic - Next topic

RichieL

The following short program generates bad code when compiled with "Maximize Speed".

The problem appears to be related to common sub-expression optimization. All of the selectees of the ternary conditional operations are of the form x[N]. If you change one of the selectees to another form (e.g. a constant), the program compiles correctly. It also compiles correctly with optimizations turned off.

The program:
#include <stdio.h>

int main(int argc, char **argv)
{
    float       x[5] = {1., 2., 3., 4., 5.};
    int         y;

    scanf("%d", y);
    float z = (y == 3) ? x[4] :
              (y == 0) ? x[0] :
              (y == 1) ? x[1] :
                         x[2];
    printf("f6.3", z);
}

RichieL

Here is a probably-related program with a series of ternary conditionals that also mis-compiles with "Maximize Speed", but without any common sub-expressions:

#include <stdio.h>
#include <math.h>
int main(int argc, char **argv)
{
    int     i;
    float   x, y;
    scanf("%d,%f6.3", &i, &x);
    y = (i < 3)    ? nan("low")  :
        (i > 7)    ? nan("high") :
        (x == 0.0) ? 0.0         :
                     (float)i / x;
}

Again, this program compiles correctly with optimizations = "None", but there is something weird about the output; the common jump target of the selection expression, after each selectee stores its result in [ebp - 18], is:

        fld   qword ptr [ebp-18]
        fstp  qword ptr [ebp-18]
        fld   qword ptr [ebp-18]
        fstp  qword ptr [ebp-18]
        fld   qword ptr [ebp-18]
        fstp  qword ptr [y]


A lot of action for very little result :-)

RichieL

A little more information:

I have many examples of these nested ternary conditionals in the code I'm using to test V8 - all of the examples with integer or pointer selectees compile correctly. Only the ones with floating-point selectees mis-compile.

Bitbeisser

Thanks Richie for providing me with a perfect example of how to write really bad C code, I was looking for an example like this for an upcoming programming class I am giving...

Ralf

jj2007

Thanks, Richie, for your excellent "detective work".

There are clearly some issues, e.g. the "lot of action for very little result". Pelles C is overall a very good compiler, but it must deliver correct results also for code that test its limits ;-)

TimoVJL

Nice to see someone doing lowlevel testing too :D

For disasm listing here is tool for that ;)

-- Timo
May the source be with you

DMac

Quote from: Bitbeisser on May 08, 2014, 01:52:53 AM
Thanks Richie for providing me with a perfect example of how to write really bad C code, I was looking for an example like this for an upcoming programming class I am giving...

Ralf

Ralf, that's nothing, this value returning if-else stack is reasonably elegant and easy to comprehend.  I have a much better example for the class here. Gotta love the comments I had a good laugh when I read this one.  I'll never reveal who wrote the code though.  ::)
No one cares how much you know,
until they know how much you care.

Bitbeisser

Quote from: DMac on May 08, 2014, 08:39:06 PM
Quote from: Bitbeisser on May 08, 2014, 01:52:53 AM
Thanks Richie for providing me with a perfect example of how to write really bad C code, I was looking for an example like this for an upcoming programming class I am giving...

Ralf

Ralf, that's nothing, this value returning if-else stack is reasonably elegant and easy to comprehend.
I firmly believe that nesting the ternary operators like this is a first step to seriously obfuscated code that nobody can really comprehend and a clear (counter)example of how to apply the KISS principle in programming. What some people might perceive as "reasonable elegant" leads very often to unmaintainable code IMPE.
QuoteI have a much better example for the class here. Gotta love the comments I had a good laugh when I read this one.  I'll never reveal who wrote the code though.  ::)
Don't worry, I won't tell...  :-X

But those links and the comments to that even nicer example clearly share the same thought, code like this is simply not maintainable. Not all things that a compiler/program language allow you to do are things that someone should seriously put into production code.

That the compiler in this case seems to trip over this in case of optimization is just a side effect of this...

Ralf

Pelle

/Pelle

RichieL


Pelle

/Pelle