I covered both bases. I was suggesting that the time to compile with clang is 4x LESS than gcc 4.7 for our code base. Which IMHO is a lot more important than slight optimisations of loops that don't make a difference in the end.
The end result produced by gcc in some cases is more performant (looking at profiling output), however we continue to use clang because most of our code spends a LOT more time in I/O than it does in certain tight loops that GCC would optimise, and clang produces better diagnostic output, and compiles faster thus we get feedback faster and spend less time waiting for our codebase to compile.
Ok, that wasn't clear to me, as you then went into the detail regarding the runtime performance, which seemed unrelated (like, my attempt to make it relevant made the "4x" become highly confusing, as you seemed to be arguing a tradeoff that hosay123 hadn't gone into). Fair enough.
But you're almost certainly not comparing the same set of optimizations. If you bring the optimization level of gcc down to the point that it generates code as slow as clang, are the compile times comparable?
What makes you believe that I am compiling with optimisations in one, and not with the other.
We don't pass in any optimisations at all, especially during development. We have found a couple issues in the past whereby -O3 or even -O2 would cause GCC AND/OR clang to miscompile code. So we simply dropped all optimisations.
Danger Will Robinson!!! Back when I was at Google, we were advised to tripple-check compiler warnings, manually look for undefined behavior, run valgrind, etc. if we thought we found a bug in the compiler or TCMalloc. A high percentage of claimed bugs in the compiler or TCMalloc turned out to be relying on undefined behavior.
If switching on standard optimizations is causing "miscompiled" code, especially in both GCC and Clang, it's very likely that your code has silent bugs that are revealed by optimizations. Compilers are perfectly allowed to perform very unexpected optimizations where they detect undefined behavior.
One of the gdb gurus at Google was telling me about a bug brought to him by a fellow engineer, where both branches of an if-else had logging statements in them, and the common code after the branches had a logging statement. Only the logging statement after the if-else was logging anything. It turned out that the branch condition was the result of undefined behavior and under very specific circumstances, gcc had optimized away both sides of the if-else. The optimizer had essentially decided that the bool was never true and was never false. This wasn't a compiler bug. For implementation-defined behavior, C compiler are required to do consistent and sane things. For undefined behavior, C compilers aren't required to do consistent or sane things. Essentially, undefined behavior are the corner cases that compiler writers are explicitly allowed to ignore when performing optimizations. A classic example is int i; for(i = 1; i > 0; ++i) could legally be left alone on one line and be optimized away to while(true) a few lines later, since overflow of signed integers is undefined behavior, the compiler is allowed to perform optimizations as if overflow can't happen.
We compile with -Werror, so triple checking compiler warnings isn't required, it won't even compile if there are any warnings.
At one point we were using an older version of GCC, and an older version of clang and both would miscompile different pieces of the code with optimisations turned on. A lot of things have been fixed since then. There were a few cases where the code that was written was undefined in the standard and the compiler could do as they pleased, but there were quite a few cases where that wasn't the case. The places where it was undefined we fixed, the others we never did figure out what was going on. Newer versions of GCC/clang did the right thing, so we finally upgraded, solving a whole lot of the problems.
At this point in time it just doesn't make sense for us to compile with optimisations turned on, so why risk it?
The end result produced by gcc in some cases is more performant (looking at profiling output), however we continue to use clang because most of our code spends a LOT more time in I/O than it does in certain tight loops that GCC would optimise, and clang produces better diagnostic output, and compiles faster thus we get feedback faster and spend less time waiting for our codebase to compile.