https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91540
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> --- On the trunk we get: _5 = cond1_2(D) & cond2_3(D); _6 = (int) _5; _7 = 43 - _6; If we replace the minus with xor, we would get what clang gives. I think we do this with or though. I looked into a slightly different case: int Test(bool cond1, bool cond2) { if (cond1) { if (cond2) { return 43; } } return 42; } int Test1(bool cond1, bool cond2) { int t = 0; if (cond1) { if (cond2) { t = 1; } } return 42 + t; } int Test0(bool cond1, bool cond2) { int t = 0; if (cond1) { if (cond2) { t = 1; } } return 42 + t; } int Test2(bool cond1, bool cond2) { int t = cond1 & cond2; return 42 + t; } int Test3(bool cond1, bool cond2) { int t = (cond1 & cond2); return 42 | t; } ---- CUT ---- GCC produces the decent code for all of the Tests here while clang produces produces decent for Test2 and Test3.