From 6e34e617754c45b58f3ef9c5cbacfb71419ba2e4 Mon Sep 17 00:00:00 2001 From: ghazi Date: Wed, 3 Jan 2001 16:48:15 +0000 Subject: [PATCH] * 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__. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38664 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 ++ gcc/builtins.c | 75 +++++++++++--------- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.c-torture/execute/string-opt-8.c | 79 +++++++++++++++++++++- 4 files changed, 130 insertions(+), 34 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 23e3743b10c..0a74c9a302a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2001-01-03 Kaveh R. Ghazi + + * 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 * config/sparc/sparc.h (RETURN_IN_MEMORY): Return 0 for variable diff --git a/gcc/builtins.c b/gcc/builtins.c index 70a4b89be36..dbacc4742aa 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 32b834958af..f29c3902974 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2001-01-03 Kaveh R. Ghazi + + * gcc.c-torture/execute/string-opt-8.c: Add more testcases. + Turn on cmpstrsi checks for __pj__ and __i370__. + 2001-01-03 Nathan Sidwell * g++.old-deja/g++.other/virtual11.C: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/string-opt-8.c b/gcc/testsuite/gcc.c-torture/execute/string-opt-8.c index 6a4edb5d641..bcbb73cd576 100644 --- a/gcc/testsuite/gcc.c-torture/execute/string-opt-8.c +++ b/gcc/testsuite/gcc.c-torture/execute/string-opt-8.c @@ -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 -- 2.11.0