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.
===================================================================
@@ -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;
}
===================================================================
@@ -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;
+}