http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53987
Bug #: 53987 Summary: [SH] Unnecessary zero-extension before cmp/eq Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: olege...@gcc.gnu.org Target: sh*-*-* The following function: int test_00 (unsigned char* a, unsigned char* b, int c, int d) { if (*a == *b) return c; return d; } gets compiled to: mov.b @r4,r1 mov.b @r5,r2 extu.b r1,r1 extu.b r2,r2 cmp/eq r2,r1 bt .L4 mov r7,r6 .L4: rts mov r6,r0 Obviously the zero-extensions can be omitted. The following combine patterns can be used to eliminate the zero extensions Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 189550) +++ gcc/config/sh/sh.md (working copy) @@ -759,6 +759,30 @@ cmp/eq %1,%0" [(set_attr "type" "mt_group")]) +(define_insn_and_split "*cmpeqsi_t" + [(set (reg:SI T_REG) + (eq:SI (zero_extend:SI (match_operand:QI 0 "arith_reg_operand" "r")) + (match_operand:SI 1 "arith_reg_operand" "r")))] + "TARGET_SH1" +{ + gcc_unreachable (); + return "#"; +} + "&& can_create_pseudo_p ()" + [(set (match_dup 2) (zero_extend:SI (match_dup 0))) + (set (reg:SI T_REG) (eq:SI (match_dup 1) (match_dup 2)))] +{ + operands[2] = gen_reg_rtx (SImode); +}) + +(define_insn "*cmpeqsi_t" + [(set (reg:SI T_REG) + (eq:SI (sign_extend:SI (match_operand:QI 0 "arith_reg_operand" "r")) + (sign_extend:SI (match_operand:QI 1 "arith_reg_operand" "r"))))] + "TARGET_SH1" + "cmp/eq %1,%0" + [(set_attr "type" "mt_group")]) + (define_insn "cmpgtsi_t" [(set (reg:SI T_REG) (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r") A quick look at the CSiBE result-size set (-m4-single -O2 -pretend-cmove) shows a few code size decreases and one increase, where the following code sequence is generated in unrarlib.s: .L397: mov.l .L467,r3 ! 167 movsi_ie/1 mov.b @(2,r9),r0 ! 165 *movqi_load_mem_disp/1 mov.w @r9,r6 ! 169 *extendhisi2_compact_snd mov r0,r7 !<< ! 513 *movqi_reg_reg/1 mov.b r0,@(2,r3) ! 172 *movqi_store_mem_disp04/1 mov.w @(4,r9),r0 ! 514 *movhi_load_mem_disp/1 extu.b r7,r7 !<< ! 441 *zero_extendqisi2_compact mov.w r6,@r3 ! 170 *movhi/4 cmp/eq r7,r8 ! 442 cmpeqsi_t/3 This seems to be the consequence of the splitter, which changes the insn order...