http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53976
--- Comment #3 from Oleg Endo <olegendo at gcc dot gnu.org> --- (In reply to Oleg Endo from comment #2) > Interestingly, the following function shows some improved behavior (notice > the removed volatile mem store): > > int test_2_1 (int* a, int b, int c) > { > a[1] = b != 0; > > if (b == 0) > a[10] = c; > > return b == 0; > } > > -O2 -m2a: > tst r5,r5 > movrt r1 > mov.l r1,@(4,r4) > bf .L4 > mov.l r6,@(40,r4) > .L4: > rts > movt r0 > > > This is already minimal. > However, for non-SH2A it's still the same: > tst r5,r5 > mov #-1,r1 > negc r1,r1 > tst r5,r5 > bf/s .L4 > mov.l r1,@(4,r4) > mov.l r6,@(40,r4) > tst r5,r5 > .L4: > rts > movt r0 One of the problems in this case is that negc clobbers the T bit. Another alternative movt r0 xor #1,r0 should be selected here. This could be done by looking at the insns around the negc-movrt and check whether some insn after negc-movrt sets the T bit in the same way as it was set before the negc-movrt. In this case not clobbering the T bit would eliminate the redundant test. However, if this pattern occurs in a loop or pressure on R0 is high, using negc and the redundant test is probably going to be better.