diff options
author | Roger Sayle <roger@eyesopen.com> | 2001-12-27 23:34:31 +0000 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2001-12-27 15:34:31 -0800 |
commit | fe85f179e895686974d32e66d26e321647dd1519 (patch) | |
tree | b184d011cb0a84a8f17030c368d557336ab31867 /gcc/builtins.c | |
parent | 30d7b5f4139259ea367158d33c40924826b407fd (diff) | |
download | gcc-fe85f179e895686974d32e66d26e321647dd1519.zip gcc-fe85f179e895686974d32e66d26e321647dd1519.tar.gz gcc-fe85f179e895686974d32e66d26e321647dd1519.tar.bz2 |
re PR rtl-optimization/3508 (builtin memcmp() could be optimised)
* builtins.c (expand_builtin_memcmp): Optimize memcmp built-in
when all arguments are known constant. Fixes PR opt/3508.
* gcc.c-torture/execute/string-opt-16.c: New testcase.
From-SVN: r48335
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 1df7a0d..d7d83e8 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2252,6 +2252,7 @@ expand_builtin_memcmp (exp, arglist, target, mode) enum machine_mode mode; { tree arg1, arg2, len; + const char *p1, *p2; if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) @@ -2271,6 +2272,19 @@ expand_builtin_memcmp (exp, arglist, target, mode) return const0_rtx; } + p1 = c_getstr (arg1); + p2 = c_getstr (arg2); + + /* If all arguments are constant, and the value of len is not greater + than the lengths of arg1 and arg2, evaluate at compile-time. */ + if (host_integerp (len, 1) && p1 && p2 + && compare_tree_int (len, strlen (p1)+1) <= 0 + && compare_tree_int (len, strlen (p2)+1) <= 0) + { + const int r = memcmp (p1, p2, tree_low_cst (len, 1)); + return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx)); + } + /* If len parameter is one, return an expression corresponding to (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */ if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1) |