This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][SH] Check for 0 length with inlined strnlen builtin
- From: Christian Bruel <christian dot bruel at st dot com>
- To: Kaz Kojima <kkojima at rr dot iij4u dot or dot jp>, Oleg Endo <oleg dot endo at t-online dot de>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 6 Jan 2015 10:28:48 +0100
- Subject: [PATCH][SH] Check for 0 length with inlined strnlen builtin
- Authentication-results: sourceware.org; auth=none
Hello,
We should not enter the first iteration when length is 0. Testcase
attached. Difficult to reduce because register allocation generated
accidentally the correct return value.
testsuite OK
OK for 4.9 and trunk ?
Christian
2015-01-08 Christian Bruel <christian.bruel@st.com>
PR target/64507
* config/sh/sh-mem.cc (sh_expand_cmpnstr): Check 0 length.
2015-01-08 Christian Bruel <christian.bruel@st.com>
PR target/64507
* gcc.target/sh/pr64507.c: New test.
Index: gcc/config/sh/sh-mem.cc
===================================================================
--- gcc/config/sh/sh-mem.cc (revision 219182)
+++ gcc/config/sh/sh-mem.cc (working copy)
@@ -1,5 +1,5 @@
/* Helper routines for memory move and comparison insns.
- Copyright (C) 2013-2014 Free Software Foundation, Inc.
+ Copyright (C) 2013-2015 Free Software Foundation, Inc.
This file is part of GCC.
@@ -421,6 +421,7 @@
/* end loop. Reached max iterations. */
if (sbytes == 0)
{
+ emit_insn (gen_subsi3 (operands[0], tmp1, tmp2));
jump = emit_jump_insn (gen_jump_compact (L_return));
emit_barrier_after (jump);
}
@@ -496,6 +497,13 @@
jump = emit_jump_insn (gen_jump_compact( L_end_loop_byte));
emit_barrier_after (jump);
}
+ else
+ {
+ emit_insn (gen_tstsi_t (len, len));
+ emit_move_insn (operands[0], const0_rtx);
+ jump = emit_jump_insn (gen_branch_true (L_return));
+ add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+ }
addr1 = adjust_automodify_address (addr1, QImode, s1_addr, 0);
addr2 = adjust_automodify_address (addr2, QImode, s2_addr, 0);
@@ -536,10 +544,10 @@
emit_insn (gen_zero_extendqisi2 (tmp2, gen_lowpart (QImode, tmp2)));
emit_insn (gen_zero_extendqisi2 (tmp1, gen_lowpart (QImode, tmp1)));
- emit_label (L_return);
-
emit_insn (gen_subsi3 (operands[0], tmp1, tmp2));
+ emit_label (L_return);
+
return true;
}
Index: gcc/testsuite/gcc.target/sh/pr64507.c
===================================================================
--- gcc/testsuite/gcc.target/sh/pr64507.c (revision 0)
+++ gcc/testsuite/gcc.target/sh/pr64507.c (working copy)
@@ -0,0 +1,25 @@
+/* Check that the __builtin_strnlen returns 0 with with
+ non-constant 0 length. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern int snprintf(char *, int, const char *, ...);
+extern void abort (void);
+
+int main()
+ {
+ int i;
+ int cmp = 0;
+ char buffer[1024];
+ const char* s = "the string";
+
+ snprintf(buffer, 4, "%s", s);
+
+ for (i = 1; i < 4; i++)
+ cmp += __builtin_strncmp(buffer, s, i - 1);
+
+ if (cmp)
+ abort();
+
+ return 0;
+}