This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/53987] New: [SH] Unnecessary zero-extension before cmp/eq
- From: "olegendo at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 16 Jul 2012 23:49:58 +0000
- Subject: [Bug target/53987] New: [SH] Unnecessary zero-extension before cmp/eq
- Auto-submitted: auto-generated
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...