The recent enhancement to memchr/memcmp folding introduced two bugs
(that I know of).  The attached patch fixes the one where a call to
the string_constant function that would previously be guaranteed to
succeed now fails as a result of the function only handling strings
and not other types.  The unexpected failure triggers an ICE down
the line.  I have committed the bootstrapped/regtested one-line
patch in r11-2742.

Martin
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.

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" } } */

Reply via email to