PR tree-optimization/92412 - excessive errno aliasing assumption defeats optimization
authorMartin Sebor <msebor@redhat.com>
Tue, 12 Nov 2019 18:49:31 +0000 (18:49 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Tue, 12 Nov 2019 18:49:31 +0000 (11:49 -0700)
gcc/ChangeLog:

PR tree-optimization/92412
* targhooks.c (default_ref_may_alias_errno): Errono can only alias
extern variables.

gcc/testsuite/ChangeLog:

PR tree-optimization/92412
* gcc.dg/strlenopt-91.c: New test.

From-SVN: r278099

gcc/ChangeLog
gcc/targhooks.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/strlenopt-91.c [new file with mode: 0644]

index ddd9817..a434f25 100644 (file)
@@ -1,5 +1,11 @@
 2019-11-12  Martin Sebor  <msebor@redhat.com>
 
+       PR tree-optimization/92412
+       * targhooks.c (default_ref_may_alias_errno): Errono can only alias
+       extern variables.
+
+2019-11-12  Martin Sebor  <msebor@redhat.com>
+
        PR middle-end/83688
        * gimple-ssa-sprintf.c (format_result::alias_info): New struct.
        (directive::argno): New member.
index 822a031..b6443d2 100644 (file)
@@ -1414,9 +1414,11 @@ default_ref_may_alias_errno (ao_ref *ref)
   if (TYPE_UNSIGNED (TREE_TYPE (base))
       || TYPE_MODE (TREE_TYPE (base)) != TYPE_MODE (integer_type_node))
     return false;
-  /* The default implementation assumes an errno location
-     declaration is never defined in the current compilation unit.  */
+  /* The default implementation assumes an errno location declaration
+     is never defined in the current compilation unit and may not be
+     aliased by a local variable.  */
   if (DECL_P (base)
+      && DECL_EXTERNAL (base)
       && !TREE_STATIC (base))
     return true;
   else if (TREE_CODE (base) == MEM_REF
index 460ca2b..584ccd7 100644 (file)
@@ -1,5 +1,10 @@
 2019-11-12  Martin Sebor  <msebor@redhat.com>
 
+       PR tree-optimization/92412
+       * gcc.dg/strlenopt-91.c: New test.
+
+2019-11-12  Martin Sebor  <msebor@redhat.com>
+
        PR tree-optimization/35503
        * gcc.dg/tree-ssa/builtin-sprintf-warn-23.c: New test.
 
diff --git a/gcc/testsuite/gcc.dg/strlenopt-91.c b/gcc/testsuite/gcc.dg/strlenopt-91.c
new file mode 100644 (file)
index 0000000..2381d03
--- /dev/null
@@ -0,0 +1,124 @@
+/* PR tree-optimization/92412 - excessive errno aliasing assumption defeats
+   optimization
+   { dg-do compile }
+   { dg-options "-O2 -Wall -fdump-tree-optimized" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+extern void* alloca (size_t);
+extern void* calloc (size_t, size_t);
+extern void* malloc (size_t);
+
+extern const char exta[4];
+static char stata[] = "123";
+
+void sink (const void*, ...);
+
+#define T(ptr, alloc) do {                                             \
+    const char *p = ptr;                                               \
+    if (p[0] != '1' || p[1] != '2' || p[2] != '3' || p[3] != '\0'      \
+       || __builtin_strlen (p) != 3)                                   \
+      return;                                                          \
+                                                                       \
+    void *q = alloc;                                                   \
+    __builtin_strcpy (q, p);                                           \
+                                                                       \
+    if (p[0] != '1' || p[1] != '2' || p[2] != '3' || p[3] != '\0'      \
+       || __builtin_strlen (p) != 3                                    \
+       || __builtin_strlen (q) != 3)                                   \
+      __builtin_abort ();                                              \
+                                                                       \
+    sink (p, q);                                                       \
+  } while (0)
+
+
+void alloca_test_local (unsigned n)
+{
+  char loca[] = "123";
+  T (loca, alloca (n));
+}
+
+void alloca_test_extern_const (unsigned n)
+{
+  T (exta, alloca (n));
+}
+
+void alloca_test_static (unsigned n)
+{
+  T (stata, alloca (n));
+}
+
+
+// Verify fix for PR tree-optimization/92412.
+void calloc_test_local (unsigned m, unsigned n)
+{
+  char loca[] = "123";
+  T (loca, calloc (m, n));
+}
+
+void calloc_test_extern_const (unsigned m, unsigned n)
+{
+  T (exta, calloc (m, n));
+}
+
+void calloc_test_static (unsigned m, unsigned n)
+{
+  T (stata, calloc (m, n));
+}
+
+
+// Verify fix for PR tree-optimization/92412.
+void malloc_test_local (unsigned n)
+{
+  char loca[] = "123";
+  T (loca, malloc (n));
+}
+
+void malloc_test_extern_const (unsigned n)
+{
+  T (exta, malloc (n));
+}
+
+void malloc_test_static (unsigned n)
+{
+  T (stata, malloc (n));
+}
+
+
+#undef T
+#define T(ptr, n) do {                                                 \
+    const char *p = ptr;                                               \
+    if (p[0] != '1' || p[1] != '2' || p[2] != '3' || p[3] != '\0'      \
+       || __builtin_strlen (p) != 3)                                   \
+      return;                                                          \
+                                                                       \
+    char vla[n];                                                       \
+    char *q = vla;                                                     \
+    __builtin_strcpy (q, p);                                           \
+                                                                       \
+    if (p[0] != '1' || p[1] != '2' || p[2] != '3' || p[3] != '\0'      \
+       || __builtin_strlen (p) != 3                                    \
+       || __builtin_strlen (q) != 3)                                   \
+      __builtin_abort ();                                              \
+                                                                       \
+    sink (p, vla);                                                     \
+  } while (0)
+
+
+void vla_test_local (unsigned n)
+{
+  char loca[] = "123";
+  T (loca, n);
+}
+
+void vla_test_extern_const (unsigned n)
+{
+  T (exta, n);
+}
+
+void vla_test_static (unsigned n)
+{
+  T (stata, n);
+}
+
+/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */