From 6a6b03ba34e7a0d84f7a92ba378ac602c5759209 Mon Sep 17 00:00:00 2001 From: Christian Bruel Date: Tue, 6 Jan 2015 12:59:09 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++++ gcc/config/sh/sh-mem.cc | 12 ++++++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/sh/pr64507.c | 25 +++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/sh/pr64507.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4b3d6caec03..7423db3589b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2015-01-08 Christian Bruel + + PR target/64507 + * config/sh/sh-mem.cc (sh_expand_cmpnstr): Check 0 length. + 2015-01-06 Thomas Preud'homme PR tree-optimization/63259 diff --git a/gcc/config/sh/sh-mem.cc b/gcc/config/sh/sh-mem.cc index 4252500a705..3d61c2adc81 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 8cba5d9f8d6..63eeda9cec2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-01-08 Christian Bruel + + PR target/64507 + * gcc.target/sh/pr64507.c: New test. + 2015-01-06 Arnaud Charlet * 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 00000000000..d3d93849bd3 --- /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; +} -- 2.30.2