This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/53987] New: [SH] Unnecessary zero-extension before cmp/eq


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: unassigned@gcc.gnu.org
        ReportedBy: olegendo@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...


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]