builtins.c (expand_builtin_strncmp): Use host_integerp and tree_low_cst.
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>
Wed, 3 Jan 2001 16:48:15 +0000 (16:48 +0000)
committerKaveh Ghazi <ghazi@gcc.gnu.org>
Wed, 3 Jan 2001 16:48:15 +0000 (16:48 +0000)
* builtins.c (expand_builtin_strncmp): Use host_integerp and
tree_low_cst.  Allow using cmpstrsi in more cases.

testsuite:
* gcc.c-torture/execute/string-opt-8.c: Add more testcases.
Turn on cmpstrsi checks for __pj__ and __i370__.

From-SVN: r38664

gcc/ChangeLog
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/string-opt-8.c

index 23e3743..0a74c9a 100644 (file)
@@ -1,3 +1,8 @@
+2001-01-03  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * builtins.c (expand_builtin_strncmp): Use host_integerp and
+       tree_low_cst.  Allow using cmpstrsi in more cases.
+
 Wed Jan  3 10:48:43 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * config/sparc/sparc.h (RETURN_IN_MEMORY): Return 0 for variable
index 70a4b89..dbacc47 100644 (file)
@@ -2330,12 +2330,8 @@ expand_builtin_strncmp (exp, target, mode)
   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
 
-  /* We must be passed a constant len parameter.  */
-  if (TREE_CODE (arg3) != INTEGER_CST)
-    return 0;
-  
   /* If the len parameter is zero, return zero.  */
