diff options
author | Martin Liska <mliska@suse.cz> | 2016-10-14 14:09:51 +0200 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2016-10-14 12:09:51 +0000 |
commit | 488c624747ddb76a9110a4ada52073b584669d0d (patch) | |
tree | ace94ab399d4400cb7af811ab144e00cb1ed65fd /gcc/fold-const-call.c | |
parent | a918bfbf3c5b686362f3f97314c2b4bf142d2f82 (diff) | |
download | gcc-488c624747ddb76a9110a4ada52073b584669d0d.zip gcc-488c624747ddb76a9110a4ada52073b584669d0d.tar.gz gcc-488c624747ddb76a9110a4ada52073b584669d0d.tar.bz2 |
Fold __builtin_memchr function
* builtins.h(target_char_cst_p): Declare the function.
* builtins.c (fold_builtin_memchr): Remove.
(target_char_cst_p): Move the function from gimple-fold.c.
(fold_builtin_3): Do not call the function.
* gimple-fold.c (gimple_fold_builtin_memchr): New function.
(gimple_fold_builtin): Call the function.
* fold-const-call.c (fold_const_call_1): Handle CFN_BUILT_IN_MEMCHR.
From-SVN: r241160
Diffstat (limited to 'gcc/fold-const-call.c')
-rw-r--r-- | gcc/fold-const-call.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c index f67b245..05a15f9 100644 --- a/gcc/fold-const-call.c +++ b/gcc/fold-const-call.c @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "fold-const-call.h" #include "case-cfn-macros.h" #include "tm.h" /* For C[LT]Z_DEFINED_AT_ZERO. */ +#include "builtins.h" /* Functions that test for certain constant types, abstracting away the decision about whether to check for overflow. */ @@ -1463,6 +1464,36 @@ fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2) return NULL_TREE; } + switch (fn) + { + case CFN_BUILT_IN_MEMCHR: + { + char c; + if (integer_zerop (arg2) + && !TREE_SIDE_EFFECTS (arg0) + && !TREE_SIDE_EFFECTS (arg1)) + return build_int_cst (type, 0); + + if (!tree_fits_uhwi_p (arg2) || !target_char_cst_p (arg1, &c)) + return NULL_TREE; + + unsigned HOST_WIDE_INT length = tree_to_uhwi (arg2); + unsigned HOST_WIDE_INT string_length; + const char *p1 = c_getstr (arg0, &string_length); + if (p1) + { + const char *r + = (const char *)memchr (p1, c, MIN (length, string_length)); + if (r == NULL && length <= string_length) + return build_int_cst (type, 0); + } + + break; + } + default: + break; + } + return NULL_TREE; } |