alias.c (record_component_aliases): Do not simplify pointed-to types of ODR types
authorJan Hubicka <hubicka@ucw.cz>
Wed, 17 Jul 2019 17:19:21 +0000 (19:19 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 17 Jul 2019 17:19:21 +0000 (17:19 +0000)
* alias.c (record_component_aliases): Do not simplify pointed-to
types of ODR types
* testsuite/g++.dg/lto/alias-4_0.C

From-SVN: r273552

gcc/ChangeLog
gcc/alias.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lto/alias-4_0.C [new file with mode: 0644]

index 5c69a63c18a6a097126a8ac23eb9d054a25f6418..26c647f3f46e02a3b5c09d19996e8efdf2789e47 100644 (file)
@@ -1,3 +1,8 @@
+2019-07-17  Jan Hubicka  <hubicka@ucw.cz>
+
+       * alias.c (record_component_aliases): Do not simplify pointed-to
+       types of ODR types 
+
 2019-07-17  Uroš Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.md (*andqi_2_maybe_si): Handle potential
index eece84ae2442dfd5a2267de591a7bd316f2d33cd..2755df729070a8b90743f1a4ae74d86b3cc76cc1 100644 (file)
@@ -1202,47 +1202,52 @@ record_component_aliases (tree type)
     case RECORD_TYPE:
     case UNION_TYPE:
     case QUAL_UNION_TYPE:
-      for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field))
-       if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field))
-         {
-           /* LTO type merging does not make any difference between 
-              component pointer types.  We may have
-
-              struct foo {int *a;};
-
-              as TYPE_CANONICAL of 
-
-              struct bar {float *a;};
-
-              Because accesses to int * and float * do not alias, we would get
-              false negative when accessing the same memory location by
-              float ** and bar *. We thus record the canonical type as:
-
-              struct {void *a;};
-
-              void * is special cased and works as a universal pointer type.
-              Accesses to it conflicts with accesses to any other pointer
-              type.  */
-           tree t = TREE_TYPE (field);
-           if (in_lto_p)
-             {
-               /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
-                  element type and that type has to be normalized to void *,
-                  too, in the case it is a pointer. */
-               while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
-                 {
-                   gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
-                   t = TREE_TYPE (t);
-                 }
-               if (POINTER_TYPE_P (t))
-                 t = ptr_type_node;
-               else if (flag_checking)
-                 gcc_checking_assert (get_alias_set (t)
-                                      == get_alias_set (TREE_TYPE (field)));
-             }
-
-           record_alias_subset (superset, get_alias_set (t));
-         }
+      {
+       /* LTO non-ODR type merging does not make any difference between 
+          component pointer types.  We may have
+
+          struct foo {int *a;};
+
+          as TYPE_CANONICAL of 
+
+          struct bar {float *a;};
+
+          Because accesses to int * and float * do not alias, we would get
+          false negative when accessing the same memory location by
+          float ** and bar *. We thus record the canonical type as:
+
+          struct {void *a;};
+
+          void * is special cased and works as a universal pointer type.
+          Accesses to it conflicts with accesses to any other pointer
+          type.  */
+       bool void_pointers = in_lto_p
+                            && (!odr_type_p (type)
+                                || !odr_based_tbaa_p (type));
+       for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field))
+         if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field))
+           {
+             tree t = TREE_TYPE (field);
+             if (void_pointers)
+               {
+                 /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
+                    element type and that type has to be normalized to void *,
+                    too, in the case it is a pointer. */
+                 while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
+                   {
+                     gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
+                     t = TREE_TYPE (t);
+                   }
+                 if (POINTER_TYPE_P (t))
+                   t = ptr_type_node;
+                 else if (flag_checking)
+                   gcc_checking_assert (get_alias_set (t)
+                                        == get_alias_set (TREE_TYPE (field)));
+               }
+
+             record_alias_subset (superset, get_alias_set (t));
+           }
+      }
       break;
 
     case COMPLEX_TYPE:
index 2d7a6bfc6541f1848085e5e3a1af5668ccf5cdd9..d3d710796b8ff7590ece5c979469e3d2deab7125 100644 (file)
@@ -1,3 +1,7 @@
+2019-07-17  Jan Hubicka  <hubicka@ucw.cz>
+
+       * g++.dg/lto/alias-4_0.C
+
 2019-07-17  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/91178
diff --git a/gcc/testsuite/g++.dg/lto/alias-4_0.C b/gcc/testsuite/g++.dg/lto/alias-4_0.C
new file mode 100644 (file)
index 0000000..410c314
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { { -O3 -flto -fno-early-inlining } } } */
+__attribute__ ((used))
+short *ptr_init, **ptr=&ptr_init;
+
+__attribute__ ((used))
+struct a {
+  int *aptr;
+} a, *aptr=&a;
+
+void
+write_ptr ()
+{
+  *aptr = a;
+}
+
+__attribute__ ((used))
+void
+test ()
+{
+  *ptr = (short int *)0;
+  write_ptr ();
+  if (!__builtin_constant_p (*ptr == (void *)0))
+    __builtin_abort ();
+}
+int
+main()
+{
+  test ();
+  return 0;
+}