GCC 4.8 made me chose Clang

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

GCC 4.8 made me chose Clang

Post by lucasart »

I made a very stupid mistake today: updated my Ubuntu from 13.04 to 13.10. One of the reasons I did that, was to upgrade to GCC 4.8. So there I was, all excited to compile DiscoCheck with GCC 4.8... How stupid I was!

I compiled the exact same code with:
* GCC 4.7.3, with or without flto (link time optimization): All good, verified by total node count on a depth=12 run of 20 positions.
* GCC 4.8.1, with of without flto: both compiles are wrong. Neither have the correct node count, and both versions don't even have the same node counts (ie. they are both broken in different ways).
* not only the GCC 4.8 compiles are all broken, but they are slower than the ones of GCC 4.7.

So I have now a compiler that SILENTLY breaks my code. This is totally unacceptable. And there is no way to find out where the problem comes from, so I'm completely screwed as far as GCC is concerned. Perhaps a git bissect, but I really don't have the patience for that. The fact that GCC now makes broken and slower compiles, is enough to put me off it for the foreseeable future. Writing a chess program is a complicated enough task already, if we can't even rely on the compiler to produce correct code, we're doomed!

The good news however is Clang:
* Clang managed to produce a correct compile (correct node count).

But:
* clang does not accept GNU extensions (std=c++11 but not std=gnu++11). That means I need to throw away variable length arrays. They were so nice for triangular PV array on the stack, without them, I will now have to rely on an ugle global structure.
* clang does not accept flto (link time optimization). This was a great source of performance in GCC 4.7.3 when compiling my code, as I hate to have to inline everything: I prefer to rely on flto to do it for me.
* the Clang compile is 10% slower than GCC 4.7 !

Anyway, I guess I'll have to bite the bullet and only use Clang from now on, until an acceptable version of GCC resurfaces. I will miss VLA though :cry:

Has anyone experienced similar issues with GCC 4.8 ?
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
Michel
Posts: 2272
Joined: Mon Sep 29, 2008 1:50 am

Re: GCC 4.8 made me chose Clang

Post by Michel »

Perhaps a git bissect, but I really don't have the patience for that.
Why not? git bisect is very fast.

It may well be that this whole thing hides a bug in your code. Compiler errors are extremely rare.
User avatar
trojanfoe
Posts: 65
Joined: Sun Jul 31, 2011 11:57 am
Location: Waterlooville, Hampshire, UK

Re: GCC 4.8 made me chose Clang

Post by trojanfoe »

lucasart wrote: * clang does not accept GNU extensions (std=c++11 but not std=gnu++11). That means I need to throw away variable length arrays. They were so nice for triangular PV array on the stack, without them, I will now have to rely on an ugle global structure.
That isn't true; I've just compiled this, without complaint, using Apple clang 5.0 (I used -std=c++11):

Code: Select all

#include <cstdio>
#include <cstring>

FILE * concat_fopen &#40;char *s1, char *s2, char *mode&#41;
&#123;
   char str&#91;strlen &#40;s1&#41; + strlen &#40;s2&#41; + 1&#93;;
   strcpy &#40;str, s1&#41;;
   strcat &#40;str, s2&#41;;
   return fopen &#40;str, mode&#41;;
&#125;
lucasart wrote:
* clang does not accept flto (link time optimization). This was a great source of performance in GCC 4.7.3 when compiling my code, as I hate to have to inline everything: I prefer to rely on flto to do it for me.
Apple clang 5.0 does support LTO and as that is based on LLVM 3.3 SVN, I'm surprised it's not in the non-Apple version.
lucasart wrote:
* the Clang compile is 10% slower than GCC 4.7 !
No idea about that; I've never compared.

I would strongly suspect that your code is non-portable and slightly broken if it's suddenly started breaking with gcc 4.8. You mention the use of variable length array, which is a feature I would never consider using if I wanted to create portable code (std::vector is the portable variable-length array).

You might be better off getting it to work with gcc 4.8 and thus having a better code base, rather than assuming these faults are with the compiler rather than your code.
User avatar
Codesquid
Posts: 138
Joined: Tue Aug 23, 2011 10:25 pm
Location: Germany

Re: GCC 4.8 made me chose Clang

Post by Codesquid »

lucasart wrote:GCC 4.8.1, with of without flto: both compiles are wrong. Neither have the correct node count, and both versions don't even have the same node counts (ie. they are both broken in different ways).
So I have now a compiler that SILENTLY breaks my code.
What makes you sure it's a problem with GCC and not a very subtle bug in your code, e.g. a reliance on undefined or implementation specific behavior?
And there is no way to find out where the problem comes from, so I'm completely screwed as far as GCC is concerned.
There is: Dump the search trees, compare the output with the two compiles. Find the difference and iteratively narrow it down. Eventually you'll find a line of code that behaves differently.
nanos gigantium humeris insidentes
geko
Posts: 36
Joined: Fri Sep 06, 2013 11:20 am
Location: Italy
Full name: Giuseppe Cannella

Re: GCC 4.8 made me chose Clang

Post by geko »

hi Lucas,
Valgrind detect "Conditional jump or move depends on uninitialised value(s)"
and exit with

Code: Select all

./src/types.h&#58;107&#58; int opp_color&#40;int&#41;&#58; Assertion `color_ok&#40;color&#41;' failed.
Try to fix this error

best
Giuseppe
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: GCC 4.8 made me chose Clang

Post by lucasart »

Michel wrote:
Perhaps a git bissect, but I really don't have the patience for that.
Why not? git bisect is very fast.

It may well be that this whole thing hides a bug in your code. Compiler errors are extremely rare.
OK, I've done the git bisect, and the offending commit is as follows:
https://github.com/lucasart/chess/commi ... f37b895be5

From this commit onwards, the node counts start to diverge: GCC 4.7, GCC 4.6, and Clang produce correct compiles, but not GCC 4.8.

I've been staring at the code for this commit for a while, and I really don't see anything wrong with it. I'll try to reimplement the same thing in a different way to see what happens.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: GCC 4.8 made me chose Clang

Post by mcostalba »

lucasart wrote: I've been staring at the code for this commit for a while, and I really don't see anything wrong with it.
Remove it piece by piece until you find the offending statement.
User avatar
Codesquid
Posts: 138
Joined: Tue Aug 23, 2011 10:25 pm
Location: Germany

Re: GCC 4.8 made me chose Clang

Post by Codesquid »

lucasart wrote:OK, I've done the git bisect, and the offending commit is as follows:
https://github.com/lucasart/chess/commi ... f37b895be5

From this commit onwards, the node counts start to diverge: GCC 4.7, GCC 4.6, and Clang produce correct compiles, but not GCC 4.8.

I've been staring at the code for this commit for a while, and I really don't see anything wrong with it. I'll try to reimplement the same thing in a different way to see what happens.
Maybe this change merely triggers a problem elsewhere?
nanos gigantium humeris insidentes
mar
Posts: 2554
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: GCC 4.8 made me chose Clang

Post by mar »

Hmm, I just tried to compile my engine with gcc 4.8 and it's not broken. It even seems faster...
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: GCC 4.8 made me chose Clang

Post by lucasart »

mcostalba wrote:
lucasart wrote: I've been staring at the code for this commit for a while, and I really don't see anything wrong with it.
Remove it piece by piece until you find the offending statement.
Ah yes, why didn't I think of that? Thanks for the tip.

So basically, I make a copy of my source tree before the commit, and start rewriting this commit, bit by bit, until it breaks (GCC 4.8 and Clang produce different bench signature).
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.