Re: [Evolution-hackers] gcc 4.4 may be causing a number of bugs in Evolution



On Tue, 2010-02-02 at 11:05 -0500, Jeffrey Stedfast wrote:
> Paul Smith wrote:
> > On Mon, 2010-02-01 at 11:52 -0500, Jeffrey Stedfast wrote:
> >   
> >> This weekend I discovered a particularly nasty bug in gcc 4.4 where gcc
> >> would mistakenly optimize out important sections of code
> >> when it encountered a particular trick used in a ton of places inside
> >> Evolution (EDList and pretty much everywhere custom single-linked lists
> >> are used inside at least Camel and likely other places as well).
> >>
> >> A temporary solution is to pass the -fno-strict-aliasing argument to gcc.
> >>
> >> Unfortunately, the gcc developers claim that this is not a bug:
> >> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42907
> >
> > It is not a bug in GCC: GCC will compile a program that conforms to the
> > C standard 100% correctly.  Evolution is relying on behavior that is
> > left as undefined by the standard.  Optimizations often cause undefined
> > code to behave incorrectly, defined as "contrary to the author's
> > intent", where non-optimized versions of the code "work".  That doesn't
> > mean that the compiler has a bug.
> 
> s/C standard/C99 standard/

Well, if you try adding -std=c89 to your compiles and GCC still uses
this optimization, I guess I would agree that's a bug :-).

> In C89, a type-cast was a type-cast and had well understood and defined
> behavior. And in C89, aliasing was legal and widely used.

Aliasing is still legal in C99, of course: it would be a completely
different language if it weren't legal.  However, there are restrictions
on how it can be used (and result in defined behavior) that weren't
present before, that's true.

> So while it might not /technically/ be a bug in gcc now that it's
> focusing on c99, it can be argued it's a bug since it broke previous
> behavior.

Well, new optimizations OFTEN break previous behavior, if that behavior
took advantage of aspects of the language that weren't defined.  I'm not
sure that means we should never attempt any new optimizations.

> It can also easily be argued that, in the case of "undefined
> behavior", a compiler should default to doing what the other (and/or
> older versions of the same) compilers do. In this case, other
> compilers (and older versions of gcc) handle aliasing the same, but
> the new gcc 4.4 behavior changed.

Sure, all things being equal that's obviously the right answer.  The
problem comes when there are actually very good reasons to change the
behavior.  C is actually surprisingly difficult to optimize and one of
the big reasons this is so is C's aliasing requirements.  You have to
forgo all kinds of useful optimizations if you have to treat almost
every pointer as if it could possibly alias almost every other pointer
(if any two pointers might point to the same memory).  This leads to
very inefficient load/store behaviors, severe restrictions on the types
of code hoisting you can do, etc. etc.  This hurts especially on
register-starved architectures like the x86.

The aliasing rules introduced in C99 are not that strong (compared to
other languages), but nevertheless they allow a whole new class of
optimization opportunities that otherwise would not exist.  For some
code, the difference in the quality of the assembly produced can be
stark.

I'm pretty confident the GCC developers didn't add this optimization
just to screw over developers for the sake of the letter of the
standard.  They genuinely feel that the advantages outweigh the
drawbacks, and they added the -fno-strict-alias flag so that people who
disagree have a solution as well.

It may have been better to leave it off in -O2 and have people turn it
on if they wanted it, rather than vice versa; I don't know.  That's why
I say it's really a QOI issue.

> Hence why I call it a bug ;-)

Potayto, potahto! :-)

Anyway, I agree with you that if Evo makes use of this type of aliasing
then we should definitely add that flag to the default makefile flags.
Configure can check for it and use it if present.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]