On x86 architectures, when the target is -march=pentium or higher, the compiler seems to replace (x || y) by ((x | y) != 0) too soon for optimizations to apply, when x and y are integers. Testcase (compiled with "gcc -O3 -march=something"): typedef int T; void g(T); void f(T x, T y) { if (x || y) return; g(!x); } When the target is -march=i386, GCC is doing a great job and it is able to replace !x by 1 when optimizing: if (x || y) return; g(1); However, when the target is -march=pentium, the generated code is equivalent to: if ((x | y) != 0) return; /* this is a bit better than previously */ g(x != 0); /* this is a lot worse */ If int is replaced by _Bool in the typedef, then the code is correctly optimized: !x is replaced by 1 whatever the target. So the misoptimization is triggered only when boolean values are passed through integers (quite a common situation in C) and when some specific x86 architectures are targeted. $ gcc-snapshot -v Using built-in specs. Target: i686-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,java,f95,objc,obj-c++,treelang --prefix=/usr/lib/gcc-snapshot --enable-shared --with-system-zlib --disable-nls --enable-__cxa_atexit --enable-libstdcxx-allocator=mt --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/gcc-snapshot/jre --enable-mpfr --disable-werror i686-linux-gnu Thread model: posix gcc version 4.1.0 20050904 (experimental)
Confirmed, a known issue. Related to PR 15911. and Really is caused by not doing PR 15357 late in the game.
In both cases we now get a call to g(1) due to the fix for 15911. So, fixed.