Compiler bugs where the compiler generates bad code are definitely real (I've found two), but are very rare (I've found two ever).
95% of the time when I've had a bug that only shows up with specific build settings, it's because I used an uninitialized variable. Something like this:
int myVariable;
if(a < b){
myVariable = 6;
} else if(a < c){
myVariable = 12;
}
If a is greater than both b and c, myVariable will just have whatever old leftover value happened to be sitting in the register or stack location given to myVariable. It might be 0, it might be -12000, and it's almost guaranteed to change based on compiler settings as that causes registers to get used for different things. It's harder to notice this happening when myVariable is a float as half of the random sets of bits when used as a floating point number will be between 1 and -1. When this happens to pointers it can cause other confusing bugs.
As CJ said, turn on more warnings and also run the static analyzer. They might be able to find your bug for you.
Also, after years of inflicting bugs on myself caused by this. I decided never ever declare a variable without defining it! There isn't a good reason to do it unless you are supporting 20 year old compilers.