https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65164
Bug ID: 65164 Summary: [5 Regression][SH] missed subc in integer sign function Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: olegendo at gcc dot gnu.org Target: sh*-*-* These are integer sign functions taken from a book. For some of them the code got worse after the introduction of the treg_set_expr stuff. int signfunc_00 (int x) { return (x >> 31) | ((unsigned int)(-x) >> 31); } int signfunc_01 (int x) { return -((unsigned int)x >> 31) | ((unsigned int)(-x) >> 31); } int signfunc_02 (int x) { return (x > 0) - (x < 0); } 4.9: cmp/pl r4 movt r0 shll r4 movt r4 rts sub r4,r0 trunk: mov r4,r1 shll r1 movt r1 cmp/pl r4 movt r0 rts sub r1,r0 int signfunc_03 (int x) { return (x >= 0) - (x <= 0); } 4.9: cmp/pz r4 mov #0,r1 movt r0 cmp/ge r4,r1 rts subc r1,r0 trunk: mov #0,r1 cmp/ge r4,r1 movt r1 cmp/pz r4 movt r0 rts sub r1,r0 It seems that this requires a pattern like (set (match_operand:SI 0 "arith_reg_dest") (minus:SI (match_operand 1 "treg_set_expr") (match_operand 2 "treg_set_expr"))) For signfunc_02, combine is looking for the pattern: Failed to match this instruction: (set (reg:SI 169 [ D.1518 ]) (minus:SI (gt:SI (reg/v:SI 168 [ x ]) (const_int 0 [0])) (lshiftrt:SI (reg/v:SI 168 [ x ]) (const_int 31 [0x1f])))) For signfunc_03, combine is looking for the pattern: (set (reg:SI 169 [ D.1522 ]) (minus:SI (ge:SI (reg:SI 4 r4 [ x ]) (const_int 0 [0])) (le:SI (reg:SI 4 r4 [ x ]) (const_int 0 [0])))) On SH, it seems that the insn sequence cmp/pz r4 mov #0,r1 movt r0 cmp/ge r4,r1 subc r1,r0 is the best to realize an integer sign function. So actually all the functions above should be converted into the same sequence.