There’s an interesting post here about heisenbugs and compiler optimizers. I’ve found two compiler bugs in my time. One was related to the optimizer, although it wasn’t due to the compiler generating incorrect code. Well, not quite, anyway.
In one case, a commercial embedded cross-compiler, the optimized code the compiler was generating was logically correct code. The problem was that it was incorrect in context. I was accessing machine registers that had to be accessed with 16-bit operations – if you tried to access half of the register with a byte operation, the processor would overwrite the other half of the register with random data. Naturally, the compiler was optimizing 16-bit accesses that only dealt with one byte of the register to 8-bit operations, because that was the better thing to do when dealing with normal memory. The compiler could produce code for several related variants of the processor in question, and I’m not sure that the register restrictions in question applied to other processors at the time.
I reported what was happening to the vendor, and they changed it in the next release of the compiler, but I couldn’t wait for the fix, and had to use assembly language to produce my access routines.
The other instance involved an IDE that used GCC as a cross-compiler. Our code wasn’t working, and initial investigation showed results that made no sense – one passed parameter was getting the value meant for the other, and another was getting a garbage value. Closer examination of the generated code showed that the stack frame for the function call in question was being built incorrectly, which beggared belief. Why was it only happening on this one call, rather than on all of them? If it were a general bug, there would be virtually no programs would be compiled correctly – what was it about this one call? Further investigation showed that the vendor had grabbed a version of GCC that had been pulled from distribution after about a day because of a significant bug involving calling across languages – calling C routines from C worked, as did calling C++ routines from C++, but calling one from the other didn’t … the specific bug that we were seeing, although we didn’t realize that it was due to a cross-language call until we saw the release notes on the GNU website. We were lucky that the vendor provided the capability to tell the IDE how to access other tools, or we’d have been dead in the water on our project.
It’s not often that you run into compiler bugs, unless you’re the one maintaining the compiler (in which case you probably see them more often than you’d care to). Most times, the problem is in your code, not the compiler. However, you can’t rule it out, particularly if you’re doing things that stress the compiler’s capabilities, or use features that most people don’t require. Some people make a point of looking for compiler bugs, which is nice of them. It’s not what I’d care to do on a daily basis, although I have designed and written test code to verify that language features work as intended.