Commit f700c7ca by Oleg Endo

re PR target/67675 ([SH] Improve __builtin_strcmp alignment test)

gcc/
	PR target/67675
	* config/sh/sh-mem.cc (sh_expand_cmpstr): Check alignment of addr1 and
	addr2 individually.  Don't emit logical or insn if one is known to
	be aligned approriately.
	(sh_expand_cmpnstr): Likewise.

gcc/testsuite/
	PR target/67675
	* gcc.target/sh/pr67675.c: New.

From-SVN: r228118
parent e6cf8d65
2015-09-25 Oleg Endo <olegendo@gcc.gnu.org>
PR target/67675
* config/sh/sh-mem.cc (sh_expand_cmpstr): Check alignment of addr1 and
addr2 individually. Don't emit logical or insn if one is known to
be aligned approriately.
(sh_expand_cmpnstr): Likewise.
2015-09-25 Richard Sandiford <richard.sandiford@arm.com>
* config/aarch64/aarch64-builtins.c (aarch64_expand_builtin): Force
......@@ -224,17 +224,28 @@ sh_expand_cmpstr (rtx *operands)
rtx_code_label *L_loop_long = gen_label_rtx ();
rtx_code_label *L_end_loop_long = gen_label_rtx ();
int align = INTVAL (operands[3]);
emit_move_insn (tmp0, const0_rtx);
const unsigned int addr1_alignment = MEM_ALIGN (operands[1]) / BITS_PER_UNIT;
const unsigned int addr2_alignment = MEM_ALIGN (operands[2]) / BITS_PER_UNIT;
if (align < 4)
if (addr1_alignment < 4 && addr2_alignment < 4)
{
emit_insn (gen_iorsi3 (tmp1, s1_addr, s2_addr));
emit_insn (gen_tstsi_t (tmp1, GEN_INT (3)));
jump = emit_jump_insn (gen_branch_false (L_loop_byte));
add_int_reg_note (jump, REG_BR_PROB, prob_likely);
}
else if (addr1_alignment < 4 && addr2_alignment >= 4)
{
emit_insn (gen_tstsi_t (s1_addr, GEN_INT (3)));
jump = emit_jump_insn (gen_branch_false (L_loop_byte));
add_int_reg_note (jump, REG_BR_PROB, prob_likely);
}
else if (addr1_alignment >= 4 && addr2_alignment < 4)
{
emit_insn (gen_tstsi_t (s2_addr, GEN_INT (3)));
jump = emit_jump_insn (gen_branch_false (L_loop_byte));
add_int_reg_note (jump, REG_BR_PROB, prob_likely);
}
addr1 = adjust_automodify_address (addr1, SImode, s1_addr, 0);
addr2 = adjust_automodify_address (addr2, SImode, s2_addr, 0);
......@@ -352,6 +363,9 @@ sh_expand_cmpnstr (rtx *operands)
rtx len = force_reg (SImode, operands[3]);
int constp = CONST_INT_P (operands[3]);
const unsigned int addr1_alignment = MEM_ALIGN (operands[1]) / BITS_PER_UNIT;
const unsigned int addr2_alignment = MEM_ALIGN (operands[2]) / BITS_PER_UNIT;
/* Loop on a register count. */
if (constp)
{
......@@ -362,7 +376,6 @@ sh_expand_cmpnstr (rtx *operands)
rtx_code_label *L_loop_long = gen_label_rtx ();
rtx_code_label *L_end_loop_long = gen_label_rtx ();
int align = INTVAL (operands[4]);
int bytes = INTVAL (operands[3]);
int witers = bytes / 4;
......@@ -373,13 +386,25 @@ sh_expand_cmpnstr (rtx *operands)
emit_move_insn (tmp0, const0_rtx);
if (align < 4)
if (addr1_alignment < 4 && addr2_alignment < 4)
{
emit_insn (gen_iorsi3 (tmp1, s1_addr, s2_addr));
emit_insn (gen_tstsi_t (tmp1, GEN_INT (3)));
jump = emit_jump_insn (gen_branch_false (L_loop_byte));
add_int_reg_note (jump, REG_BR_PROB, prob_likely);
}
else if (addr1_alignment < 4 && addr2_alignment >= 4)
{
emit_insn (gen_tstsi_t (s1_addr, GEN_INT (3)));
jump = emit_jump_insn (gen_branch_false (L_loop_byte));
add_int_reg_note (jump, REG_BR_PROB, prob_likely);
}
else if (addr1_alignment >= 4 && addr2_alignment < 4)
{
emit_insn (gen_tstsi_t (s2_addr, GEN_INT (3)));
jump = emit_jump_insn (gen_branch_false (L_loop_byte));
add_int_reg_note (jump, REG_BR_PROB, prob_likely);
}
/* word count. Do we have iterations ? */
emit_insn (gen_lshrsi3 (lenw, len, GEN_INT (2)));
......
2015-09-25 Oleg Endo <olegendo@gcc.gnu.org>
PR target/67675
* gcc.target/sh/pr67675.c: New.
2015-09-25 Richard Sandiford <richard.sandiford@arm.com>
* gcc.target/aarch64/fpcr_fpsr_1.c: New file.
......
/* Check that run time alignment tests are generated only for inputs of
unknown alignment. */
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-not "jmp|bsr|jsr" } } */
/* { dg-final { scan-assembler-times {tst #3,r0} 6 } } */
/* { dg-final { scan-assembler-times {or r[0-9],r[0-9]} 1 } } */
int
test_00 (const char* x, const char* y)
{
/* 1x or reg,reg, 1x tst #3,r0 */
return __builtin_strcmp (x, y);
}
int
test_01 (const char* x, const char* y)
{
/* 1x tst #3,r0 */
return __builtin_strcmp (__builtin_assume_aligned (x, 4), y);
}
int
test_02 (const char* x, const char* y)
{
/* 1x tst #3,r0 */
return __builtin_strcmp (x, __builtin_assume_aligned (y, 4));
}
int
test_03 (const char* x, const char* y)
{
return __builtin_strcmp (__builtin_assume_aligned (x, 4),
__builtin_assume_aligned (y, 4));
}
int
test_04 (const char* x, const char* y)
{
/* 1x tst #3,r0 */
return __builtin_strcmp (x, "1234567");
}
int
test_05 (const char* x, const char* y)
{
/* 1x tst #3,r0 */
return __builtin_strcmp ("1234567", y);
}
int
test_06 (const char* s1)
{
/* 1x tst #3,r0 */
return __builtin_strncmp (s1, "abcdabcd", 8);
}
int
test_07 (const char* s1)
{
return __builtin_strncmp (__builtin_assume_aligned (s1, 4), "abcdabcd", 8);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment