https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64345
--- Comment #2 from Oleg Endo <olegendo at gcc dot gnu.org> --- A recent change in the middle end has triggered this: FAIL: gcc.target/sh/pr54236-1.c scan-assembler-times negc 2 The test int test_07 (int *vec) { /* Must not see a 'sett' or 'addc' here. This is a case where combine tries to produce 'a + (0 - b) + 1' out of 'a - b + 1'. On non-SH2A there is a 'tst + negc', on SH2A a 'bld + movt'. */ int z = vec[0]; int vi = vec[1]; int zi = vec[2]; if (zi != 0 && z < -1) vi -= (((vi >> 7) & 0x01) << 1) - 1; return vi; } fails to produce the expected tst + negc sequence. A reduced case is: int test (int vi) { return vi - (((vi >> 6) & 0x01) << 1); } -m2a -O2 (gcc 5): bld #6,r4 movt r0 rts add r0,r0 trunk: mov #-5,r1 mov r4,r0 shld r1,r0 rts and #2,r0 -m4 -O2 (gcc 5): mov r4,r0 tst #64,r0 mov #-1,r0 negc r0,r0 rts add r0,r0 trunk: mov #-5,r1 mov r4,r0 shld r1,r0 rts and #2,r0 For the more complex expression int test (int vi) { return vi - (((vi >> 6) & 0x01) << 1) - 1; } -m4 -O2 (gcc 5): mov r4,r0 mov #-1,r1 tst #64,r0 negc r1,r1 add r1,r1 rts subc r1,r0 trunk: mov #-5,r1 mov r4,r0 shld r1,r0 sett and #2,r0 subc r0,r4 rts mov r4,r0 It seems the zero_extract patterns are not used for this anymore. Instead combine is looking for something like (set (reg:SI 168 [ D.1649 ]) (and:SI (lshiftrt:SI (reg:SI 4 r4 [ vi ]) (const_int 5 [0x5])) (const_int 2 [0x2]))) This pattern should be added as a zero_extract variant.