re PR target/64507 (SH inlined builtin strncmp doesn't return 0 for 0 length)
authorChristian Bruel <christian.bruel@st.com>
Tue, 6 Jan 2015 11:59:09 +0000 (12:59 +0100)
committerChristian Bruel <chrbr@gcc.gnu.org>
Tue, 6 Jan 2015 11:59:09 +0000 (12:59 +0100)
PR target/64507
* config/sh/sh-mem.cc (sh_expand_cmpnstr): Check 0 length.

From-SVN: r219257

gcc/ChangeLog
gcc/config/sh/sh-mem.cc
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/pr64507.c [new file with mode: 0644]

index 4b3d6ca..7423db3 100644 (file)
@@ -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
index 4252500..3d61c2a 100644 (file)
@@ -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;
 }
 
index 8cba5d9..63eeda9 100644 (file)
@@ -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 (file)
index 0000000..d3d9384
--- /dev/null
@@ -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;
+}