diff options
author | Christian Bruel <christian.bruel@st.com> | 2015-01-06 12:59:09 +0100 |
---|---|---|
committer | Christian Bruel <chrbr@gcc.gnu.org> | 2015-01-06 12:59:09 +0100 |
commit | 6a6b03ba34e7a0d84f7a92ba378ac602c5759209 (patch) | |
tree | c3bd3725766aa1b76d30e5723876482626311803 | |
parent | e4a5735015888eaea5ec6964a3d879a1e61ea75a (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/sh/sh-mem.cc | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr64507.c | 25 |
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; +} |