在 2019/5/6 下午7:58, JunMa 写道:
在 2019/5/6 下午6:02, Richard Biener 写道:
On Thu, Mar 21, 2019 at 5:57 AM JunMa <ju...@linux.alibaba.com> wrote:
Hi
For now, gcc can not fold code like:
const char a[5] = "123"
__builtin_memchr (a, '7', sizeof a)
It tries to avoid folding out of string length although length of a
is 5.
This is a bit conservative, it's safe to folding memchr/bcmp/memcmp
builtins when constant string stores in array with some trailing nuls.
This patch folds these cases by exposing additional length of
trailing nuls in c_getstr().
Bootstrapped/regtested on x86_64-linux, ok for trunk?
It's probably better if gimple_fold_builtin_memchr uses string_constant
directly instead?
We can use string_constant in gimple_fold_builtin_memchr, however it is a
bit complex to use it in memchr/memcmp constant folding.
You are changing memcmp constant folding but only have a testcase
for memchr.
I'll add later.
If we decide to amend c_getstr I would rather make it return the
total length instead of the number of trailing zeros.
I think return the total length is safe in other place as well.
I used the argument in patch since I do not want any impact on
other part at all.
Although it is safe to use total length, I found that function
inline_expand_builtin_string_cmp() which used c_getstr() may emit
redundant rtls for trailing null chars when total length is returned.
Also it is trivial to handle constant string with trailing null chars.
So this updated patch follow richard's suggestion: using string_constant
directly.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
Regards
JunMa
gcc/ChangeLog
2019-05-07 Jun Ma <ju...@linux.alibaba.com>
PR Tree-optimization/89772
* gimple-fold.c (gimple_fold_builtin_memchr): consider trailing nuls in
out-of-bound accesses checking.
gcc/testsuite/ChangeLog
2019-05-07 Jun Ma <ju...@linux.alibaba.com>
PR Tree-optimization/89772
* gcc.dg/builtin-memchr-4.c: New test.
Thanks
JunMa
Richard.
Regards
JunMa
gcc/ChangeLog
2019-03-21 Jun Ma <ju...@linux.alibaba.com>
PR Tree-optimization/89772
* fold-const.c (c_getstr): Add new parameter to get length of
additional
trailing nuls after constant string.
* gimple-fold.c (gimple_fold_builtin_memchr): consider
trailing nuls in
out-of-bound accesses checking.
* fold-const-call.c (fold_const_call): Likewise.
gcc/testsuite/ChangeLog
2019-03-21 Jun Ma <ju...@linux.alibaba.com>
PR Tree-optimization/89772
* gcc.dg/builtin-memchr-4.c: New test.
---
gcc/gimple-fold.c | 9 ++++++++-
gcc/testsuite/gcc.dg/builtin-memchr-4.c | 30 ++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.dg/builtin-memchr-4.c
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 1b10bae..7ee5aea 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -2557,7 +2557,14 @@ gimple_fold_builtin_memchr (gimple_stmt_iterator *gsi)
const char *r = (const char *)memchr (p1, c, MIN (length,
string_length));
if (r == NULL)
{
- if (length <= string_length)
+ tree mem_size, offset_node;
+ string_constant (arg1, &offset_node, &mem_size, NULL);
+ unsigned HOST_WIDE_INT offset = (offset_node == NULL_TREE)
+ ? 0 : tree_to_uhwi (offset_node);
+ /* MEM_SIZE is the size of the array the string literal
+ is stored in. */
+ unsigned HOST_WIDE_INT string_size = tree_to_uhwi (mem_size) - offset;
+ if (length <= string_size)
{
replace_call_with_value (gsi, build_int_cst (ptr_type_node, 0));
return true;
diff --git a/gcc/testsuite/gcc.dg/builtin-memchr-4.c
b/gcc/testsuite/gcc.dg/builtin-memchr-4.c
new file mode 100644
index 0000000..3ef424c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-memchr-4.c
@@ -0,0 +1,30 @@
+/* PR tree-optimization/89772
+ Verify that memchr calls with a pointer to a constant character
+ are folded as expected.
+ { dg-do compile }
+ { dg-options "-O1 -Wall -fdump-tree-lower" } */
+
+typedef __SIZE_TYPE__ size_t;
+typedef __WCHAR_TYPE__ wchar_t;
+
+extern void* memchr (const void*, int, size_t);
+extern int printf (const char*, ...);
+extern void abort (void);
+
+#define A(expr) \
+ ((expr) \
+ ? (void)0 \
+ : (printf ("assertion failed on line %i: %s\n", \
+ __LINE__, #expr), \
+ abort ()))
+
+const char a[8] = {'a',0,'b'};
+
+void test_memchr_cst_char (void)
+{
+ A (!memchr (a, 'c', 2));
+ A (!memchr (a, 'c', 5));
+ A (!memchr (a, 'c', sizeof a));
+}
+
+/* { dg-final { scan-tree-dump-not "abort" "gimple" } } */
--
1.8.3.1