As mentioned in the PR, it should be valid to use strncmp instead of memcmp
because first argument of a strstr can be shorter than a second (known) 
argument.

Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.

Ready to be installed?
Martin
>From 4a9dcb24d82ce1793a281710ce1ddab59f9dd7a8 Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Mon, 23 Jan 2017 13:18:37 +0100
Subject: [PATCH] Fix strstr folding (PR tree-optimization/79196).

gcc/ChangeLog:

2017-01-23  Martin Liska  <mli...@suse.cz>

	* tree-ssa-strlen.c (fold_strstr_to_memcmp): Rename
	to fold_strstr_to_strncmp and fold the pattern to strncmp
	instead of memcmp.
	(strlen_optimize_stmt): Call the renamed function.

gcc/testsuite/ChangeLog:

2017-01-23  Martin Liska  <mli...@suse.cz>

	* gcc.dg/asan/pr79196.c: New test.
	* gcc.dg/strlenopt-30.c: Update scanned pattern.
---
 gcc/testsuite/gcc.dg/asan/pr79196.c | 17 +++++++++++++++++
 gcc/testsuite/gcc.dg/strlenopt-30.c |  2 +-
 gcc/tree-ssa-strlen.c               | 36 ++++++++++++++++++------------------
 3 files changed, 36 insertions(+), 19 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/asan/pr79196.c

diff --git a/gcc/testsuite/gcc.dg/asan/pr79196.c b/gcc/testsuite/gcc.dg/asan/pr79196.c
new file mode 100644
index 00000000000..66a31b90f30
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/pr79196.c
@@ -0,0 +1,17 @@
+// PR tree-optimization/79196
+// { dg-do run }
+
+int
+__attribute__((noinline))
+test(char *a)
+{
+  if (__builtin_strstr (a, "DROP CONVERSION") == a)
+    return 1;
+
+  return 0;
+}
+
+int main(int argc, char **argv)
+{
+  return test ("x");
+}
diff --git a/gcc/testsuite/gcc.dg/strlenopt-30.c b/gcc/testsuite/gcc.dg/strlenopt-30.c
index 089b3a2341d..a85df686ce2 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-30.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-30.c
@@ -60,4 +60,4 @@ _Bool f7(char *s)
   return (t1 == s);
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin_memcmp" 5 "strlen" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 5 "strlen" } } */
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 2e7ac2c7786..141115ed12b 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -2225,10 +2225,10 @@ handle_char_store (gimple_stmt_iterator *gsi)
   return true;
 }
 
-/* Try to fold strstr (s, t) eq/ne s to memcmp (s, t, strlen (t)) eq/ne 0.  */
+/* Try to fold strstr (s, t) eq/ne s to strncmp (s, t, strlen (t)) eq/ne 0.  */
 
 static void
-fold_strstr_to_memcmp (tree rhs1, tree rhs2, gimple *stmt)
+fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt)
 {
   if (TREE_CODE (rhs1) != SSA_NAME
       || TREE_CODE (rhs2) != SSA_NAME)
@@ -2273,34 +2273,34 @@ fold_strstr_to_memcmp (tree rhs1, tree rhs2, gimple *stmt)
 	  if (arg1_len != NULL_TREE)
 	    {
 	      gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
-	      tree memcmp_decl = builtin_decl_explicit (BUILT_IN_MEMCMP);
-	      gcall *memcmp_call = gimple_build_call (memcmp_decl, 3,
+	      tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP);
+	      gcall *strncmp_call = gimple_build_call (strncmp_decl, 3,
 						      arg0, arg1, arg1_len);
-	      tree memcmp_lhs = make_ssa_name (integer_type_node);
-	      gimple_set_vuse (memcmp_call, gimple_vuse (call_stmt));
-	      gimple_call_set_lhs (memcmp_call, memcmp_lhs);
+	      tree strncmp_lhs = make_ssa_name (integer_type_node);
+	      gimple_set_vuse (strncmp_call, gimple_vuse (call_stmt));
+	      gimple_call_set_lhs (strncmp_call, strncmp_lhs);
 	      gsi_remove (&gsi, true);
-	      gsi_insert_before (&gsi, memcmp_call, GSI_SAME_STMT);
-	      tree zero = build_zero_cst (TREE_TYPE (memcmp_lhs));
+	      gsi_insert_before (&gsi, strncmp_call, GSI_SAME_STMT);
+	      tree zero = build_zero_cst (TREE_TYPE (strncmp_lhs));
 
 	      if (is_gimple_assign (stmt))
 		{
 		  if (gimple_assign_rhs_code (stmt) == COND_EXPR)
 		    {
 		      tree cond = gimple_assign_rhs1 (stmt);
-		      TREE_OPERAND (cond, 0) = memcmp_lhs;
+		      TREE_OPERAND (cond, 0) = strncmp_lhs;
 		      TREE_OPERAND (cond, 1) = zero;
 		    }
 		  else
 		    {
-		      gimple_assign_set_rhs1 (stmt, memcmp_lhs);
+		      gimple_assign_set_rhs1 (stmt, strncmp_lhs);
 		      gimple_assign_set_rhs2 (stmt, zero);
 		    }
 		}
 	      else
 		{
 		  gcond *cond = as_a<gcond *> (stmt);
-		  gimple_cond_set_lhs (cond, memcmp_lhs);
+		  gimple_cond_set_lhs (cond, strncmp_lhs);
 		  gimple_cond_set_rhs (cond, zero);
 		}
 	      update_stmt (stmt);
@@ -2398,12 +2398,12 @@ strlen_optimize_stmt (gimple_stmt_iterator *gsi)
 	    enum tree_code cond_code = TREE_CODE (cond);
 
 	    if (cond_code == EQ_EXPR || cond_code == NE_EXPR)
-	      fold_strstr_to_memcmp (TREE_OPERAND (cond, 0),
-				     TREE_OPERAND (cond, 1), stmt);
+	      fold_strstr_to_strncmp (TREE_OPERAND (cond, 0),
+				      TREE_OPERAND (cond, 1), stmt);
 	  }
 	else if (code == EQ_EXPR || code == NE_EXPR)
-	  fold_strstr_to_memcmp (gimple_assign_rhs1 (stmt),
-				 gimple_assign_rhs2 (stmt), stmt);
+	  fold_strstr_to_strncmp (gimple_assign_rhs1 (stmt),
+				  gimple_assign_rhs2 (stmt), stmt);
       }
     else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
 	{
@@ -2423,8 +2423,8 @@ strlen_optimize_stmt (gimple_stmt_iterator *gsi)
     {
       enum tree_code code = gimple_cond_code (cond);
       if (code == EQ_EXPR || code == NE_EXPR)
-	fold_strstr_to_memcmp (gimple_cond_lhs (stmt),
-			       gimple_cond_rhs (stmt), stmt);
+	fold_strstr_to_strncmp (gimple_cond_lhs (stmt),
+				gimple_cond_rhs (stmt), stmt);
     }
 
   if (gimple_vdef (stmt))
-- 
2.11.0

Reply via email to