-  if (compare_tree_int (arg3, 0) == 0)
+  if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
   {
     /* Evaluate and ignore arg1 and arg2 in case they have
        side-effects.  */
@@ -2348,17 +2344,18 @@ expand_builtin_strncmp (exp, target, mode)
   p2 = c_getstr (arg2);
 
   /* If all arguments are constant, evaluate at compile-time.  */
-  if (p1 && p2)
+  if (host_integerp (arg3, 1) && p1 && p2)
   {
-    const int r = strncmp (p1, p2, TREE_INT_CST_LOW (arg3));
+    const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
     return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
   }
 
   /* If len == 1 or (either string parameter is "" and (len >= 1)),
-      return (*(u_char*)arg1 - *(u_char*)arg2).  */
-  if (compare_tree_int (arg3, 1) == 0
-      || (compare_tree_int (arg3, 1) > 0
-         && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))))
+      return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
+  if (host_integerp (arg3, 1)
+      && (tree_low_cst (arg3, 1) == 1
+         || (tree_low_cst (arg3, 1) > 1
+             && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
     {
       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
@@ -2375,28 +2372,40 @@ expand_builtin_strncmp (exp, target, mode)
     }
 
 #ifdef HAVE_cmpstrsi
-  /* If the length parameter is constant (checked above) and either
-     string parameter is constant, call expand_builtin_memcmp() using
-     a length parameter equal to the lesser of the given length and
-     the strlen+1 of the constant string.  */
-  if (HAVE_cmpstrsi && (p1 || p2))
-    {
-      /* Exactly one of the strings is constant at this point, because
-        if both were then we'd have expanded this at compile-time.  */
-      tree string_len = p1 ? c_strlen (arg1) : c_strlen (arg2);
-
-      string_len = size_binop (PLUS_EXPR, string_len, ssize_int (1));
-      
-      if (tree_int_cst_lt (string_len, arg3))
-        {
-         /* The strlen+1 is strictly shorter, use it.  */
-         tree newarglist = build_tree_list (NULL_TREE, string_len);
-         newarglist = tree_cons (NULL_TREE, arg2, newarglist);
-         newarglist = tree_cons (NULL_TREE, arg1, newarglist);
-         return expand_builtin_memcmp (exp, newarglist, target);
-       }
-      else
-       return expand_builtin_memcmp (exp, arglist, target);
+  /* If c_strlen can determine an expression for one of the string
+     lengths, and it doesn't have side effects, then call
+     expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3).  */
+  if (HAVE_cmpstrsi)
+    { 
+      tree newarglist, len = 0;
+
+      /* Perhaps one of the strings is really constant, if so prefer
+         that constant length over the other string's length.  */
+      if (p1)
+       len = c_strlen (arg1);
+      else if (p2)
+       len = c_strlen (arg2);
+
+      /* If we still don't have a len, try either string arg as long
+        as they don't have side effects.  */
+      if (!len && !TREE_SIDE_EFFECTS (arg1))
+       len = c_strlen (arg1);
+      if (!len && !TREE_SIDE_EFFECTS (arg2))
+       len = c_strlen (arg2);
+      /* If we still don't have a length, punt.  */
+      if (!len)
+       return 0;
+       
+      /* Add one to the string length.  */
+      len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
+        
+      /* The actual new length parameter is MIN(len,arg3).  */
+      len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
+
+      newarglist = build_tree_list (NULL_TREE, len);
+      newarglist = tree_cons (NULL_TREE, arg2, newarglist);
+      newarglist = tree_cons (NULL_TREE, arg1, newarglist);
+      return expand_builtin_memcmp (exp, newarglist, target);
     }
 #endif
   
index 32b8349..f29c390 100644 (file)
@@ -1,3 +1,8 @@
+2001-01-03  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * gcc.c-torture/execute/string-opt-8.c: Add more testcases.
+       Turn on cmpstrsi checks for __pj__ and __i370__.
+
 2001-01-03  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.old-deja/g++.other/virtual11.C: New test.
index 6a4edb5..bcbb73c 100644 (file)
@@ -13,6 +13,7 @@ int main ()
 {
   const char *const s1 = "hello world";
   const char *s2, *s3;
+  int n = 6, x;
   
   if (strncmp (s1, "hello world", 12) != 0)
     abort();
@@ -64,7 +65,7 @@ int main ()
   s2 = s1; s3 = s1+4;
   if (strncmp (++s2, ++s3+2, 1) >= 0 || s2 != s1+1 || s3 != s1+5)
     abort();
-#if defined(__i386__)
+#if defined(__i386__) || defined (__pj__) || defined (__i370__)
   /* These tests work on platforms which support cmpstrsi.  */
   s2 = s1;
   if (strncmp (++s2, "ello", 3) != 0 || s2 != s1+1)
@@ -140,6 +141,82 @@ int main ()
   s2 = s1;
   if (strncmp ("allo", ++s2, 6) >= 0 || s2 != s1+1)
     abort();
+
+  s2 = s1; n = 2; x = 1;
+  if (strncmp (++s2, s1+(x&3), ++n) != 0 || s2 != s1+1 || n != 3)
+    abort();
+  s2 = s1; n = 2; x = 1;
+  if (strncmp (s1+(x&3), ++s2, ++n) != 0 || s2 != s1+1 || n != 3)
+    abort();
+  s2 = s1; n = 3; x = 1;
+  if (strncmp (++s2, s1+(x&3), ++n) != 0 || s2 != s1+1 || n != 4)
+    abort();
+  s2 = s1; n = 3; x = 1;
+  if (strncmp (s1+(x&3), ++s2, ++n) != 0 || s2 != s1+1 || n != 4)
+    abort();
+  s2 = s1; n = 4; x = 1;
+  if (strncmp (++s2, s1+(x&3), ++n) != 0 || s2 != s1+1 || n != 5)
+    abort();
+  s2 = s1; n = 4; x = 1;
+  if (strncmp (s1+(x&3), ++s2, ++n) != 0 || s2 != s1+1 || n != 5)
+    abort();
+  s2 = s1; n = 5; x = 1;
+  if (strncmp (++s2, s1+(x&3), ++n) != 0 || s2 != s1+1 || n != 6)
+    abort();
+  s2 = s1; n = 5; x = 1;
+  if (strncmp (s1+(x&3), ++s2, ++n) != 0 || s2 != s1+1 || n != 6)
+    abort();
+
+  s2 = s1; n = 2;
+  if (strncmp (++s2, "zllo", ++n) >= 0 || s2 != s1+1 || n != 3)
+    abort();
+  s2 = s1; n = 2; x = 1;
+  if (strncmp ("zllo", ++s2, ++n) <= 0 || s2 != s1+1 || n != 3)
+    abort();
+  s2 = s1; n = 3; x = 1;
+  if (strncmp (++s2, "zllo", ++n) >= 0 || s2 != s1+1 || n != 4)
+    abort();
+  s2 = s1; n = 3; x = 1;
+  if (strncmp ("zllo", ++s2, ++n) <= 0 || s2 != s1+1 || n != 4)
+    abort();
+  s2 = s1; n = 4; x = 1;
+  if (strncmp (++s2, "zllo", ++n) >= 0 || s2 != s1+1 || n != 5)
+    abort();
+  s2 = s1; n = 4; x = 1;
+  if (strncmp ("zllo", ++s2, ++n) <= 0 || s2 != s1+1 || n != 5)
+    abort();
+  s2 = s1; n = 5; x = 1;
+  if (strncmp (++s2, "zllo", ++n) >= 0 || s2 != s1+1 || n != 6)
+    abort();
+  s2 = s1; n = 5; x = 1;
+  if (strncmp ("zllo", ++s2, ++n) <= 0 || s2 != s1+1 || n != 6)
+    abort();
+
+  s2 = s1; n = 2;
+  if (strncmp (++s2, "allo", ++n) <= 0 || s2 != s1+1 || n != 3)
+    abort();
+  s2 = s1; n = 2; x = 1;
+  if (strncmp ("allo", ++s2, ++n) >= 0 || s2 != s1+1 || n != 3)
+    abort();
+  s2 = s1; n = 3; x = 1;
+  if (strncmp (++s2, "allo", ++n) <= 0 || s2 != s1+1 || n != 4)
+    abort();
+  s2 = s1; n = 3; x = 1;
+  if (strncmp ("allo", ++s2, ++n) >= 0 || s2 != s1+1 || n != 4)
+    abort();
+  s2 = s1; n = 4; x = 1;
+  if (strncmp (++s2, "allo", ++n) <= 0 || s2 != s1+1 || n != 5)
+    abort();
+  s2 = s1; n = 4; x = 1;
+  if (strncmp ("allo", ++s2, ++n) >= 0 || s2 != s1+1 || n != 5)
+    abort();
+  s2 = s1; n = 5; x = 1;
+  if (strncmp (++s2, "allo", ++n) <= 0 || s2 != s1+1 || n != 6)
+    abort();
+  s2 = s1; n = 5; x = 1;
+  if (strncmp ("allo", ++s2, ++n) >= 0 || s2 != s1+1 || n != 6)
+    abort();
+
 #endif  
   
   /* Test at least one instance of the __builtin_ style.  We do this