Hi,

this is the first patch for PR78809 (totally 3 patches)

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78809
inline strcmp with small constant strings

The design doc is at:
https://www.mail-archive.com/gcc@gcc.gnu.org/msg83822.html

this patch is for the first part of change:

A. for strncmp (s1, s2, n)
     if one of "s1" or "s2" is a constant string, "n" is a constant, and
larger than the length of the constant string:
     change strncmp (s1, s2, n) to strcmp (s1, s2);

adding test case strcmpopt_1.c into gcc.dg

bootstraped and tested on both X86 and aarch64. no regression.

Okay for commit?

thanks.

Qing

======================

gcc/ChangeLog

2017-11-15  Qing Zhao  <qing.z...@oracle.com>

       * gimple-fold.c (gimple_fold_builtin_string_compare): Add handling
       of replacing call to strncmp with corresponding call to strcmp when
       meeting conditions.

gcc/testsuite/ChangeLog

2017-11-15  Qing Zhao  <qing.z...@oracle.com>

       PR middle-end/78809
       * gcc.dg/strcmpopt_1.c: New test.

---
 gcc/gimple-fold.c                  | 15 +++++++++++++++
 gcc/testsuite/gcc.dg/strcmpopt_1.c | 28 ++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/strcmpopt_1.c

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index adb6f3b..1ed6383 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -2258,6 +2258,21 @@ gimple_fold_builtin_string_compare (gimple_stmt_iterator 
*gsi)
       return true;
     }
 
+  /* If length is larger than the length of one constant string, 
+     replace strncmp with corresponding strcmp */ 
+  if (fcode == BUILT_IN_STRNCMP 
+      && length > 0
+      && ((p2 && (size_t) length > strlen (p2)) 
+          || (p1 && (size_t) length > strlen (p1))))
+    {
+      tree fn = builtin_decl_implicit (BUILT_IN_STRCMP);
+      if (!fn)
+        return false;
+      gimple *repl = gimple_build_call (fn, 2, str1, str2);
+      replace_call_with_call_and_fold (gsi, repl);
+      return true;
+    }
+
   return false;
 }
 
diff --git a/gcc/testsuite/gcc.dg/strcmpopt_1.c 
b/gcc/testsuite/gcc.dg/strcmpopt_1.c
new file mode 100644
index 0000000..40596a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strcmpopt_1.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-gimple" } */
+
+#include <string.h>
+#include <stdlib.h>
+
+int cmp1 (char *p)
+{
+  return strncmp (p, "fis", 4);
+}
+int cmp2 (char *q)
+{
+  return strncmp ("fis", q, 4);
+}
+
+int main ()
+{
+
+  char *p = "fish";
+  char *q = "fis\0";
+
+  if (cmp1 (p) == 0 || cmp2 (q) != 0)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "strcmp \\(" 2 "gimple" } } */
-- 
1.9.1

Reply via email to