summaryrefslogtreecommitdiff
path: root/gcc/fold-const-call.c
diff options
context:
space:
mode:
authormarxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>2016-10-14 12:08:27 +0000
committermarxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>2016-10-14 12:08:27 +0000
commitac8a4f8e58d4925a9771f94336c43bd189b10737 (patch)
treec896ce6d1d5d5cec3b0369bdda9ddacf3ad4f63f /gcc/fold-const-call.c
parentff16a800057a4482d46a33e045b5522ee76fe960 (diff)
downloadgcc-ac8a4f8e58d4925a9771f94336c43bd189b10737.tar.gz
Fold __builtin_str{n}{case}cmp functions
* builtins.c (fold_builtin_strcmp): Remove function. (fold_builtin_strncmp): Likewise. (fold_builtin_2): Remove call of the function. (fold_builtin_3): Likewise. * fold-const-call.c (fold_const_call): Add constant folding for CFN_BUILT_IN_STRCASECMP and CFN_BUILT_IN_STRNCASECMP. * fold-const-call.h (build_cmp_result): Declare the function. * gimple-fold.c (gimple_load_first_char): New function. (gimple_fold_builtin_string_compare): Likewise. (gimple_fold_builtin): Call the function. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@241159 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const-call.c')
-rw-r--r--gcc/fold-const-call.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c
index 2bbc8872865..f67b245876c 100644
--- a/gcc/fold-const-call.c
+++ b/gcc/fold-const-call.c
@@ -69,7 +69,7 @@ host_size_t_cst_p (tree t, size_t *size_out)
"equal" and > 0 means "more". Canonicalize it to -1, 0 or 1 and
return it in type TYPE. */
-static inline tree
+tree
build_cmp_result (tree type, int res)
{
return build_int_cst (type, res < 0 ? -1 : res > 0 ? 1 : 0);
@@ -1397,6 +1397,15 @@ fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1)
return build_cmp_result (type, strcmp (p0, p1));
return NULL_TREE;
+ case CFN_BUILT_IN_STRCASECMP:
+ if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
+ {
+ int r = strcmp (p0, p1);
+ if (r == 0)
+ return build_cmp_result (type, r);
+ }
+ return NULL_TREE;
+
default:
return fold_const_call_1 (fn, type, arg0, arg1);
}
@@ -1464,16 +1473,36 @@ tree
fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
{
const char *p0, *p1;
- size_t s2;
+ size_t s2 = 0;
switch (fn)
{
case CFN_BUILT_IN_STRNCMP:
- if ((p0 = c_getstr (arg0))
- && (p1 = c_getstr (arg1))
- && host_size_t_cst_p (arg2, &s2))
- return build_int_cst (type, strncmp (p0, p1, s2));
- return NULL_TREE;
-
+ {
+ bool const_size_p = host_size_t_cst_p (arg2, &s2);
+ if (const_size_p && s2 == 0
+ && !TREE_SIDE_EFFECTS (arg0)
+ && !TREE_SIDE_EFFECTS (arg1))
+ return build_int_cst (type, 0);
+ else if (const_size_p
+ && (p0 = c_getstr (arg0))
+ && (p1 = c_getstr (arg1)))
+ return build_int_cst (type, strncmp (p0, p1, s2));
+ return NULL_TREE;
+ }
+ case CFN_BUILT_IN_STRNCASECMP:
+ {
+ bool const_size_p = host_size_t_cst_p (arg2, &s2);
+ if (const_size_p && s2 == 0
+ && !TREE_SIDE_EFFECTS (arg0)
+ && !TREE_SIDE_EFFECTS (arg1))
+ return build_int_cst (type, 0);
+ else if (const_size_p
+ && (p0 = c_getstr (arg0))
+ && (p1 = c_getstr (arg1))
+ && strncmp (p0, p1, s2) == 0)
+ return build_int_cst (type, 0);
+ return NULL_TREE;
+ }
case CFN_BUILT_IN_BCMP:
case CFN_BUILT_IN_MEMCMP:
if ((p0 = c_getstr (arg0))