https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63783
--- Comment #12 from Michael Karcher <gcc-bugzilla at mkarcher dot dialup.fu-berlin.de> --- Further digging into this showed that there actually is a pass that would merge the two "tst r1,r1" instructions - the jump2 pass in cfgclenup.c. The optimization is called "crossjumping" in gcc, also known as tail merging. For some reason[1], gcc is reluctant to perform crossjumping on small common parts. In this case, the common part is just one instruction, and the parameter min-crossjump-insns is five by default unless optimizing for size. With "-fparam-min-crossjump-insns=1" or "-Os", my first patch removing all the special-casing of zero compares produces the same result as the patch fixing the logical negations. In the current situation, I see no advantage of not cross-jumping in this case, so the minimally invasive solution is definitely the second patch to fix logical negation, but still it somehow feels ugly to me to have a limited reimplementation of crossjumping in the sh-treg-combine pass. Replacing stuff of that pass by improving other optimizations is IMHO beyond the scope of this bug, though. [1] These are actually performance reasons: https://gcc.gnu.org/ml/gcc-patches/2004-07/msg00495.html