aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Bruel <christian.bruel@st.com>2015-01-06 12:59:09 +0100
committerChristian Bruel <chrbr@gcc.gnu.org>2015-01-06 12:59:09 +0100
commit6a6b03ba34e7a0d84f7a92ba378ac602c5759209 (patch)
treec3bd3725766aa1b76d30e5723876482626311803
parente4a5735015888eaea5ec6964a3d879a1e61ea75a (diff)
downloadgcc-6a6b03ba34e7a0d84f7a92ba378ac602c5759209.zip
gcc-6a6b03ba34e7a0d84f7a92ba378ac602c5759209.tar.gz
gcc-6a6b03ba34e7a0d84f7a92ba378ac602c5759209.tar.bz2
re PR target/64507 (SH inlined builtin strncmp doesn't return 0 for 0 length)
PR target/64507 * config/sh/sh-mem.cc (sh_expand_cmpnstr): Check 0 length. From-SVN: r219257
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/sh/sh-mem.cc12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/sh/pr64507.c25
4 files changed, 45 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4b3d6ca..7423db3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+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-06 Thomas Preud'homme <thomas.preudhomme@arm.com>
PR tree-optimization/63259
diff --git a/gcc/config/sh/sh-mem.cc b/gcc/config/sh/sh-mem.cc
index 4252500..3d61c2a 100644
--- a/gcc/config/sh/sh-mem.cc
+++ b/gcc/config/sh/sh-mem.cc
@@ -421,6 +421,7 @@ sh_expand_cmpnstr (rtx *operands)
/* 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 @@ sh_expand_cmpnstr (rtx *operands)
jump = emit_jump_insn (gen_jump_compact( L_end_loop_byte));
emit_barrier_after (jump);
}
+ else
+ {
+ emit_insn (gen_cmpeqsi_t (len, const0_rtx));
+ 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 @@ sh_expand_cmpnstr (rtx *operands)
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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8cba5d9..63eeda9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-01-08 Christian Bruel <christian.bruel@st.com>
+
+ PR target/64507
+ * gcc.target/sh/pr64507.c: New test.
+
2015-01-06 Arnaud Charlet <charlet@adacore.com>
* gnat.db/fixce.adb, gnat.db/specs/delta_small.ads: Kill warnings.
diff --git a/gcc/testsuite/gcc.target/sh/pr64507.c b/gcc/testsuite/gcc.target/sh/pr64507.c
new file mode 100644
index 0000000..d3d9384
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr64507.c
@@ -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;
+}