Commit 819c1488 by Kaveh R. Ghazi Committed by Kaveh Ghazi

builtins.c (expand_builtin_strncmp): Use host_integerp and tree_low_cst.

	* 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
parent 36e40658
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> 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 * config/sparc/sparc.h (RETURN_IN_MEMORY): Return 0 for variable
......
...@@ -2330,12 +2330,8 @@ expand_builtin_strncmp (exp, target, mode) ...@@ -2330,12 +2330,8 @@ expand_builtin_strncmp (exp, target, mode)
arg2 = TREE_VALUE (TREE_CHAIN (arglist)); arg2 = TREE_VALUE (TREE_CHAIN (arglist));
arg3 = TREE_VALUE (TREE_CHAIN (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 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 /* Evaluate and ignore arg1 and arg2 in case they have
side-effects. */ side-effects. */
...@@ -2348,17 +2344,18 @@ expand_builtin_strncmp (exp, target, mode) ...@@ -2348,17 +2344,18 @@ expand_builtin_strncmp (exp, target, mode)
p2 = c_getstr (arg2); p2 = c_getstr (arg2);
/* If all arguments are constant, evaluate at compile-time. */ /* 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)); return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
} }
/* If len == 1 or (either string parameter is "" and (len >= 1)), /* If len == 1 or (either string parameter is "" and (len >= 1)),
return (*(u_char*)arg1 - *(u_char*)arg2). */ return (*(const u_char*)arg1 - *(const u_char*)arg2). */
if (compare_tree_int (arg3, 1) == 0 if (host_integerp (arg3, 1)
|| (compare_tree_int (arg3, 1) > 0 && (tree_low_cst (arg3, 1) == 1
&& ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))) || (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_node = build_type_variant (unsigned_char_type_node, 1, 0);
tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node); tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
...@@ -2375,28 +2372,40 @@ expand_builtin_strncmp (exp, target, mode) ...@@ -2375,28 +2372,40 @@ expand_builtin_strncmp (exp, target, mode)
} }
#ifdef HAVE_cmpstrsi #ifdef HAVE_cmpstrsi
/* If the length parameter is constant (checked above) and either /* If c_strlen can determine an expression for one of the string
string parameter is constant, call expand_builtin_memcmp() using lengths, and it doesn't have side effects, then call
a length parameter equal to the lesser of the given length and expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3). */
the strlen+1 of the constant string. */ if (HAVE_cmpstrsi)
if (HAVE_cmpstrsi && (p1 || p2)) {
{ tree newarglist, len = 0;
/* Exactly one of the strings is constant at this point, because
if both were then we'd have expanded this at compile-time. */ /* Perhaps one of the strings is really constant, if so prefer
tree string_len = p1 ? c_strlen (arg1) : c_strlen (arg2); that constant length over the other string's length. */
if (p1)
string_len = size_binop (PLUS_EXPR, string_len, ssize_int (1)); len = c_strlen (arg1);
else if (p2)
if (tree_int_cst_lt (string_len, arg3)) len = c_strlen (arg2);
{
/* The strlen+1 is strictly shorter, use it. */ /* If we still don't have a len, try either string arg as long
tree newarglist = build_tree_list (NULL_TREE, string_len); as they don't have side effects. */
newarglist = tree_cons (NULL_TREE, arg2, newarglist); if (!len && !TREE_SIDE_EFFECTS (arg1))
newarglist = tree_cons (NULL_TREE, arg1, newarglist); len = c_strlen (arg1);
return expand_builtin_memcmp (exp, newarglist, target); if (!len && !TREE_SIDE_EFFECTS (arg2))
} len = c_strlen (arg2);
else /* If we still don't have a length, punt. */
return expand_builtin_memcmp (exp, arglist, target); 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 #endif
......
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> 2001-01-03 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.other/virtual11.C: New test. * g++.old-deja/g++.other/virtual11.C: New test.
......
...@@ -13,6 +13,7 @@ int main () ...@@ -13,6 +13,7 @@ int main ()
{ {
const char *const s1 = "hello world"; const char *const s1 = "hello world";
const char *s2, *s3; const char *s2, *s3;
int n = 6, x;
if (strncmp (s1, "hello world", 12) != 0) if (strncmp (s1, "hello world", 12) != 0)
abort(); abort();
...@@ -64,7 +65,7 @@ int main () ...@@ -64,7 +65,7 @@ int main ()
s2 = s1; s3 = s1+4; s2 = s1; s3 = s1+4;
if (strncmp (++s2, ++s3+2, 1) >= 0 || s2 != s1+1 || s3 != s1+5) if (strncmp (++s2, ++s3+2, 1) >= 0 || s2 != s1+1 || s3 != s1+5)
abort(); abort();
#if defined(__i386__) #if defined(__i386__) || defined (__pj__) || defined (__i370__)
/* These tests work on platforms which support cmpstrsi. */ /* These tests work on platforms which support cmpstrsi. */
s2 = s1; s2 = s1;
if (strncmp (++s2, "ello", 3) != 0 || s2 != s1+1) if (strncmp (++s2, "ello", 3) != 0 || s2 != s1+1)
...@@ -140,6 +141,82 @@ int main () ...@@ -140,6 +141,82 @@ int main ()
s2 = s1; s2 = s1;
if (strncmp ("allo", ++s2, 6) >= 0 || s2 != s1+1) if (strncmp ("allo", ++s2, 6) >= 0 || s2 != s1+1)
abort(); 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 #endif
/* Test at least one instance of the __builtin_ style. We do this /* Test at least one instance of the __builtin_ style. We do this
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment