I'm having a problem with code like the following on all 4.2.x versions of gcc (at least on intel and with my port):

unsigned z = 1;
unsigned *foo()
{
    return &z;
}

int main(void)
{
    z = 1;
    *foo() = 0;
    return z;
}

When optimisation is enabled, but inlining disabled (-O1 for example) the compiler appears to fail to recognise that z clobbered by *foo()=0, and produces code that returns a constant 1. The problem appears to be caused by foo being marked pure; if I move foo to another compilation unit, to problem goes away unless I mark the prototype with __attribute__((pure)). Also the problem goes away if I add a side-effect to foo. Looking at the tree dumps reveals that this problem appears in the FRE pass - although I'd guess that the problem could well originate in the earlier alias analysis pass.

This problem is fixed in 4.3. A binary search through trunk GCC led me to revision 119502 (Daniel Berlin, 2006-12-04). However, it doesn't look like it's possible to back-port this change to 4.2, because of the intervening changes to the files involved. I naively attempted to patch across the relitively simple changes to tree-ssa-alias.c in 119502, but not suprisingly that didn't help on its own.

Does anyone recognise this problem? Any help tracking down the cause of the problem would be very gratefully received - if nothing else I'll have to re-fix the problem in 4.2. However, my experience hacking the tree passes is pretty much zero :(

In the long run I can upgrade to 4.3 or 4.4. However, updating my port and re-validating it is a fair amount of work that I'm not keen to tackle immediately.


Thanks,
Ned.

--


Reply via email to