www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - dmd optimizer bug under linux

reply Janzert <janzert janzert.com> writes:
Hi,

I've been chasing a bug for a few days and finally have it narrowed down
to the following example. Basically a branch that should always be false
is taken anyway.

The printf line below should never be executed, but it is if compiled
under linux with "dmd -release -O -inline badbranch.d".

I first started chasing this while using 1.043 but have since upgraded
to 1.052 and still see it. Not surprisingly I also see it with phobos or
tango. Unfortunately my assembly reading skills are poor enough that I
can't quite tell what is going on by looking at obj2asm output once the
optimizer is done with it.

Janzert

badbranch.d:
extern(C) int printf(char*, ...);

struct Container
{
    ulong[2] bits = [0UL, 1];
}

int called(ulong value)
{
    value = value * 3;
    return value;
}

int test(Container* c, int[] shift)
{
    int count = 0;
    if (c.bits[0])
        count = 1;
    count |= called(c.bits[1]) << shift[0];
    // This is always false, but is taken anyway.
    if (c.bits[0])
        printf("Impossible output %lld\n", c.bits[0]);

    return count;
}

int main(char[][] args)
{
    int[] shift = [0];
    Container c;
    return test(&c, shift);
}
Nov 29 2009
parent reply =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= <pelle.mansson gmail.com> writes:
Janzert wrote:
 Hi,
 
 I've been chasing a bug for a few days and finally have it narrowed down
 to the following example. Basically a branch that should always be false
 is taken anyway.
 
 The printf line below should never be executed, but it is if compiled
 under linux with "dmd -release -O -inline badbranch.d".
 
 I first started chasing this while using 1.043 but have since upgraded
 to 1.052 and still see it. Not surprisingly I also see it with phobos or
 tango. Unfortunately my assembly reading skills are poor enough that I
 can't quite tell what is going on by looking at obj2asm output once the
 optimizer is done with it.
 
 Janzert
 
 badbranch.d:
 extern(C) int printf(char*, ...);
 
 struct Container
 {
     ulong[2] bits = [0UL, 1];
 }
 
 int called(ulong value)
 {
     value = value * 3;
     return value;
 }
 
 int test(Container* c, int[] shift)
 {
     int count = 0;
     if (c.bits[0])
         count = 1;
     count |= called(c.bits[1]) << shift[0];
     // This is always false, but is taken anyway.
     if (c.bits[0])
         printf("Impossible output %lld\n", c.bits[0]);
 
     return count;
 }
 
 int main(char[][] args)
 {
     int[] shift = [0];
     Container c;
     return test(&c, shift);
 }

Nov 29 2009
parent Janzert <janzert janzert.com> writes:
Pelle MÃ¥nsson wrote:
 I just tried it (in 2.034), and indeed, you should bugzilla it!

Ok, it's not just me then. :) Submitted, Bug 3558 http://d.puremagic.com/issues/show_bug.cgi?id=3558 Janzert
Nov 29 2009