Commit ca8034a0 by Kaveh R. Ghazi Committed by Kaveh Ghazi

builtins.c (expand_builtin_strcmp): Use const*_rtx when expanding strcmp at compile-time.

	* builtins.c (expand_builtin_strcmp): Use const*_rtx when
	expanding strcmp at compile-time.  Add another transformation.
	(expand_builtin_strncmp): Add more transformations.  Call
	expand_builtin_memcmp, not expand_builtin_strcmp, under
	appropriate conditions if HAVE_cmpstrsi.

testsuite:
	gcc.c-torture/execute/string-opt-3.c: Add more strcmp checks.
	gcc.c-torture/execute/string-opt-8.c: Add more strncmp checks.

From-SVN: r37963
parent 6c873122
2000-12-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* builtins.c (expand_builtin_strcmp): Use const*_rtx when
expanding strcmp at compile-time. Add another transformation.
(expand_builtin_strncmp): Add more transformations. Call
expand_builtin_memcmp, not expand_builtin_strcmp, under
appropriate conditions if HAVE_cmpstrsi.
2000-12-02 David Edelsohn <edelsohn@gnu.org> 2000-12-02 David Edelsohn <edelsohn@gnu.org>
* rs6000.md (anddi3_internal[23]): Prefer rldic? over andis * rs6000.md (anddi3_internal[23]): Prefer rldic? over andis
......
...@@ -2244,14 +2244,28 @@ expand_builtin_strcmp (exp, target, mode) ...@@ -2244,14 +2244,28 @@ expand_builtin_strcmp (exp, target, mode)
if (p1 && p2) if (p1 && p2)
{ {
int i = strcmp (p1, p2); const int i = strcmp (p1, p2);
return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
return expand_expr (i < 0 ? build_int_2 (-1, -1)
: i == 0 ? integer_zero_node
: integer_one_node,
target, mode, EXPAND_NORMAL);
} }
/* If either arg is "", return an expression corresponding to
(*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
if ((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);
tree ind1 =
fold (build1 (CONVERT_EXPR, integer_type_node,
build1 (INDIRECT_REF, cst_uchar_node,
build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
tree ind2 =
fold (build1 (CONVERT_EXPR, integer_type_node,
build1 (INDIRECT_REF, cst_uchar_node,
build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
return expand_expr (result, target, mode, EXPAND_NORMAL);
}
#ifdef HAVE_cmpstrsi #ifdef HAVE_cmpstrsi
if (! HAVE_cmpstrsi) if (! HAVE_cmpstrsi)
return 0; return 0;
...@@ -2360,25 +2374,51 @@ expand_builtin_strncmp (exp, target, mode) ...@@ -2360,25 +2374,51 @@ expand_builtin_strncmp (exp, target, mode)
return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx)); return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
} }
/* If either string parameter is constant and its strlen is strictly /* If len == 1 or (either string parameter is "" and (len >= 1)),
less than the length parameter, call expand_builtin_strcmp(). */ return (*(u_char*)arg1 - *(u_char*)arg2). */
if ((p1 && compare_tree_int (arg3, strlen (p1)) > 0) if (compare_tree_int (arg3, 1) == 0
|| (p2 && compare_tree_int (arg3, strlen (p2)) > 0)) || (compare_tree_int (arg3, 1) > 0
{ && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))))
tree newarglist = {
tree_cons (NULL_TREE, arg1, build_tree_list (NULL_TREE, arg2)); tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
rtx result; tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
tree ind1 =
fold (build1 (CONVERT_EXPR, integer_type_node,
build1 (INDIRECT_REF, cst_uchar_node,
build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
tree ind2 =
fold (build1 (CONVERT_EXPR, integer_type_node,
build1 (INDIRECT_REF, cst_uchar_node,
build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
return expand_expr (result, target, mode, EXPAND_NORMAL);
}
/* Call expand_builtin_strcmp with the modified newarglist. If #ifdef HAVE_cmpstrsi
the expansion does not occur, do not allow strncmp to expand to /* If the length parameter is constant (checked above) and either
strcmp since strcmp requires that both strings be NULL string parameter is constant, call expand_builtin_memcmp() using
terminated whereas strncmp does not. */ a length parameter equal to the lesser of the given length and
TREE_OPERAND (exp, 1) = newarglist; the strlen+1 of the constant string. */
result = expand_builtin_strcmp (exp, target, mode); if (HAVE_cmpstrsi && (p1 || p2))
/* Always restore the original arguments. */ {
TREE_OPERAND (exp, 1) = arglist; /* Exactly one of the strings is constant at this point, because
return result; 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);
}
#endif
return 0; return 0;
} }
......
2000-12-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
gcc.c-torture/execute/string-opt-3.c: Add more strcmp checks.
gcc.c-torture/execute/string-opt-8.c: Add more strncmp checks.
2000-12-02 Geoffrey Keating <geoffk@redhat.com> 2000-12-02 Geoffrey Keating <geoffk@redhat.com>
* gcc.dg/cpp/if-6.c: New testcase. * gcc.dg/cpp/if-6.c: New testcase.
......
...@@ -37,6 +37,18 @@ int main() ...@@ -37,6 +37,18 @@ int main()
abort (); abort ();
if (strcmp (10 + foo, "dx") >= 0) if (strcmp (10 + foo, "dx") >= 0)
abort (); abort ();
if (strcmp (bar, "") <= 0)
abort ();
if (strcmp ("", bar) >= 0)
abort ();
if (strcmp (bar+8, "") != 0)
abort ();
if (strcmp ("", bar+8) != 0)
abort ();
if (strcmp (bar+(--x), "") <= 0 || x != 6)
abort ();
if (strcmp ("", bar+(++x)) >= 0 || x != 7)
abort ();
if (strrchr (foo, 'x')) if (strrchr (foo, 'x'))
abort (); abort ();
if (strrchr (foo, 'o') != foo + 7) if (strrchr (foo, 'o') != foo + 7)
......
...@@ -44,6 +44,103 @@ int main () ...@@ -44,6 +44,103 @@ int main ()
s2 = s1; s3 = s1+4; s2 = s1; s3 = s1+4;
if (strncmp (++s2, ++s3, 0) != 0 || s2 != s1+1 || s3 != s1+5) if (strncmp (++s2, ++s3, 0) != 0 || s2 != s1+1 || s3 != s1+5)
abort(); abort();
s2 = s1;
if (strncmp (++s2, "", 1) <= 0 || s2 != s1+1)
abort();
if (strncmp ("", ++s2, 1) >= 0 || s2 != s1+2)
abort();
if (strncmp (++s2, "", 100) <= 0 || s2 != s1+3)
abort();
if (strncmp ("", ++s2, 100) >= 0 || s2 != s1+4)
abort();
if (strncmp (++s2+6, "", 100) != 0 || s2 != s1+5)
abort();
if (strncmp ("", ++s2+5, 100) != 0 || s2 != s1+6)
abort();
if (strncmp ("ozz", ++s2, 1) != 0 || s2 != s1+7)
abort();
if (strncmp (++s2, "rzz", 1) != 0 || s2 != s1+8)
abort();
s2 = s1; s3 = s1+4;
if (strncmp (++s2, ++s3+2, 1) >= 0 || s2 != s1+1 || s3 != s1+5)
abort();
#if defined(__i386__)
/* These tests work on platforms which support cmpstrsi. */
s2 = s1;
if (strncmp (++s2, "ello", 3) != 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp ("ello", ++s2, 3) != 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp (++s2, "ello", 4) != 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp ("ello", ++s2, 4) != 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp (++s2, "ello", 5) <= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp ("ello", ++s2, 5) >= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp (++s2, "ello", 6) <= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp ("ello", ++s2, 6) >= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp (++s2, "zllo", 3) >= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp ("zllo", ++s2, 3) <= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp (++s2, "zllo", 4) >= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp ("zllo", ++s2, 4) <= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp (++s2, "zllo", 5) >= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp ("zllo", ++s2, 5) <= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp (++s2, "zllo", 6) >= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp ("zllo", ++s2, 6) <= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp (++s2, "allo", 3) <= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp ("allo", ++s2, 3) >= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp (++s2, "allo", 4) <= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp ("allo", ++s2, 4) >= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp (++s2, "allo", 5) <= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp ("allo", ++s2, 5) >= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp (++s2, "allo", 6) <= 0 || s2 != s1+1)
abort();
s2 = s1;
if (strncmp ("allo", ++s2, 6) >= 0 || s2 != s1+1)
abort();
#endif
return 0; return 0;
} }
......
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