https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65250
Bug ID: 65250 Summary: [SH] Improve comparisons followed by a negated cstore 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*-*-* The following example bool test (int value) { switch(value) { case 0: case 1: case 2: return true; default: return false; } } with -O2 -m4 compiles to: mov #2,r1 cmp/hi r1,r4 mov #-1,r0 rts negc r0,r0 On SH4 there is no movrt, so it's better to do that as: mov #2,r1 cmp/hs r4,r2 rts movt r0 ..which is just inverting the comparison. Combine tries the following pattern: Failed to match this instruction: (parallel [ (set (reg:SI 168) (leu:SI (reg:SI 4 r4 [ value ]) (const_int 2 [0x2]))) (set (reg:SI 147 t) (const_int 1 [0x1])) (use (reg:SI 169)) ]) ..which is a combination of the inverted comparison and the expanded movrt (via negc), which always sets T = 1. A treg_set_expr pattern like the following could be added: (define_insn_and_split "*" [(set (match_operand:SI 0 "arith_reg_dest") (match_operand 1 "treg_set_expr_not_const01")) (set (reg:SI T_REG) (const_int 1)) (use (match_operand:SI 2 "arith_reg_operand"))] ...) which would then split out the comparison insn and a trailing sett. If the sett is a dead store it will (should) get eliminated afterwards. However, before that, the initial comparison and cstore expansion should be investigated.