From bb04901d14f7749eb949092fd3dfcb6ca1958701 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 18 Aug 2020 12:49:35 -0600 Subject: [PATCH] Fix PR tree-optimization/96670 - ICE on memchr with an empty initializer. gcc/ChangeLog: PR tree-optimization/96670 PR middle-end/78257 * gimple-fold.c (gimple_fold_builtin_memchr): Call byte_representation to get it, not string_constant. gcc/testsuite/ChangeLog: PR tree-optimization/96670 * gcc.dg/memchr-2.c: New test. * gcc.dg/memcmp-6.c: New test. --- gcc/gimple-fold.c | 2 +- gcc/testsuite/gcc.dg/memchr-2.c | 41 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/memcmp-6.c | 47 +++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/memchr-2.c create mode 100644 gcc/testsuite/gcc.dg/memcmp-6.c diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index db56cb6aa47..dcc1b56a273 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -2670,7 +2670,7 @@ gimple_fold_builtin_memchr (gimple_stmt_iterator *gsi) if (r == NULL) { tree mem_size, offset_node; - string_constant (arg1, &offset_node, &mem_size, NULL); + byte_representation (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 diff --git a/gcc/testsuite/gcc.dg/memchr-2.c b/gcc/testsuite/gcc.dg/memchr-2.c new file mode 100644 index 00000000000..61357f96d12 --- /dev/null +++ b/gcc/testsuite/gcc.dg/memchr-2.c @@ -0,0 +1,41 @@ +/* PR tree-optimization/96670 - ICE on memchr with an empty initializer + { dg-do compile } + { dg-options "-O -Wall -fdump-tree-optimized" } */ + +struct { + int i, j; +} const s = { }; + +void memchr_success_unused (void) +{ + int n = (char *)&s.j - (char *)&s; + char *p = (char *)&s; + __builtin_memchr (p, '\0', n); +} + +void memchr_success_used (void) +{ + int n = (char *)&s.j - (char *)&s; + char *p = (char *)&s; + if (&s != __builtin_memchr (p, '\0', n)) + __builtin_abort (); +} + +void memchr_fail_unused (void) +{ + int n = (char *)&s.j - (char *)&s; + char *p = (char *)&s; + __builtin_memchr (p, '\5', n); +} + +void memchr_fail_used (void) +{ + int n = (char *)&s.j - (char *)&s; + char *p = (char *)&s; + if (__builtin_memchr (p, '\5', n)) + __builtin_abort (); +} + +/* { dg-prune-output "\\\[-Wunused-value" } + { dg-final { scan-tree-dump-not "abort" "optimized" } } + { dg-final { scan-tree-dump-not "memcmp \\(" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/memcmp-6.c b/gcc/testsuite/gcc.dg/memcmp-6.c new file mode 100644 index 00000000000..d57352616cf --- /dev/null +++ b/gcc/testsuite/gcc.dg/memcmp-6.c @@ -0,0 +1,47 @@ +/* PR tree-optimization/96670 - ICE on memchr with an empty initializer + { dg-do compile } + { dg-options "-O -Wall -fdump-tree-optimized" } */ + +struct { + int i, j; +} const s = { }; + +const char a[sizeof s] = { }; + +void memcmp_success_unused (void) +{ + int n = (char *)&s.j - (char *)&s; + char *p = (char *)&s; + __builtin_memcmp (p, a, n); + __builtin_memcmp (a, p, n); +} + +void memcmp_success_used (void) +{ + int n = (char *)&s.j - (char *)&s; + char *p = (char *)&s; + if (__builtin_memcmp (p, a, n) + || __builtin_memcmp (a, p, n)) + __builtin_abort (); +} + +void memcmp_fail_unused (void) +{ + int n = (char *)&s.j - (char *)&s; + char *p = (char *)&s; + __builtin_memcmp (p, a, n); + __builtin_memcmp (a, p, n); +} + +void memcmp_fail_used (void) +{ + int n = (char *)&s.j - (char *)&s; + char *p = (char *)&s; + if (__builtin_memcmp (p, a, n) + || __builtin_memcmp (a, p, n)) + __builtin_abort (); +} + +/* { dg-prune-output "\\\[-Wunused-value" } + { dg-final { scan-tree-dump-not "abort" "optimized" } } + { dg-final { scan-tree-dump-not "memcmp \\\(" "optimized" } } */ -- 2.30.2