Fix PR tree-optimization/96670 - ICE on memchr with an empty initializer.
authorMartin Sebor <msebor@redhat.com>
Tue, 18 Aug 2020 18:49:35 +0000 (12:49 -0600)
committerMartin Sebor <msebor@redhat.com>
Tue, 18 Aug 2020 18:49:35 +0000 (12:49 -0600)
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
gcc/testsuite/gcc.dg/memchr-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/memcmp-6.c [new file with mode: 0644]

index db56cb6..dcc1b56 100644 (file)
@@ -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 (file)
index 0000000..61357f9
--- /dev/null
@@ -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 (file)
index 0000000..d573526
--- /dev/null
@@ -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" } } */