public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Fix verify_type ICE during Ada bootstrap
@ 2015-11-24  8:25 Jan Hubicka
  2015-11-24  9:00 ` Richard Biener
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Hubicka @ 2015-11-24  8:25 UTC (permalink / raw)
  To: gcc-patches, rguenther

Hi,
this patch fixes verify_type ICE while building Ada.  The problem is that
we end up with INTEGER_TYPE that has TYPE_ALIAS_SET buts its main variant
is integer_type_node that is built in LTO and has non-zero alias set.

This is will lead to wrong code if function using integer built with
-fno-strit-aliasing gets inlined, but I am not fixing this (dunno how).

This patch merely disables streaming of TYPE_ALIAS_SET==0 for non-main
variants, because it is consistently ignored by get_alias_set anyway and adds
corresponding testing. I also took liberty to optimize
pack_ts_type_common_value_fields by ordering the constant flags first and
turning TYPE_ALIAS_SET streaming to a bit instead of var_len_int that is either
0 or -1.

I suppose -fno-strict-aliasing can be saved only by making all TYPE_ALIAS_SET==0
types variant and making get_alias_set honor it. When mixing -fstrict-aliasing
and -fno-strict-aliasing we will have different type variants on each code
which will stick. THe canonical type machinery then can preffer the non-0
variant.

This seems like a deeper change - at least I do not see how to make prestreamed
types to work with this sense easily. Another variant would be to put the info
directly to MEM_REF that is probably better and easier and drop forcing
TYPE_ALIAS_SET==0. Then however we will need to wrap all memory accesses into
MEM_REF, even non-LTO.

Bootstrapped/regtested x86_64-linux with and without LTO including ada.
Requires the earlier VECTOR_TYPE change to pass cleanly testsuite, otherwise it
fails on 2 vectorizer testcases.

OK?

Honza
	* alias.c (get_alias_set): Before checking TYPE_ALIAS_SET_KNOWN_P
	double check that type is main variant.
	* tree.c (build_variant_type_copy): Clear TYPE_ALIAS_SET when producing
	variant.
	(verify_type_variant): Verify that variants have no
	TYPE_ALIAS_SET_KNOWN_P set
	* tree-streamer-out.c (pack_ts_type_common_value_fields): Reorder
	streaming so constant fields come first; stream TYPE_ALIAS_SET==0
	only for main variants; stream TYPE_ALIAS_SET as a bit.
	* tree-streamer-in.c (unpack_ts_type_common_value_fields): Update
	accordingly.
Index: alias.c
===================================================================
--- alias.c	(revision 230783)
+++ alias.c	(working copy)
@@ -888,6 +888,7 @@ get_alias_set (tree t)
     }
 
   /* If this is a type with a known alias set, return it.  */
+  gcc_checking_assert (t == TYPE_MAIN_VARIANT (t));
   if (TYPE_ALIAS_SET_KNOWN_P (t))
     return TYPE_ALIAS_SET (t);
 
@@ -1025,6 +1026,7 @@ get_alias_set (tree t)
 	     We can not call get_alias_set (p) here as that would trigger
 	     infinite recursion when p == t.  In other cases it would just
 	     trigger unnecesary legwork of rebuilding the pointer again.  */
+	  gcc_checking_assert (p == TYPE_MAIN_VARIANT (p));
 	  if (TYPE_ALIAS_SET_KNOWN_P (p))
 	    set = TYPE_ALIAS_SET (p);
 	  else
Index: tree.c
===================================================================
--- tree.c	(revision 230783)
+++ tree.c	(working copy)
@@ -6706,6 +6706,7 @@ build_variant_type_copy (tree type)
   /* Since we're building a variant, assume that it is a non-semantic
      variant. This also propagates TYPE_STRUCTURAL_EQUALITY_P. */
   TYPE_CANONICAL (t) = TYPE_CANONICAL (type);
+  /* Type variants have no alias set defined.  */
+  TYPE_ALIAS_SET (t) = -1;
 
   /* Add the new type to the chain of variants of TYPE.  */
   TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
@@ -13056,8 +13058,12 @@ verify_type_variant (const_tree t, tree
   if ((!in_lto_p || !TYPE_FILE_SCOPE_P (t)) && 0)
     verify_variant_match (TYPE_CONTEXT);
   verify_variant_match (TYPE_STRING_FLAG);
-  if (TYPE_ALIAS_SET_KNOWN_P (t) && TYPE_ALIAS_SET_KNOWN_P (tv))
-    verify_variant_match (TYPE_ALIAS_SET);
+  if (TYPE_ALIAS_SET_KNOWN_P (t))
+    {
+      error ("type variant with TYPE_ALIAS_SET_KNOWN_P");
+      return false;
+    }
 
   /* tree_type_non_common checks.  */
 
Index: tree-streamer-out.c
===================================================================
--- tree-streamer-out.c	(revision 230783)
+++ tree-streamer-out.c	(working copy)
@@ -313,6 +313,17 @@ pack_ts_type_common_value_fields (struct
   /* TYPE_NO_FORCE_BLK is private to stor-layout and need
      no streaming.  */
   bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING (expr), 1);
+  bp_pack_value (bp, TYPE_PACKED (expr), 1);
+  bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
+  bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
+  bp_pack_value (bp, TYPE_READONLY (expr), 1);
+  /* Make sure to preserve the fact whether the frontend would assign
+     alias-set zero to this type.  Do that only for main variants, because
+     type variants alias sets are never computed.
+     FIXME:  This does not work for pre-streamed builtin types.  */
+  bp_pack_value (bp, (TYPE_ALIAS_SET (expr) == 0
+		      || (!in_lto_p && TYPE_MAIN_VARIANT (expr) == expr
+			  && get_alias_set (expr) == 0)), 1);
   if (RECORD_OR_UNION_TYPE_P (expr))
     {
       bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
@@ -320,17 +331,8 @@ pack_ts_type_common_value_fields (struct
     }
   else if (TREE_CODE (expr) == ARRAY_TYPE)
     bp_pack_value (bp, TYPE_NONALIASED_COMPONENT (expr), 1);
-  bp_pack_value (bp, TYPE_PACKED (expr), 1);
-  bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
-  bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
-  bp_pack_value (bp, TYPE_READONLY (expr), 1);
   bp_pack_var_len_unsigned (bp, TYPE_PRECISION (expr));
   bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
-  /* Make sure to preserve the fact whether the frontend would assign
-     alias-set zero to this type.  */
-  bp_pack_var_len_int (bp, (TYPE_ALIAS_SET (expr) == 0
-			    || (!in_lto_p
-				&& get_alias_set (expr) == 0)) ? 0 : -1);
 }
 
 
Index: tree-streamer-in.c
===================================================================
--- tree-streamer-in.c	(revision 230783)
+++ tree-streamer-in.c	(working copy)
@@ -362,6 +362,11 @@ unpack_ts_type_common_value_fields (stru
   /* TYPE_NO_FORCE_BLK is private to stor-layout and need
      no streaming.  */
   TYPE_NEEDS_CONSTRUCTING (expr) = (unsigned) bp_unpack_value (bp, 1);
+  TYPE_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1);
+  TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
+  TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
+  TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);
+  TYPE_ALIAS_SET (expr) = bp_unpack_value (bp, 1) ? 0 : -1;
   if (RECORD_OR_UNION_TYPE_P (expr))
     {
       TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
@@ -369,17 +374,12 @@ unpack_ts_type_common_value_fields (stru
     }
   else if (TREE_CODE (expr) == ARRAY_TYPE)
     TYPE_NONALIASED_COMPONENT (expr) = (unsigned) bp_unpack_value (bp, 1);
-  TYPE_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1);
-  TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
-  TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
-  TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_PRECISION (expr) = bp_unpack_var_len_unsigned (bp);
   TYPE_ALIGN (expr) = bp_unpack_var_len_unsigned (bp);
 #ifdef ACCEL_COMPILER
   if (TYPE_ALIGN (expr) > targetm.absolute_biggest_alignment)
     TYPE_ALIGN (expr) = targetm.absolute_biggest_alignment;
 #endif
-  TYPE_ALIAS_SET (expr) = bp_unpack_var_len_int (bp);
 }
 
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix verify_type ICE during Ada bootstrap
  2015-11-24  8:25 Fix verify_type ICE during Ada bootstrap Jan Hubicka
@ 2015-11-24  9:00 ` Richard Biener
  2015-11-24 18:55   ` Jan Hubicka
  0 siblings, 1 reply; 11+ messages in thread
From: Richard Biener @ 2015-11-24  9:00 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

On Tue, 24 Nov 2015, Jan Hubicka wrote:

> Hi,
> this patch fixes verify_type ICE while building Ada.  The problem is that
> we end up with INTEGER_TYPE that has TYPE_ALIAS_SET buts its main variant
> is integer_type_node that is built in LTO and has non-zero alias set.
> 
> This is will lead to wrong code if function using integer built with
> -fno-strit-aliasing gets inlined, but I am not fixing this (dunno how).

Yeah, the usual issues with the pre-streamed nodes :/  (also for builtins
which may vary with flags like -ffast-math)

Note that even with non-LTO using 
attribute((optimize("no-strict-aliasing"))) has the same issue.  We might
need to say that inlining no-strict-aliasing into strict-aliasing code
is wrong.

Index: gcc/ipa-inline.c
===================================================================
--- gcc/ipa-inline.c    (revision 230737)
+++ gcc/ipa-inline.c    (working copy)
@@ -410,7 +410,8 @@ can_inline_edge_p (struct cgraph_edge *e
         Not even for always_inline declared functions.  */
       /* Strictly speaking only when the callee contains signed integer
          math where overflow is undefined.  */
-     else if ((check_maybe_up (flag_strict_overflow)
+     else if (((check_maybe_up (flag_strict_overflow)
+               || check_maybe_down (flag_strict_aliasing))
               /* this flag is set by optimize.  Allow inlining across
                  optimize boundary.  */
               && (!opt_for_fn (caller->decl, optimize)

maybe you can check the effect of this.

> This patch merely disables streaming of TYPE_ALIAS_SET==0 for non-main
> variants, because it is consistently ignored by get_alias_set anyway and adds
> corresponding testing. I also took liberty to optimize
> pack_ts_type_common_value_fields by ordering the constant flags first and
> turning TYPE_ALIAS_SET streaming to a bit instead of var_len_int that is either
> 0 or -1.
> 
> I suppose -fno-strict-aliasing can be saved only by making all TYPE_ALIAS_SET==0
> types variant and making get_alias_set honor it. When mixing -fstrict-aliasing
> and -fno-strict-aliasing we will have different type variants on each code
> which will stick. THe canonical type machinery then can preffer the non-0
> variant.

Well, as we'll keep different main varinants and variants for the
strict-aliasing vs. the no-strict-aliasing case we simply need to make
sure to not look at TYPE_CANONICAL before testing TYPE_ALIAS_SET_KNOWN_P
on the main variant.  The special-handling relies on that being the
case and the alias-set being zero for all used types.

> This seems like a deeper change - at least I do not see how to make 
> prestreamed types to work with this sense easily. Another variant would 
> be to put the info directly to MEM_REF that is probably better and 
> easier and drop forcing TYPE_ALIAS_SET==0. Then however we will need to 
> wrap all memory accesses into MEM_REF, even non-LTO.

We do already wrap all bases into MEM_REFs at streaming time, it would
be easy to adjust it to make it effectively alias-set zero.  But of
course the overhead and the downstream effects of having more MEM_REFs
(we strip the unneeded ones at stream-in) are unknown (compared to
the effect of disabling inlining).

The prestreamed types should work for all function bodies with
optimize(no-strict-aliasing) via the flag_no_strict_aliasing check
in get_alias_set.

> Bootstrapped/regtested x86_64-linux with and without LTO including ada.
> Requires the earlier VECTOR_TYPE change to pass cleanly testsuite, otherwise it
> fails on 2 vectorizer testcases.
> 
> OK?

Ok.

Thanks,
Richard.

> Honza
> 	* alias.c (get_alias_set): Before checking TYPE_ALIAS_SET_KNOWN_P
> 	double check that type is main variant.
> 	* tree.c (build_variant_type_copy): Clear TYPE_ALIAS_SET when producing
> 	variant.
> 	(verify_type_variant): Verify that variants have no
> 	TYPE_ALIAS_SET_KNOWN_P set
> 	* tree-streamer-out.c (pack_ts_type_common_value_fields): Reorder
> 	streaming so constant fields come first; stream TYPE_ALIAS_SET==0
> 	only for main variants; stream TYPE_ALIAS_SET as a bit.
> 	* tree-streamer-in.c (unpack_ts_type_common_value_fields): Update
> 	accordingly.
> Index: alias.c
> ===================================================================
> --- alias.c	(revision 230783)
> +++ alias.c	(working copy)
> @@ -888,6 +888,7 @@ get_alias_set (tree t)
>      }
>  
>    /* If this is a type with a known alias set, return it.  */
> +  gcc_checking_assert (t == TYPE_MAIN_VARIANT (t));
>    if (TYPE_ALIAS_SET_KNOWN_P (t))
>      return TYPE_ALIAS_SET (t);
>  
> @@ -1025,6 +1026,7 @@ get_alias_set (tree t)
>  	     We can not call get_alias_set (p) here as that would trigger
>  	     infinite recursion when p == t.  In other cases it would just
>  	     trigger unnecesary legwork of rebuilding the pointer again.  */
> +	  gcc_checking_assert (p == TYPE_MAIN_VARIANT (p));
>  	  if (TYPE_ALIAS_SET_KNOWN_P (p))
>  	    set = TYPE_ALIAS_SET (p);
>  	  else
> Index: tree.c
> ===================================================================
> --- tree.c	(revision 230783)
> +++ tree.c	(working copy)
> @@ -6706,6 +6706,7 @@ build_variant_type_copy (tree type)
>    /* Since we're building a variant, assume that it is a non-semantic
>       variant. This also propagates TYPE_STRUCTURAL_EQUALITY_P. */
>    TYPE_CANONICAL (t) = TYPE_CANONICAL (type);
> +  /* Type variants have no alias set defined.  */
> +  TYPE_ALIAS_SET (t) = -1;
>  
>    /* Add the new type to the chain of variants of TYPE.  */
>    TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
> @@ -13056,8 +13058,12 @@ verify_type_variant (const_tree t, tree
>    if ((!in_lto_p || !TYPE_FILE_SCOPE_P (t)) && 0)
>      verify_variant_match (TYPE_CONTEXT);
>    verify_variant_match (TYPE_STRING_FLAG);
> -  if (TYPE_ALIAS_SET_KNOWN_P (t) && TYPE_ALIAS_SET_KNOWN_P (tv))
> -    verify_variant_match (TYPE_ALIAS_SET);
> +  if (TYPE_ALIAS_SET_KNOWN_P (t))
> +    {
> +      error ("type variant with TYPE_ALIAS_SET_KNOWN_P");
> +      return false;
> +    }
>  
>    /* tree_type_non_common checks.  */
>  
> Index: tree-streamer-out.c
> ===================================================================
> --- tree-streamer-out.c	(revision 230783)
> +++ tree-streamer-out.c	(working copy)
> @@ -313,6 +313,17 @@ pack_ts_type_common_value_fields (struct
>    /* TYPE_NO_FORCE_BLK is private to stor-layout and need
>       no streaming.  */
>    bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING (expr), 1);
> +  bp_pack_value (bp, TYPE_PACKED (expr), 1);
> +  bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
> +  bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
> +  bp_pack_value (bp, TYPE_READONLY (expr), 1);
> +  /* Make sure to preserve the fact whether the frontend would assign
> +     alias-set zero to this type.  Do that only for main variants, because
> +     type variants alias sets are never computed.
> +     FIXME:  This does not work for pre-streamed builtin types.  */
> +  bp_pack_value (bp, (TYPE_ALIAS_SET (expr) == 0
> +		      || (!in_lto_p && TYPE_MAIN_VARIANT (expr) == expr
> +			  && get_alias_set (expr) == 0)), 1);
>    if (RECORD_OR_UNION_TYPE_P (expr))
>      {
>        bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
> @@ -320,17 +331,8 @@ pack_ts_type_common_value_fields (struct
>      }
>    else if (TREE_CODE (expr) == ARRAY_TYPE)
>      bp_pack_value (bp, TYPE_NONALIASED_COMPONENT (expr), 1);
> -  bp_pack_value (bp, TYPE_PACKED (expr), 1);
> -  bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
> -  bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
> -  bp_pack_value (bp, TYPE_READONLY (expr), 1);
>    bp_pack_var_len_unsigned (bp, TYPE_PRECISION (expr));
>    bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
> -  /* Make sure to preserve the fact whether the frontend would assign
> -     alias-set zero to this type.  */
> -  bp_pack_var_len_int (bp, (TYPE_ALIAS_SET (expr) == 0
> -			    || (!in_lto_p
> -				&& get_alias_set (expr) == 0)) ? 0 : -1);
>  }
>  
>  
> Index: tree-streamer-in.c
> ===================================================================
> --- tree-streamer-in.c	(revision 230783)
> +++ tree-streamer-in.c	(working copy)
> @@ -362,6 +362,11 @@ unpack_ts_type_common_value_fields (stru
>    /* TYPE_NO_FORCE_BLK is private to stor-layout and need
>       no streaming.  */
>    TYPE_NEEDS_CONSTRUCTING (expr) = (unsigned) bp_unpack_value (bp, 1);
> +  TYPE_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1);
> +  TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
> +  TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
> +  TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);
> +  TYPE_ALIAS_SET (expr) = bp_unpack_value (bp, 1) ? 0 : -1;
>    if (RECORD_OR_UNION_TYPE_P (expr))
>      {
>        TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
> @@ -369,17 +374,12 @@ unpack_ts_type_common_value_fields (stru
>      }
>    else if (TREE_CODE (expr) == ARRAY_TYPE)
>      TYPE_NONALIASED_COMPONENT (expr) = (unsigned) bp_unpack_value (bp, 1);
> -  TYPE_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1);
> -  TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
> -  TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
> -  TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);
>    TYPE_PRECISION (expr) = bp_unpack_var_len_unsigned (bp);
>    TYPE_ALIGN (expr) = bp_unpack_var_len_unsigned (bp);
>  #ifdef ACCEL_COMPILER
>    if (TYPE_ALIGN (expr) > targetm.absolute_biggest_alignment)
>      TYPE_ALIGN (expr) = targetm.absolute_biggest_alignment;
>  #endif
> -  TYPE_ALIAS_SET (expr) = bp_unpack_var_len_int (bp);
>  }
>  
>  
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix verify_type ICE during Ada bootstrap
  2015-11-24  9:00 ` Richard Biener
@ 2015-11-24 18:55   ` Jan Hubicka
  2015-11-24 19:45     ` Jan Hubicka
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Hubicka @ 2015-11-24 18:55 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jan Hubicka, gcc-patches

> On Tue, 24 Nov 2015, Jan Hubicka wrote:
> 
> > Hi,
> > this patch fixes verify_type ICE while building Ada.  The problem is that
> > we end up with INTEGER_TYPE that has TYPE_ALIAS_SET buts its main variant
> > is integer_type_node that is built in LTO and has non-zero alias set.
> > 
> > This is will lead to wrong code if function using integer built with
> > -fno-strit-aliasing gets inlined, but I am not fixing this (dunno how).
> 
> Yeah, the usual issues with the pre-streamed nodes :/  (also for builtins
> which may vary with flags like -ffast-math)
> 
> Note that even with non-LTO using 
> attribute((optimize("no-strict-aliasing"))) has the same issue.  We might
> need to say that inlining no-strict-aliasing into strict-aliasing code
> is wrong.

Yeah, we may just rule out strict aliasing from optimization attribute if
we don't find better solution, becuase it is better than doing false promises.

However I hope we could do better...
> 
> Index: gcc/ipa-inline.c
> ===================================================================
> --- gcc/ipa-inline.c    (revision 230737)
> +++ gcc/ipa-inline.c    (working copy)
> @@ -410,7 +410,8 @@ can_inline_edge_p (struct cgraph_edge *e
>          Not even for always_inline declared functions.  */
>        /* Strictly speaking only when the callee contains signed integer
>           math where overflow is undefined.  */
> -     else if ((check_maybe_up (flag_strict_overflow)
> +     else if (((check_maybe_up (flag_strict_overflow)
> +               || check_maybe_down (flag_strict_aliasing))
>                /* this flag is set by optimize.  Allow inlining across
>                   optimize boundary.  */
>                && (!opt_for_fn (caller->decl, optimize)
> 
> maybe you can check the effect of this.

Sadly this has really bad effect on Firefox - here majority of code is built
with -fno-strict-aliasing and the benchmark sensitive part is -fstrict-aliasing.
Because we merge comdat inlines, we end up with non-strict-aliasing variants and
doing so prevents a lot of important inlining.

I know this from previous stage3 when we had this change and reverted it.
> 
> > This patch merely disables streaming of TYPE_ALIAS_SET==0 for non-main
> > variants, because it is consistently ignored by get_alias_set anyway and adds
> > corresponding testing. I also took liberty to optimize
> > pack_ts_type_common_value_fields by ordering the constant flags first and
> > turning TYPE_ALIAS_SET streaming to a bit instead of var_len_int that is either
> > 0 or -1.
> > 
> > I suppose -fno-strict-aliasing can be saved only by making all TYPE_ALIAS_SET==0
> > types variant and making get_alias_set honor it. When mixing -fstrict-aliasing
> > and -fno-strict-aliasing we will have different type variants on each code
> > which will stick. THe canonical type machinery then can preffer the non-0
> > variant.
> 
> Well, as we'll keep different main varinants and variants for the
> strict-aliasing vs. the no-strict-aliasing case we simply need to make
> sure to not look at TYPE_CANONICAL before testing TYPE_ALIAS_SET_KNOWN_P
> on the main variant.  The special-handling relies on that being the
> case and the alias-set being zero for all used types.

Yeah, that was what I had in mind.
> 
> > This seems like a deeper change - at least I do not see how to make 
> > prestreamed types to work with this sense easily. Another variant would 
> > be to put the info directly to MEM_REF that is probably better and 
> > easier and drop forcing TYPE_ALIAS_SET==0. Then however we will need to 
> > wrap all memory accesses into MEM_REF, even non-LTO.
> 
> We do already wrap all bases into MEM_REFs at streaming time, it would
> be easy to adjust it to make it effectively alias-set zero.  But of
> course the overhead and the downstream effects of having more MEM_REFs
> (we strip the unneeded ones at stream-in) are unknown (compared to
> the effect of disabling inlining).

Hmm, I can test in on Firefox (once I get it back to working condition).

An alternative I was thinking about was to keep duplicated bodies in the
callgraph for inlines that may get impossible after declmerging.  That
also needs works and the consequences on code size estimates and overall
binary size are bit hard to guess.

This may be good solution for the overall problem of mixing flags, but
my gut feeling is that we probably win most score by doing the memrefs.
> 
> The prestreamed types should work for all function bodies with
> optimize(no-strict-aliasing) via the flag_no_strict_aliasing check
> in get_alias_set.

Yeah, except for inlining that is important in this case and moreover
there is oposite problem too. When we stream in -fno-strict-aliasing code
first, we end up with types in alias set 0 as canonical types that leads
to bad TBAA, too.
> 
> > Bootstrapped/regtested x86_64-linux with and without LTO including ada.
> > Requires the earlier VECTOR_TYPE change to pass cleanly testsuite, otherwise it
> > fails on 2 vectorizer testcases.
> > 
> > OK?
> 
> Ok.
Thanks.

Honza
> 
> Thanks,
> Richard.
> 
> > Honza
> > 	* alias.c (get_alias_set): Before checking TYPE_ALIAS_SET_KNOWN_P
> > 	double check that type is main variant.
> > 	* tree.c (build_variant_type_copy): Clear TYPE_ALIAS_SET when producing
> > 	variant.
> > 	(verify_type_variant): Verify that variants have no
> > 	TYPE_ALIAS_SET_KNOWN_P set
> > 	* tree-streamer-out.c (pack_ts_type_common_value_fields): Reorder
> > 	streaming so constant fields come first; stream TYPE_ALIAS_SET==0
> > 	only for main variants; stream TYPE_ALIAS_SET as a bit.
> > 	* tree-streamer-in.c (unpack_ts_type_common_value_fields): Update
> > 	accordingly.
> > Index: alias.c
> > ===================================================================
> > --- alias.c	(revision 230783)
> > +++ alias.c	(working copy)
> > @@ -888,6 +888,7 @@ get_alias_set (tree t)
> >      }
> >  
> >    /* If this is a type with a known alias set, return it.  */
> > +  gcc_checking_assert (t == TYPE_MAIN_VARIANT (t));
> >    if (TYPE_ALIAS_SET_KNOWN_P (t))
> >      return TYPE_ALIAS_SET (t);
> >  
> > @@ -1025,6 +1026,7 @@ get_alias_set (tree t)
> >  	     We can not call get_alias_set (p) here as that would trigger
> >  	     infinite recursion when p == t.  In other cases it would just
> >  	     trigger unnecesary legwork of rebuilding the pointer again.  */
> > +	  gcc_checking_assert (p == TYPE_MAIN_VARIANT (p));
> >  	  if (TYPE_ALIAS_SET_KNOWN_P (p))
> >  	    set = TYPE_ALIAS_SET (p);
> >  	  else
> > Index: tree.c
> > ===================================================================
> > --- tree.c	(revision 230783)
> > +++ tree.c	(working copy)
> > @@ -6706,6 +6706,7 @@ build_variant_type_copy (tree type)
> >    /* Since we're building a variant, assume that it is a non-semantic
> >       variant. This also propagates TYPE_STRUCTURAL_EQUALITY_P. */
> >    TYPE_CANONICAL (t) = TYPE_CANONICAL (type);
> > +  /* Type variants have no alias set defined.  */
> > +  TYPE_ALIAS_SET (t) = -1;
> >  
> >    /* Add the new type to the chain of variants of TYPE.  */
> >    TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
> > @@ -13056,8 +13058,12 @@ verify_type_variant (const_tree t, tree
> >    if ((!in_lto_p || !TYPE_FILE_SCOPE_P (t)) && 0)
> >      verify_variant_match (TYPE_CONTEXT);
> >    verify_variant_match (TYPE_STRING_FLAG);
> > -  if (TYPE_ALIAS_SET_KNOWN_P (t) && TYPE_ALIAS_SET_KNOWN_P (tv))
> > -    verify_variant_match (TYPE_ALIAS_SET);
> > +  if (TYPE_ALIAS_SET_KNOWN_P (t))
> > +    {
> > +      error ("type variant with TYPE_ALIAS_SET_KNOWN_P");
> > +      return false;
> > +    }
> >  
> >    /* tree_type_non_common checks.  */
> >  
> > Index: tree-streamer-out.c
> > ===================================================================
> > --- tree-streamer-out.c	(revision 230783)
> > +++ tree-streamer-out.c	(working copy)
> > @@ -313,6 +313,17 @@ pack_ts_type_common_value_fields (struct
> >    /* TYPE_NO_FORCE_BLK is private to stor-layout and need
> >       no streaming.  */
> >    bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING (expr), 1);
> > +  bp_pack_value (bp, TYPE_PACKED (expr), 1);
> > +  bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
> > +  bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
> > +  bp_pack_value (bp, TYPE_READONLY (expr), 1);
> > +  /* Make sure to preserve the fact whether the frontend would assign
> > +     alias-set zero to this type.  Do that only for main variants, because
> > +     type variants alias sets are never computed.
> > +     FIXME:  This does not work for pre-streamed builtin types.  */
> > +  bp_pack_value (bp, (TYPE_ALIAS_SET (expr) == 0
> > +		      || (!in_lto_p && TYPE_MAIN_VARIANT (expr) == expr
> > +			  && get_alias_set (expr) == 0)), 1);
> >    if (RECORD_OR_UNION_TYPE_P (expr))
> >      {
> >        bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
> > @@ -320,17 +331,8 @@ pack_ts_type_common_value_fields (struct
> >      }
> >    else if (TREE_CODE (expr) == ARRAY_TYPE)
> >      bp_pack_value (bp, TYPE_NONALIASED_COMPONENT (expr), 1);
> > -  bp_pack_value (bp, TYPE_PACKED (expr), 1);
> > -  bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
> > -  bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
> > -  bp_pack_value (bp, TYPE_READONLY (expr), 1);
> >    bp_pack_var_len_unsigned (bp, TYPE_PRECISION (expr));
> >    bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
> > -  /* Make sure to preserve the fact whether the frontend would assign
> > -     alias-set zero to this type.  */
> > -  bp_pack_var_len_int (bp, (TYPE_ALIAS_SET (expr) == 0
> > -			    || (!in_lto_p
> > -				&& get_alias_set (expr) == 0)) ? 0 : -1);
> >  }
> >  
> >  
> > Index: tree-streamer-in.c
> > ===================================================================
> > --- tree-streamer-in.c	(revision 230783)
> > +++ tree-streamer-in.c	(working copy)
> > @@ -362,6 +362,11 @@ unpack_ts_type_common_value_fields (stru
> >    /* TYPE_NO_FORCE_BLK is private to stor-layout and need
> >       no streaming.  */
> >    TYPE_NEEDS_CONSTRUCTING (expr) = (unsigned) bp_unpack_value (bp, 1);
> > +  TYPE_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1);
> > +  TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
> > +  TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
> > +  TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);
> > +  TYPE_ALIAS_SET (expr) = bp_unpack_value (bp, 1) ? 0 : -1;
> >    if (RECORD_OR_UNION_TYPE_P (expr))
> >      {
> >        TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
> > @@ -369,17 +374,12 @@ unpack_ts_type_common_value_fields (stru
> >      }
> >    else if (TREE_CODE (expr) == ARRAY_TYPE)
> >      TYPE_NONALIASED_COMPONENT (expr) = (unsigned) bp_unpack_value (bp, 1);
> > -  TYPE_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1);
> > -  TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
> > -  TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
> > -  TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);
> >    TYPE_PRECISION (expr) = bp_unpack_var_len_unsigned (bp);
> >    TYPE_ALIGN (expr) = bp_unpack_var_len_unsigned (bp);
> >  #ifdef ACCEL_COMPILER
> >    if (TYPE_ALIGN (expr) > targetm.absolute_biggest_alignment)
> >      TYPE_ALIGN (expr) = targetm.absolute_biggest_alignment;
> >  #endif
> > -  TYPE_ALIAS_SET (expr) = bp_unpack_var_len_int (bp);
> >  }
> >  
> >  
> > 
> > 
> 
> -- 
> Richard Biener <rguenther@suse.de>
> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix verify_type ICE during Ada bootstrap
  2015-11-24 18:55   ` Jan Hubicka
@ 2015-11-24 19:45     ` Jan Hubicka
  2015-11-25 10:55       ` Richard Biener
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Hubicka @ 2015-11-24 19:45 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Biener, gcc-patches

> > 
> > We do already wrap all bases into MEM_REFs at streaming time, it would
> > be easy to adjust it to make it effectively alias-set zero.  But of
> > course the overhead and the downstream effects of having more MEM_REFs
> > (we strip the unneeded ones at stream-in) are unknown (compared to
> > the effect of disabling inlining).
> 
> Hmm, I can test in on Firefox (once I get it back to working condition).

One way would be to keep current MEM_REFS stripping and conditoinal in
get_alias_set on strict aliasing, but extend inliner to introduce them at a
point -fno-strict-aliasing is inlined to -fstrict-aliasing.  That way we could
drop the code in lto-streamer-out that forcingly set alias set to 0 when
get_alias_set == 0 and hopefully get all code transitions right.

Honza

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix verify_type ICE during Ada bootstrap
  2015-11-24 19:45     ` Jan Hubicka
@ 2015-11-25 10:55       ` Richard Biener
  2015-11-27  7:30         ` Jan Hubicka
  0 siblings, 1 reply; 11+ messages in thread
From: Richard Biener @ 2015-11-25 10:55 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

On Tue, 24 Nov 2015, Jan Hubicka wrote:

> > > 
> > > We do already wrap all bases into MEM_REFs at streaming time, it would
> > > be easy to adjust it to make it effectively alias-set zero.  But of
> > > course the overhead and the downstream effects of having more MEM_REFs
> > > (we strip the unneeded ones at stream-in) are unknown (compared to
> > > the effect of disabling inlining).
> > 
> > Hmm, I can test in on Firefox (once I get it back to working condition).
> 
> One way would be to keep current MEM_REFS stripping and conditoinal in
> get_alias_set on strict aliasing, but extend inliner to introduce them at a
> point -fno-strict-aliasing is inlined to -fstrict-aliasing.  That way we could
> drop the code in lto-streamer-out that forcingly set alias set to 0 when
> get_alias_set == 0 and hopefully get all code transitions right.

Yeah, that could also work.  We can also rewrite overflow stuff
this way to do overflow related inlining (in one direction only?).
That is, when inlining !strict-overflow into strict-overflow code
re-write arithmetic to unsigned during inlining.

Sth for next stage1.

Maybe you can open an enhancement PR for these cases.

Richard.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix verify_type ICE during Ada bootstrap
  2015-11-25 10:55       ` Richard Biener
@ 2015-11-27  7:30         ` Jan Hubicka
  2015-11-30  7:22           ` Jan Hubicka
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Hubicka @ 2015-11-27  7:30 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jan Hubicka, gcc-patches

> On Tue, 24 Nov 2015, Jan Hubicka wrote:
> 
> > > > 
> > > > We do already wrap all bases into MEM_REFs at streaming time, it would
> > > > be easy to adjust it to make it effectively alias-set zero.  But of
> > > > course the overhead and the downstream effects of having more MEM_REFs
> > > > (we strip the unneeded ones at stream-in) are unknown (compared to
> > > > the effect of disabling inlining).
> > > 
> > > Hmm, I can test in on Firefox (once I get it back to working condition).
> > 
> > One way would be to keep current MEM_REFS stripping and conditoinal in
> > get_alias_set on strict aliasing, but extend inliner to introduce them at a
> > point -fno-strict-aliasing is inlined to -fstrict-aliasing.  That way we could
> > drop the code in lto-streamer-out that forcingly set alias set to 0 when
> > get_alias_set == 0 and hopefully get all code transitions right.
> 
> Yeah, that could also work.  We can also rewrite overflow stuff
> this way to do overflow related inlining (in one direction only?).
> That is, when inlining !strict-overflow into strict-overflow code
> re-write arithmetic to unsigned during inlining.
> 
> Sth for next stage1.
> 
> Maybe you can open an enhancement PR for these cases.

I will certainly do.
sadly more I understand the implementation the easier I can consturct wrong
code examples (see testcases bellow).

I think the whole idea of storing TYPE_ALIAS_SET at streaming out time is not
working well. First of all it does not solve optimization attribute and second
we can randomly lose the info (on prestreamed type or types where canonical
type merging prevails with non-0 alias set type) or push random type to alias
set 0 (where canonical type merging prevail the oposite direction).  I do not
see how to easily fix it: canonical type merging can not make difference between
alias set 0 types and others unless we make it clear that the derived types
can not alias (which I think they can).  I suppose only way here would be to
force all alias set 0 types to be variant and revisit all the code to check
it before going to main vairant&canonical type.  Compared to that I like
the solution with flag in MEM_REF better, but that of course is an invasive
change where we will need to revisit all MEM_REF construction to set the
flag correctly.

I wonder what would you think of the following patch.  It basically makes
type representation to be completely agnostic of -fstrict-aliasing (it should
be because -fstrict-aliasing is function local property, while types are
not) and makes -fstrict-aliasing to be purely evaulated at a time we ask
TBAA oracle. I disabled the TYPE_ALIAS_SET streaming and instead I assert
that LTO's implementation will be compatible (which caught some surprises
where we tamper with alias set in rtti.c and free_lang_data)

I modifed inliner to make the -fstrict-aliasing infectious. That is instead of
forbidding the inlinng it simply drops the flags in caller. Moreover I play
the game with COMDATs and the fact that whenever you inline comdat w/o
explicit optimization attribute to caller w/o explicit optimization
attribute you may assume that the function body is valid under caller flags.
We already play this game in can_inline_p.  This means that no inlines are
blocked in firefox.

Of course it is always dodgy to change optimization flags after ealry
optimizations that may have made code previously valid wrt -fstrict-aliasing
invalid. I reviewed the 26 uses of -fstrict-aliasing in the compiler and it
seems that only ipa-icf and fold-const may result in such transform. So I
disabled them pre-inlining (which I think is good idea for time being until we
make -fstrict-aliasing part of MEM_REF: both transforms are far less important
than inlining). Once we update to MEM_REF we can easilu drop this.

The patch bootstraps/regtests x86_64-linux and seems to do decent job on
Firefox (actually increasing effectivity of TBAA, only 26 functions are demoted
to -fno-strict-aliasing because of the new code in ipa-inline-transform).  I
plan to do more testing tomorrow (I still can't build the firefox binary to do
some benchamrks).

Honza

	* ipa-inline-transform.c (inline_call): Merge -fno-strict-aliasing
	if needed.
	* ipa-icf-gimple.c (func_checker::compatible_types_p): Pass true
	to get_alias_set.
	* alias.c (get_alias_set): Add new strict flag.
	(new_alias_set): Always produce new set.
	(record_component_aliases): Pass true to get_alias_set.
	* alias.h (get_alias_set): New parameter STRICT which is false by
	default.
	* fold-const.c (operand_equal_p): Before inlining don not permit
	any transformations that would be invalid if code became strict-aliasing
	* tree-streamer-out.c
	 (pack_ts_type_common_value_fields): Do not stream TYPE_ALIAS_SET;
	sanity check that no alias set 0 info is lost.
	* tree-streamer-in.c (unpack_ts_type_common_value_fields): Do not
	stream in TYPE_ALIAS_SET.
	* tree.c (free_lang_data): Pass true to get_alias_set.

	* lto-symtab.c (warn_type_compatibility_p): Pass true to
	get_alias_set

	* c-common.c (parse_optimize_options): Remove ugly hack that makes
	strict-aliasing changes to be silently ignored.

	* gcc.dg/lto/alias-1_0.c: New testcase.
	* gcc.dg/lto/alias-1_1.c: New testcase.
	* gcc.c-torture/execute/alias-1.c: New testcase.
	
Index: ipa-inline-transform.c
===================================================================
--- ipa-inline-transform.c	(revision 230924)
+++ ipa-inline-transform.c	(working copy)
@@ -322,6 +322,23 @@ inline_call (struct cgraph_edge *e, bool
   if (DECL_FUNCTION_PERSONALITY (callee->decl))
     DECL_FUNCTION_PERSONALITY (to->decl)
       = DECL_FUNCTION_PERSONALITY (callee->decl);
+  if (!opt_for_fn (callee->decl, flag_strict_aliasing)
+      && opt_for_fn (to->decl, flag_strict_aliasing)
+      && (!callee->merged
+	  || lookup_attribute ("optimization", DECL_ATTRIBUTES (e->caller->decl))
+	  || lookup_attribute ("optimization", DECL_ATTRIBUTES (callee->decl))))
+    {
+      struct gcc_options opts = global_options;
+      cl_optimization_restore (&opts,
+	 TREE_OPTIMIZATION (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (to->decl)));
+      opts.x_flag_strict_aliasing = false;
+      if (dump_file)
+	fprintf (dump_file, "Dropping flag_strict_aliasing on %s:%i\n",
+		 to->name (), to->order);
+      build_optimization_node (&opts);
+      DECL_FUNCTION_SPECIFIC_OPTIMIZATION (to->decl)
+	 = build_optimization_node (&opts);
+    }
 
   /* If aliases are involved, redirect edge to the actual destination and
      possibly remove the aliases.  */
Index: ipa-icf-gimple.c
===================================================================
--- ipa-icf-gimple.c	(revision 230924)
+++ ipa-icf-gimple.c	(working copy)
@@ -241,7 +241,7 @@ func_checker::compatible_types_p (tree t
      For time being just avoid calling get_alias_set on types that are not
      having alias sets defined at all.  */
   if (type_with_alias_set_p (t1) && type_with_alias_set_p (t2)
-      && get_alias_set (t1) != get_alias_set (t2))
+      && get_alias_set (t1, true) != get_alias_set (t2, true))
     return return_false_with_msg ("alias sets are different");
 
   return true;
Index: alias.c
===================================================================
--- alias.c	(revision 230924)
+++ alias.c	(working copy)
@@ -809,17 +809,21 @@ init_alias_set_entry (alias_set_type set
 }
 
 /* Return the alias set for T, which may be either a type or an
-   expression.  Call language-specific routine for help, if needed.  */
+   expression.  Call language-specific routine for help, if needed.
+   If STRICT is true, ignore value of flag_strict_aliasing.  This is needed
+   in cases we are in -fno-strict-aliasing region but still need to compute
+   alias sets for some reason (this is used, for example, by rtti code to copy
+   alias set from type to type).  */
 
 alias_set_type
-get_alias_set (tree t)
+get_alias_set (tree t, bool strict)
 {
   alias_set_type set;
 
   /* If we're not doing any alias analysis, just assume everything
      aliases everything else.  Also return 0 if this or its type is
      an error.  */
-  if (! flag_strict_aliasing || t == error_mark_node
+  if ((! flag_strict_aliasing && !strict)|| t == error_mark_node
       || (! TYPE_P (t)
 	  && (TREE_TYPE (t) == 0 || TREE_TYPE (t) == error_mark_node)))
     return 0;
@@ -898,7 +902,7 @@ get_alias_set (tree t)
       /* For arrays with unknown size the conservative answer is the
 	 alias set of the element type.  */
       if (TREE_CODE (t) == ARRAY_TYPE)
-	return get_alias_set (TREE_TYPE (t));
+	return get_alias_set (TREE_TYPE (t), true);
 
       /* But return zero as a conservative answer for incomplete types.  */
       return 0;
@@ -920,7 +924,7 @@ get_alias_set (tree t)
      normal usage.  And indeed lets vectors be treated more like an
      array slice.  */
   else if (TREE_CODE (t) == VECTOR_TYPE)
-    set = get_alias_set (TREE_TYPE (t));
+    set = get_alias_set (TREE_TYPE (t), true);
 
   /* Unless the language specifies otherwise, treat array types the
      same as their components.  This avoids the asymmetry we get
@@ -933,7 +937,7 @@ get_alias_set (tree t)
   else if (TREE_CODE (t) == ARRAY_TYPE
 	   && (!TYPE_NONALIASED_COMPONENT (t)
 	       || TYPE_STRUCTURAL_EQUALITY_P (t)))
-    set = get_alias_set (TREE_TYPE (t));
+    set = get_alias_set (TREE_TYPE (t), true);
 
   /* From the former common C and C++ langhook implementation:
 
@@ -997,7 +1001,7 @@ get_alias_set (tree t)
 	 (see record_component_aliases) and thus it is safe it to use it for
 	 pointers to types with TYPE_STRUCTURAL_EQUALITY_P.  */
       if (TREE_CODE (p) == VOID_TYPE || TYPE_STRUCTURAL_EQUALITY_P (p))
-	set = get_alias_set (ptr_type_node);
+	set = get_alias_set (ptr_type_node, true);
       else
 	{
 	  /* Rebuild pointer type starting from canonical types using
@@ -1085,15 +1089,10 @@ get_alias_set (tree t)
 alias_set_type
 new_alias_set (void)
 {
-  if (flag_strict_aliasing)
-    {
-      if (alias_sets == 0)
-	vec_safe_push (alias_sets, (alias_set_entry *) NULL);
-      vec_safe_push (alias_sets, (alias_set_entry *) NULL);
-      return alias_sets->length () - 1;
-    }
-  else
-    return 0;
+  if (alias_sets == 0)
+    vec_safe_push (alias_sets, (alias_set_entry *) NULL);
+  vec_safe_push (alias_sets, (alias_set_entry *) NULL);
+  return alias_sets->length () - 1;
 }
 
 /* Indicate that things in SUBSET can alias things in SUPERSET, but that
@@ -1169,7 +1168,7 @@ record_alias_subset (alias_set_type supe
 void
 record_component_aliases (tree type)
 {
-  alias_set_type superset = get_alias_set (type);
+  alias_set_type superset = get_alias_set (type, true);
   tree field;
 
   if (superset == 0)
@@ -1215,16 +1214,17 @@ record_component_aliases (tree type)
 		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)));
+		  gcc_checking_assert (get_alias_set (t, true)
+				       == get_alias_set (TREE_TYPE (field),
+							 true));
 	      }
 
-	    record_alias_subset (superset, get_alias_set (t));
+	    record_alias_subset (superset, get_alias_set (t, true));
 	  }
       break;
 
     case COMPLEX_TYPE:
-      record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
+      record_alias_subset (superset, get_alias_set (TREE_TYPE (type), true));
       break;
 
     /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
Index: alias.h
===================================================================
--- alias.h	(revision 230924)
+++ alias.h	(working copy)
@@ -21,7 +21,7 @@ along with GCC; see the file COPYING3.
 #define GCC_ALIAS_H
 
 extern alias_set_type new_alias_set (void);
-extern alias_set_type get_alias_set (tree);
+extern alias_set_type get_alias_set (tree, bool strict = false);
 extern alias_set_type get_deref_alias_set (tree);
 extern alias_set_type get_varargs_alias_set (void);
 extern alias_set_type get_frame_alias_set (void);
Index: cp/rtti.c
===================================================================
--- cp/rtti.c	(revision 230924)
+++ cp/rtti.c	(working copy)
@@ -300,10 +300,10 @@ typeid_ok_p (void)
   /* Make sure abi::__type_info_pseudo has the same alias set
      as std::type_info.  */
   if (! TYPE_ALIAS_SET_KNOWN_P (pseudo_type_info))
-    TYPE_ALIAS_SET (pseudo_type_info) = get_alias_set (type_info_type);
+    TYPE_ALIAS_SET (pseudo_type_info) = get_alias_set (type_info_type, true);
   else
     gcc_assert (TYPE_ALIAS_SET (pseudo_type_info)
-		== get_alias_set (type_info_type));
+		== get_alias_set (type_info_type, true));
 
   return true;
 }
Index: fold-const.c
===================================================================
--- fold-const.c	(revision 230924)
+++ fold-const.c	(working copy)
@@ -2987,7 +2987,7 @@ operand_equal_p (const_tree arg0, const_
 					   flags)))
 		return 0;
 	      /* Verify that accesses are TBAA compatible.  */
-	      if (flag_strict_aliasing
+	      if ((flag_strict_aliasing || !cfun->after_inlining)
 		  && (!alias_ptr_types_compatible_p
 		        (TREE_TYPE (TREE_OPERAND (arg0, 1)),
 		         TREE_TYPE (TREE_OPERAND (arg1, 1)))
Index: lto/lto-symtab.c
===================================================================
--- lto/lto-symtab.c	(revision 230924)
+++ lto/lto-symtab.c	(working copy)
@@ -276,8 +276,8 @@ warn_type_compatibility_p (tree prevaili
      we make ptr_type_node to TBAA compatible with every other type.  */
   if (type_with_alias_set_p (type) && type_with_alias_set_p (prevailing_type))
     {
-      alias_set_type set1 = get_alias_set (type);
-      alias_set_type set2 = get_alias_set (prevailing_type);
+      alias_set_type set1 = get_alias_set (type, true);
+      alias_set_type set2 = get_alias_set (prevailing_type, true);
 
       if (set1 && set2 && set1 != set2 
           && (!POINTER_TYPE_P (type) || !POINTER_TYPE_P (prevailing_type)
Index: tree-streamer-out.c
===================================================================
--- tree-streamer-out.c	(revision 230924)
+++ tree-streamer-out.c	(working copy)
@@ -317,13 +319,18 @@ pack_ts_type_common_value_fields (struct
   bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
   bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
   bp_pack_value (bp, TYPE_READONLY (expr), 1);
-  /* Make sure to preserve the fact whether the frontend would assign
-     alias-set zero to this type.  Do that only for main variants, because
-     type variants alias sets are never computed.
-     FIXME:  This does not work for pre-streamed builtin types.  */
-  bp_pack_value (bp, (TYPE_ALIAS_SET (expr) == 0
-		      || (!in_lto_p && TYPE_MAIN_VARIANT (expr) == expr
-			  && get_alias_set (expr) == 0)), 1);
+  /* We used to stream TYPE_ALIAS_SET == 0 information to let frontends mark
+     types that are opaque for TBAA.  This however did not work as intended,
+     becuase TYPE_ALIAS_SET == 0 was regularly lost in type merging.
+
+     Instead now double check that all aliaset set 0 types will be alias set
+     0 in LTO world, too.  */
+  gcc_checking_assert (!type_with_alias_set_p (expr)
+		       || !canonical_type_used_p (expr)
+		       || TYPE_ALIAS_SET (expr) != 0
+		       || expr == char_type_node
+		       || expr == signed_char_type_node
+		       || expr == unsigned_char_type_node);
   if (RECORD_OR_UNION_TYPE_P (expr))
     {
       bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
Index: c-family/c-common.c
===================================================================
--- c-family/c-common.c	(revision 230924)
+++ c-family/c-common.c	(working copy)
@@ -9987,7 +9988,6 @@ parse_optimize_options (tree args, bool
   bool ret = true;
   unsigned opt_argc;
   unsigned i;
-  int saved_flag_strict_aliasing;
   const char **opt_argv;
   struct cl_decoded_option *decoded_options;
   unsigned int decoded_options_count;
@@ -10080,8 +10080,6 @@ parse_optimize_options (tree args, bool
   for (i = 1; i < opt_argc; i++)
     opt_argv[i] = (*optimize_args)[i];
 
-  saved_flag_strict_aliasing = flag_strict_aliasing;
-
   /* Now parse the options.  */
   decode_cmdline_options_to_array_default_mask (opt_argc, opt_argv,
 						&decoded_options,
@@ -10092,9 +10090,6 @@ parse_optimize_options (tree args, bool
 
   targetm.override_options_after_change();
 
-  /* Don't allow changing -fstrict-aliasing.  */
-  flag_strict_aliasing = saved_flag_strict_aliasing;
-
   optimize_args->truncate (0);
   return ret;
 }
Index: tree-streamer-in.c
===================================================================
--- tree-streamer-in.c	(revision 230924)
+++ tree-streamer-in.c	(working copy)
@@ -366,7 +366,6 @@ unpack_ts_type_common_value_fields (stru
   TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);
-  TYPE_ALIAS_SET (expr) = bp_unpack_value (bp, 1) ? 0 : -1;
   if (RECORD_OR_UNION_TYPE_P (expr))
     {
       TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
Index: testsuite/gcc.dg/lto/alias-1_0.c
===================================================================
--- testsuite/gcc.dg/lto/alias-1_0.c	(revision 0)
+++ testsuite/gcc.dg/lto/alias-1_0.c	(revision 0)
@@ -0,0 +1,19 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { { -O2 -flto } } } */
+int val;
+
+int *ptr = &val;
+float *ptr2 = &val;
+
+extern void typefun(void);
+
+
+main()
+{ 
+  *ptr=1;
+  typefun ();
+  if (*ptr)
+    link_error ();
+  return 0;
+}
+
Index: testsuite/gcc.dg/lto/alias-1_1.c
===================================================================
--- testsuite/gcc.dg/lto/alias-1_1.c	(revision 0)
+++ testsuite/gcc.dg/lto/alias-1_1.c	(revision 0)
@@ -0,0 +1,7 @@
+/* { dg-options "-fno-strict-aliasing" } */
+extern float *ptr2;
+__attribute__((optimize ("-fno-strict-aliasing")))
+typefun ()
+{ 
+  *ptr2=0;
+}
Index: testsuite/gcc.c-torture/execute/alias-1.c
===================================================================
--- testsuite/gcc.c-torture/execute/alias-1.c	(revision 0)
+++ testsuite/gcc.c-torture/execute/alias-1.c	(revision 0)
@@ -0,0 +1,19 @@
+int val;
+
+int *ptr = &val;
+float *ptr2 = &val;
+
+__attribute__((optimize ("-fno-strict-aliasing")))
+typepun ()
+{
+  *ptr2=0;
+}
+
+main()
+{
+  *ptr=1;
+  typepun ();
+  if (*ptr)
+    __builtin_abort ();
+}
+
Index: tree.c
===================================================================
--- tree.c	(revision 230924)
+++ tree.c	(working copy)
@@ -5971,7 +5971,8 @@ free_lang_data (void)
      while the slots are still in the way the frontends generated them.  */
   for (i = 0; i < itk_none; ++i)
     if (integer_types[i])
-      TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i]);
+      TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i],
+							 true);
 
   /* Traverse the IL resetting language specific information for
      operands, expressions, etc.  */

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix verify_type ICE during Ada bootstrap
  2015-11-27  7:30         ` Jan Hubicka
@ 2015-11-30  7:22           ` Jan Hubicka
  2015-11-30  7:55             ` Eric Botcazou
  2015-11-30 14:12             ` Richard Biener
  0 siblings, 2 replies; 11+ messages in thread
From: Jan Hubicka @ 2015-11-30  7:22 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Biener, gcc-patches

Hi,
here is updated patch which bootstraps&regtestes, lto-bootstraps x86_64-linux and
also works for Firefox. The basic pain is to identify which calls to get_alias_set
are used to build alias sets themselves and thus must be made -fstrict-aliasing
independent and which are used to drive queries to oracle and thus should follow
-fstrict-aliasing.  Fortunately the sanity checking I added seems pretty effective
to check bugs in this area: either we get ice in tree-streamer-out.c because alias
set is 0 when it is not expected to be or we get an ice in record_component_aliases
because alias set of component gets 0.

OK?
Honza

	* tree.c (free_lang_data): Pass true to get_alias_set.
	* tree-streamer-in.c (unpack_ts_type_common_value_fields): Do not stream
	alias set.
	* tree-ssa-alias.c (ao_ref_base_alias_set, ao_ref_alias_set): Pass true
	to get_alias_set; comment.
	(same_type_for_tbaa): Likewise.
	* alias.c (alias_set_subset_of, alias_sets_conflict_p): When strict
	aliasing is disabled, return true.
	(get_alias_set): New parameter strict.
	(new_alias_set): Always produce new alias set.
	(record_component_aliases): Pass true to get_alias_set.
	* alias.h (get_alias_set): New optional parameter STRICT.
	* lto-streamer-out.c (hash_tree): Do not hash alias set.
	* ipa-inline-transform.c (inline_call): Drop strict aliasing of
	caller if needed.
	* ipa-icf-gimple.c (func_checker::compatible_types_p): Pass true
	to get_alias_set.
	* tree-streamer-out.c (pack_ts_type_common_value_fields): Do not
	stream TYPE_ALIAS_SET; sanity check that alias set 0 at LTO time will
	match what frontneds does.
	* fold-const.c (operand_equal_p): Be cureful about TBAA info before
	inlining even with -fno-strict-aliasing.
	* gimple.c (gimple_get_alias_set): Pass true to get_alias_set.

	* misc.c (gnat_get_alias_set): Pass true to get_alias_set.
	* utils.c (relate_alias_sets): Likewise.
	* trans.c (validate_unchecked_conversion): Likewise.

	* lto-symtab.c (warn_type_compatibility_p): Pass true to get_alias_set.
	* lto.c (compare_tree_sccs_1): Do not ocmpare TYPE_ALIAS_SET.

	* gcc.c-torture/execute/alias-1.c: New testcase.
	* gcc.dg/lto/alias-1_0.c: New testcase.
	* gcc.dg/lto/alias-1_1.c: New testcase.

	* c-common.c (parse_optimize_options): Remove hack about
	flag_strict_aliasing.
	(convert_vector_to_pointer_for_subscript): Pass true to get_alias_set.

	* cp-objcp-common.c (cxx_get_alias_set): Pass true to get_alias_set.
	
	* rtti.c (typeid_ok_p): Pass true to get_alias_set.
Index: tree.c
===================================================================
--- tree.c	(revision 231020)
+++ tree.c	(working copy)
@@ -5971,7 +5971,8 @@ free_lang_data (void)
      while the slots are still in the way the frontends generated them.  */
   for (i = 0; i < itk_none; ++i)
     if (integer_types[i])
-      TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i]);
+      TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i],
+							 true);
 
   /* Traverse the IL resetting language specific information for
      operands, expressions, etc.  */
Index: cp/rtti.c
===================================================================
--- cp/rtti.c	(revision 231020)
+++ cp/rtti.c	(working copy)
@@ -300,10 +300,10 @@ typeid_ok_p (void)
   /* Make sure abi::__type_info_pseudo has the same alias set
      as std::type_info.  */
   if (! TYPE_ALIAS_SET_KNOWN_P (pseudo_type_info))
-    TYPE_ALIAS_SET (pseudo_type_info) = get_alias_set (type_info_type);
+    TYPE_ALIAS_SET (pseudo_type_info) = get_alias_set (type_info_type, true);
   else
     gcc_assert (TYPE_ALIAS_SET (pseudo_type_info)
-		== get_alias_set (type_info_type));
+		== get_alias_set (type_info_type, true));
 
   return true;
 }
Index: cp/cp-objcp-common.c
===================================================================
--- cp/cp-objcp-common.c	(revision 231020)
+++ cp/cp-objcp-common.c	(working copy)
@@ -32,7 +32,7 @@ cxx_get_alias_set (tree t)
   if (IS_FAKE_BASE_TYPE (t))
     /* The base variant of a type must be in the same alias set as the
        complete type.  */
-    return get_alias_set (TYPE_CONTEXT (t));
+    return get_alias_set (TYPE_CONTEXT (t), true);
 
   /* Punt on PMFs until we canonicalize functions properly.  */
   if (TYPE_PTRMEMFUNC_P (t)
Index: tree-streamer-in.c
===================================================================
--- tree-streamer-in.c	(revision 231020)
+++ tree-streamer-in.c	(working copy)
@@ -366,7 +366,6 @@ unpack_ts_type_common_value_fields (stru
   TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);
-  TYPE_ALIAS_SET (expr) = bp_unpack_value (bp, 1) ? 0 : -1;
   if (RECORD_OR_UNION_TYPE_P (expr))
     {
       TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
Index: tree-ssa-alias.c
===================================================================
--- tree-ssa-alias.c	(revision 231020)
+++ tree-ssa-alias.c	(working copy)
@@ -563,7 +563,10 @@ ao_ref_base_alias_set (ao_ref *ref)
   base_ref = ref->ref;
   while (handled_component_p (base_ref))
     base_ref = TREE_OPERAND (base_ref, 0);
-  ref->base_alias_set = get_alias_set (base_ref);
+  /* Do not return 0 in case of strict aliasing; this function is used at
+     IPA level by ipa-icf-gimple.c.  It is job of caller to give up on
+     using TBAA oracle when asked to not do so.  */
+  ref->base_alias_set = get_alias_set (base_ref, true);
   return ref->base_alias_set;
 }
 
@@ -574,7 +577,10 @@ ao_ref_alias_set (ao_ref *ref)
 {
   if (ref->ref_alias_set != -1)
     return ref->ref_alias_set;
-  ref->ref_alias_set = get_alias_set (ref->ref);
+  /* Do not return 0 in case of strict aliasing; this function is used at
+     IPA level by ipa-icf-gimple.c.  It is job of caller to give up on
+     using TBAA oracle when asked to not do so.  */
+  ref->ref_alias_set = get_alias_set (ref->ref, true);
   return ref->ref_alias_set;
 }
 
@@ -668,7 +674,7 @@ same_type_for_tbaa (tree type1, tree typ
      would mean that conversions between them are useless, whereas they are
      not (e.g. type and subtypes can have different modes).  So, in the end,
      they are only guaranteed to have the same alias set.  */
-  if (get_alias_set (type1) == get_alias_set (type2))
+  if (get_alias_set (type1, true) == get_alias_set (type2, true))
     return -1;
 
   /* The types are known to be not equal.  */
Index: alias.c
===================================================================
--- alias.c	(revision 231020)
+++ alias.c	(working copy)
@@ -406,7 +406,7 @@ alias_set_subset_of (alias_set_type set1
   alias_set_entry *ase2;
 
   /* Everything is a subset of the "aliases everything" set.  */
-  if (set2 == 0)
+  if (set2 == 0 || !flag_strict_aliasing)
     return true;
 
   /* Check if set1 is a subset of set2.  */
@@ -467,7 +467,7 @@ alias_sets_conflict_p (alias_set_type se
   alias_set_entry *ase2;
 
   /* The easy case.  */
-  if (alias_sets_must_conflict_p (set1, set2))
+  if (!flag_strict_aliasing || alias_sets_must_conflict_p (set1, set2))
     return 1;
 
   /* See if the first alias set is a subset of the second.  */
@@ -809,17 +809,21 @@ init_alias_set_entry (alias_set_type set
 }
 
 /* Return the alias set for T, which may be either a type or an
-   expression.  Call language-specific routine for help, if needed.  */
+   expression.  Call language-specific routine for help, if needed.
+   If STRICT is true, ignore value of flag_strict_aliasing.  This is needed
+   in cases we are in -fno-strict-aliasing region but still need to compute
+   alias sets for some reason (this is used, for example, by rtti code to copy
+   alias set from type to type).  */
 
 alias_set_type
-get_alias_set (tree t)
+get_alias_set (tree t, bool strict)
 {
   alias_set_type set;
 
   /* If we're not doing any alias analysis, just assume everything
      aliases everything else.  Also return 0 if this or its type is
      an error.  */
-  if (! flag_strict_aliasing || t == error_mark_node
+  if ((! flag_strict_aliasing && !strict)|| t == error_mark_node
       || (! TYPE_P (t)
 	  && (TREE_TYPE (t) == 0 || TREE_TYPE (t) == error_mark_node)))
     return 0;
@@ -898,7 +902,7 @@ get_alias_set (tree t)
       /* For arrays with unknown size the conservative answer is the
 	 alias set of the element type.  */
       if (TREE_CODE (t) == ARRAY_TYPE)
-	return get_alias_set (TREE_TYPE (t));
+	return get_alias_set (TREE_TYPE (t), true);
 
       /* But return zero as a conservative answer for incomplete types.  */
       return 0;
@@ -920,7 +924,7 @@ get_alias_set (tree t)
      normal usage.  And indeed lets vectors be treated more like an
      array slice.  */
   else if (TREE_CODE (t) == VECTOR_TYPE)
-    set = get_alias_set (TREE_TYPE (t));
+    set = get_alias_set (TREE_TYPE (t), true);
 
   /* Unless the language specifies otherwise, treat array types the
      same as their components.  This avoids the asymmetry we get
@@ -933,7 +937,7 @@ get_alias_set (tree t)
   else if (TREE_CODE (t) == ARRAY_TYPE
 	   && (!TYPE_NONALIASED_COMPONENT (t)
 	       || TYPE_STRUCTURAL_EQUALITY_P (t)))
-    set = get_alias_set (TREE_TYPE (t));
+    set = get_alias_set (TREE_TYPE (t), true);
 
   /* From the former common C and C++ langhook implementation:
 
@@ -997,7 +1001,7 @@ get_alias_set (tree t)
 	 (see record_component_aliases) and thus it is safe it to use it for
 	 pointers to types with TYPE_STRUCTURAL_EQUALITY_P.  */
       if (TREE_CODE (p) == VOID_TYPE || TYPE_STRUCTURAL_EQUALITY_P (p))
-	set = get_alias_set (ptr_type_node);
+	set = get_alias_set (ptr_type_node, true);
       else
 	{
 	  /* Rebuild pointer type starting from canonical types using
@@ -1085,15 +1089,10 @@ get_alias_set (tree t)
 alias_set_type
 new_alias_set (void)
 {
-  if (flag_strict_aliasing)
-    {
-      if (alias_sets == 0)
-	vec_safe_push (alias_sets, (alias_set_entry *) NULL);
-      vec_safe_push (alias_sets, (alias_set_entry *) NULL);
-      return alias_sets->length () - 1;
-    }
-  else
-    return 0;
+  if (alias_sets == 0)
+    vec_safe_push (alias_sets, (alias_set_entry *) NULL);
+  vec_safe_push (alias_sets, (alias_set_entry *) NULL);
+  return alias_sets->length () - 1;
 }
 
 /* Indicate that things in SUBSET can alias things in SUPERSET, but that
@@ -1169,7 +1168,7 @@ record_alias_subset (alias_set_type supe
 void
 record_component_aliases (tree type)
 {
-  alias_set_type superset = get_alias_set (type);
+  alias_set_type superset = get_alias_set (type, true);
   tree field;
 
   if (superset == 0)
@@ -1215,16 +1214,17 @@ record_component_aliases (tree type)
 		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)));
+		  gcc_checking_assert (get_alias_set (t, true)
+				       == get_alias_set (TREE_TYPE (field),
+							 true));
 	      }
 
-	    record_alias_subset (superset, get_alias_set (t));
+	    record_alias_subset (superset, get_alias_set (t, true));
 	  }
       break;
 
     case COMPLEX_TYPE:
-      record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
+      record_alias_subset (superset, get_alias_set (TREE_TYPE (type), true));
       break;
 
     /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
Index: alias.h
===================================================================
--- alias.h	(revision 231020)
+++ alias.h	(working copy)
@@ -21,7 +21,7 @@ along with GCC; see the file COPYING3.
 #define GCC_ALIAS_H
 
 extern alias_set_type new_alias_set (void);
-extern alias_set_type get_alias_set (tree);
+extern alias_set_type get_alias_set (tree, bool strict = false);
 extern alias_set_type get_deref_alias_set (tree);
 extern alias_set_type get_varargs_alias_set (void);
 extern alias_set_type get_frame_alias_set (void);
Index: lto/lto-symtab.c
===================================================================
--- lto/lto-symtab.c	(revision 231020)
+++ lto/lto-symtab.c	(working copy)
@@ -276,8 +276,8 @@ warn_type_compatibility_p (tree prevaili
      we make ptr_type_node to TBAA compatible with every other type.  */
   if (type_with_alias_set_p (type) && type_with_alias_set_p (prevailing_type))
     {
-      alias_set_type set1 = get_alias_set (type);
-      alias_set_type set2 = get_alias_set (prevailing_type);
+      alias_set_type set1 = get_alias_set (type, true);
+      alias_set_type set2 = get_alias_set (prevailing_type, true);
 
       if (set1 && set2 && set1 != set2 
           && (!POINTER_TYPE_P (type) || !POINTER_TYPE_P (prevailing_type)
Index: lto/lto.c
===================================================================
--- lto/lto.c	(revision 231020)
+++ lto/lto.c	(working copy)
@@ -1166,7 +1166,9 @@ compare_tree_sccs_1 (tree t1, tree t2, t
       compare_values (TYPE_READONLY);
       compare_values (TYPE_PRECISION);
       compare_values (TYPE_ALIGN);
-      compare_values (TYPE_ALIAS_SET);
+      /* Do not compare TYPE_ALIAS_SET.  Doing so introduce ordering issues
+         with calls to get_alias_set which may initialize it for streamed
+ 	 in types.  */
     }
 
   /* We don't want to compare locations, so there is nothing do compare
Index: testsuite/gcc.c-torture/execute/alias-1.c
===================================================================
--- testsuite/gcc.c-torture/execute/alias-1.c	(revision 0)
+++ testsuite/gcc.c-torture/execute/alias-1.c	(revision 0)
@@ -0,0 +1,19 @@
+int val;
+
+int *ptr = &val;
+float *ptr2 = &val;
+
+__attribute__((optimize ("-fno-strict-aliasing")))
+typepun ()
+{
+  *ptr2=0;
+}
+
+main()
+{
+  *ptr=1;
+  typepun ();
+  if (*ptr)
+    __builtin_abort ();
+}
+
Index: testsuite/gcc.dg/lto/alias-1_0.c
===================================================================
--- testsuite/gcc.dg/lto/alias-1_0.c	(revision 0)
+++ testsuite/gcc.dg/lto/alias-1_0.c	(revision 0)
@@ -0,0 +1,22 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { { -O2 -flto } } } */
+int val;
+
+int *ptr = &val;
+float *ptr2 = &val;
+
+extern void typefun(void);
+
+void link_error (void);
+
+int
+main()
+{ 
+  *ptr=1;
+  typefun ();
+  if (*ptr)
+    /*link_error ();*/
+    __builtin_abort ();
+  return 0;
+}
+
Index: testsuite/gcc.dg/lto/alias-1_1.c
===================================================================
--- testsuite/gcc.dg/lto/alias-1_1.c	(revision 0)
+++ testsuite/gcc.dg/lto/alias-1_1.c	(revision 0)
@@ -0,0 +1,8 @@
+/* { dg-options "-fno-strict-aliasing" } */
+extern float *ptr2;
+void
+__attribute__((optimize ("-fno-strict-aliasing")))
+typefun ()
+{ 
+  *ptr2=0;
+}
Index: c-family/c-common.c
===================================================================
--- c-family/c-common.c	(revision 231048)
+++ c-family/c-common.c	(working copy)
@@ -9988,7 +9988,6 @@ parse_optimize_options (tree args, bool
   bool ret = true;
   unsigned opt_argc;
   unsigned i;
-  int saved_flag_strict_aliasing;
   const char **opt_argv;
   struct cl_decoded_option *decoded_options;
   unsigned int decoded_options_count;
@@ -10081,8 +10080,6 @@ parse_optimize_options (tree args, bool
   for (i = 1; i < opt_argc; i++)
     opt_argv[i] = (*optimize_args)[i];
 
-  saved_flag_strict_aliasing = flag_strict_aliasing;
-
   /* Now parse the options.  */
   decode_cmdline_options_to_array_default_mask (opt_argc, opt_argv,
 						&decoded_options,
@@ -10093,9 +10090,6 @@ parse_optimize_options (tree args, bool
 
   targetm.override_options_after_change();
 
-  /* Don't allow changing -fstrict-aliasing.  */
-  flag_strict_aliasing = saved_flag_strict_aliasing;
-
   optimize_args->truncate (0);
   return ret;
 }
@@ -12930,8 +12924,8 @@ convert_vector_to_pointer_for_subscript
 	  /* If the original vector isn't declared may_alias and it
 	     isn't a bare vector look if the subscripting would
 	     alias the vector we subscript, and if not, force ref-all.  */
-	  alias_set_type vecset = get_alias_set (*vecp);
-	  alias_set_type sset = get_alias_set (type);
+	  alias_set_type vecset = get_alias_set (*vecp, true);
+	  alias_set_type sset = get_alias_set (type, true);
 	  if (!alias_sets_must_conflict_p (sset, vecset)
 	      && !alias_set_subset_of (sset, vecset))
 	    ref_all = true;
Index: lto-streamer-out.c
===================================================================
--- lto-streamer-out.c	(revision 231020)
+++ lto-streamer-out.c	(working copy)
@@ -1109,10 +1109,6 @@ hash_tree (struct streamer_tree_cache_d
       hstate.commit_flag ();
       hstate.add_int (TYPE_PRECISION (t));
       hstate.add_int (TYPE_ALIGN (t));
-      hstate.add_int ((TYPE_ALIAS_SET (t) == 0
-					 || (!in_lto_p
-					     && get_alias_set (t) == 0))
-					? 0 : -1);
     }
 
   if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
Index: ipa-inline-transform.c
===================================================================
--- ipa-inline-transform.c	(revision 231020)
+++ ipa-inline-transform.c	(working copy)
@@ -322,6 +322,23 @@ inline_call (struct cgraph_edge *e, bool
   if (DECL_FUNCTION_PERSONALITY (callee->decl))
     DECL_FUNCTION_PERSONALITY (to->decl)
       = DECL_FUNCTION_PERSONALITY (callee->decl);
+  if (!opt_for_fn (callee->decl, flag_strict_aliasing)
+      && opt_for_fn (to->decl, flag_strict_aliasing)
+      && (!callee->merged
+	  || lookup_attribute ("optimization", DECL_ATTRIBUTES (e->caller->decl))
+	  || lookup_attribute ("optimization", DECL_ATTRIBUTES (callee->decl))))
+    {
+      struct gcc_options opts = global_options;
+      cl_optimization_restore (&opts,
+	 TREE_OPTIMIZATION (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (to->decl)));
+      opts.x_flag_strict_aliasing = false;
+      if (dump_file)
+	fprintf (dump_file, "Dropping flag_strict_aliasing on %s:%i\n",
+		 to->name (), to->order);
+      build_optimization_node (&opts);
+      DECL_FUNCTION_SPECIFIC_OPTIMIZATION (to->decl)
+	 = build_optimization_node (&opts);
+    }
 
   /* If aliases are involved, redirect edge to the actual destination and
      possibly remove the aliases.  */
Index: ipa-icf-gimple.c
===================================================================
--- ipa-icf-gimple.c	(revision 231020)
+++ ipa-icf-gimple.c	(working copy)
@@ -241,7 +241,7 @@ func_checker::compatible_types_p (tree t
      For time being just avoid calling get_alias_set on types that are not
      having alias sets defined at all.  */
   if (type_with_alias_set_p (t1) && type_with_alias_set_p (t2)
-      && get_alias_set (t1) != get_alias_set (t2))
+      && get_alias_set (t1, true) != get_alias_set (t2, true))
     return return_false_with_msg ("alias sets are different");
 
   return true;
Index: tree-streamer-out.c
===================================================================
--- tree-streamer-out.c	(revision 231020)
+++ tree-streamer-out.c	(working copy)
@@ -317,13 +321,18 @@ pack_ts_type_common_value_fields (struct
   bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
   bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
   bp_pack_value (bp, TYPE_READONLY (expr), 1);
-  /* Make sure to preserve the fact whether the frontend would assign
-     alias-set zero to this type.  Do that only for main variants, because
-     type variants alias sets are never computed.
-     FIXME:  This does not work for pre-streamed builtin types.  */
-  bp_pack_value (bp, (TYPE_ALIAS_SET (expr) == 0
-		      || (!in_lto_p && TYPE_MAIN_VARIANT (expr) == expr
-			  && get_alias_set (expr) == 0)), 1);
+  /* We used to stream TYPE_ALIAS_SET == 0 information to let frontends mark
+     types that are opaque for TBAA.  This however did not work as intended,
+     becuase TYPE_ALIAS_SET == 0 was regularly lost in type merging.
+
+     Instead now double check that all aliaset set 0 types will be alias set
+     0 in LTO world, too.  */
+  gcc_checking_assert (!type_with_alias_set_p (expr)
+		       || !canonical_type_used_p (expr)
+		       || TYPE_ALIAS_SET (expr) != 0
+		       || expr == char_type_node
+		       || expr == signed_char_type_node
+		       || expr == unsigned_char_type_node);
   if (RECORD_OR_UNION_TYPE_P (expr))
     {
       bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
Index: fold-const.c
===================================================================
--- fold-const.c	(revision 231020)
+++ fold-const.c	(working copy)
@@ -2987,7 +2987,7 @@ operand_equal_p (const_tree arg0, const_
 					   flags)))
 		return 0;
 	      /* Verify that accesses are TBAA compatible.  */
-	      if (flag_strict_aliasing
+	      if ((flag_strict_aliasing || !cfun->after_inlining)
 		  && (!alias_ptr_types_compatible_p
 		        (TREE_TYPE (TREE_OPERAND (arg0, 1)),
 		         TREE_TYPE (TREE_OPERAND (arg1, 1)))
Index: ada/gcc-interface/misc.c
===================================================================
--- ada/gcc-interface/misc.c	(revision 231020)
+++ ada/gcc-interface/misc.c	(working copy)
@@ -592,13 +592,14 @@ gnat_get_alias_set (tree type)
 {
   /* If this is a padding type, use the type of the first field.  */
   if (TYPE_IS_PADDING_P (type))
-    return get_alias_set (TREE_TYPE (TYPE_FIELDS (type)));
+    return get_alias_set (TREE_TYPE (TYPE_FIELDS (type)), true);
 
   /* If the type is an unconstrained array, use the type of the
      self-referential array we make.  */
   else if (TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
     return
-      get_alias_set (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (type)))));
+      get_alias_set (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (type)))),
+		     true);
 
   /* If the type can alias any other types, return the alias set 0.  */
   else if (TYPE_P (type) && TYPE_UNIVERSAL_ALIASING_P (type))
Index: ada/gcc-interface/utils.c
===================================================================
--- ada/gcc-interface/utils.c	(revision 231020)
+++ ada/gcc-interface/utils.c	(working copy)
@@ -1520,14 +1520,14 @@ relate_alias_sets (tree gnu_new_type, tr
 		      && TYPE_NONALIASED_COMPONENT (gnu_new_type)
 			 != TYPE_NONALIASED_COMPONENT (gnu_old_type)));
 
-      TYPE_ALIAS_SET (gnu_new_type) = get_alias_set (gnu_old_type);
+      TYPE_ALIAS_SET (gnu_new_type) = get_alias_set (gnu_old_type, true);
       break;
 
     case ALIAS_SET_SUBSET:
     case ALIAS_SET_SUPERSET:
       {
-	alias_set_type old_set = get_alias_set (gnu_old_type);
-	alias_set_type new_set = get_alias_set (gnu_new_type);
+	alias_set_type old_set = get_alias_set (gnu_old_type, true);
+	alias_set_type new_set = get_alias_set (gnu_new_type, true);
 
 	/* Do nothing if the alias sets conflict.  This ensures that we
 	   never call record_alias_subset several times for the same pair
Index: ada/gcc-interface/trans.c
===================================================================
--- ada/gcc-interface/trans.c	(revision 231020)
+++ ada/gcc-interface/trans.c	(working copy)
@@ -9702,11 +9702,13 @@ validate_unchecked_conversion (Node_Id g
 				   ? TREE_TYPE (gnu_source_type)
 				   : NULL_TREE;
       tree gnu_target_desig_type = TREE_TYPE (gnu_target_type);
-      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type);
+      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type,
+						       true);
 
       if (target_alias_set != 0
 	  && (!POINTER_TYPE_P (gnu_source_type)
-	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type),
+	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type,
+							true),
 					 target_alias_set)))
 	{
 	  post_error_ne ("?possible aliasing problem for type&",
@@ -9728,11 +9730,13 @@ validate_unchecked_conversion (Node_Id g
 	  : NULL_TREE;
       tree gnu_target_desig_type
 	= TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_target_type)));
-      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type);
+      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type,
+						       true);
 
       if (target_alias_set != 0
 	  && (!TYPE_IS_FAT_POINTER_P (gnu_source_type)
-	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type),
+	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type,
+							true),
 					 target_alias_set)))
 	{
 	  post_error_ne ("?possible aliasing problem for type&",
Index: gimple.c
===================================================================
--- gimple.c	(revision 231020)
+++ gimple.c	(working copy)
@@ -2408,7 +2408,7 @@ gimple_get_alias_set (tree t)
 
       /* t1 == t can happen for boolean nodes which are always unsigned.  */
       if (t1 != t)
-	return get_alias_set (t1);
+	return get_alias_set (t1, true);
     }
 
   return -1;

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix verify_type ICE during Ada bootstrap
  2015-11-30  7:22           ` Jan Hubicka
@ 2015-11-30  7:55             ` Eric Botcazou
  2015-11-30  8:05               ` Jan Hubicka
  2015-11-30 14:12             ` Richard Biener
  1 sibling, 1 reply; 11+ messages in thread
From: Eric Botcazou @ 2015-11-30  7:55 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches, Richard Biener

> 	* misc.c (gnat_get_alias_set): Pass true to get_alias_set.
> 	* utils.c (relate_alias_sets): Likewise.
> 	* trans.c (validate_unchecked_conversion): Likewise.

Missing gcc-interface/ prefix here.

But can't we use a default value (of true I suppose) for the new parameter?

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix verify_type ICE during Ada bootstrap
  2015-11-30  7:55             ` Eric Botcazou
@ 2015-11-30  8:05               ` Jan Hubicka
  0 siblings, 0 replies; 11+ messages in thread
From: Jan Hubicka @ 2015-11-30  8:05 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: Jan Hubicka, gcc-patches, Richard Biener

> > 	* misc.c (gnat_get_alias_set): Pass true to get_alias_set.
> > 	* utils.c (relate_alias_sets): Likewise.
> > 	* trans.c (validate_unchecked_conversion): Likewise.
> 
> Missing gcc-interface/ prefix here.
Updated.
> 
> But can't we use a default value (of true I suppose) for the new parameter?

I originally went for default value of false with an assumption that most of
uses of get_alias_set are from the optimizers and in this context it is better
to keep the original beaviour (returning 0 for -fno-strict-aliasing)

The code used to build types I updated should be less actively developed.
Since I ended up modifying quite few calls I have no problem with flipping the
default or perhaps going for two entry points.

Honza
> 
> -- 
> Eric Botcazou

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix verify_type ICE during Ada bootstrap
  2015-11-30  7:22           ` Jan Hubicka
  2015-11-30  7:55             ` Eric Botcazou
@ 2015-11-30 14:12             ` Richard Biener
  2015-11-30 17:11               ` Jan Hubicka
  1 sibling, 1 reply; 11+ messages in thread
From: Richard Biener @ 2015-11-30 14:12 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

On Mon, 30 Nov 2015, Jan Hubicka wrote:

> Hi,
> here is updated patch which bootstraps&regtestes, lto-bootstraps x86_64-linux and
> also works for Firefox. The basic pain is to identify which calls to get_alias_set
> are used to build alias sets themselves and thus must be made -fstrict-aliasing
> independent and which are used to drive queries to oracle and thus should follow
> -fstrict-aliasing.  Fortunately the sanity checking I added seems pretty effective
> to check bugs in this area: either we get ice in tree-streamer-out.c because alias
> set is 0 when it is not expected to be or we get an ice in record_component_aliases
> because alias set of component gets 0.
> 
> OK?

I think you are doing too many things in one patch.  I'm fine with
dropping the zero-alias-set streaming (but I'd rather not assert
as FE get_alias_set langhook may assign zero to random tree nodes).

I'm also fine with handling flag_strict_aliasing conservatively
during inlining - but the condition you placed on this handling
needs a comment.  I couldn't decipher it ;)

> +      if (dump_file)
> +     fprintf (dump_file, "Dropping flag_strict_aliasing on %s:%i\n",
> +              to->name (), to->order);

So I wonder if it makes sense to pessimize such inlining as well.

The two above should be enough to fix the correctness issue.

The parse_optimize_options hack looks indeed interesting, but we solved
the issue differently by

2014-11-27  Richard Biener  <rguenther@suse.de>

        PR middle-end/63704
        * alias.c (mems_in_disjoint_alias_sets_p): Remove assert
        and instead return false when !fstrict-aliasing.

So the hack can be removed as a separate commit after the first one
above.  This should make optimize("fno-strict-aliasing") work.


I don't really see why we need all the other changes and IMHO the
get_alias_set interface change is ugly and fragile.  And this doesn't
look like sth for stage3.

Thus please split the patch up.

Thanks,
Richard.

> Honza
> 
> 	* tree.c (free_lang_data): Pass true to get_alias_set.
> 	* tree-streamer-in.c (unpack_ts_type_common_value_fields): Do not stream
> 	alias set.
> 	* tree-ssa-alias.c (ao_ref_base_alias_set, ao_ref_alias_set): Pass true
> 	to get_alias_set; comment.
> 	(same_type_for_tbaa): Likewise.
> 	* alias.c (alias_set_subset_of, alias_sets_conflict_p): When strict
> 	aliasing is disabled, return true.
> 	(get_alias_set): New parameter strict.
> 	(new_alias_set): Always produce new alias set.
> 	(record_component_aliases): Pass true to get_alias_set.
> 	* alias.h (get_alias_set): New optional parameter STRICT.
> 	* lto-streamer-out.c (hash_tree): Do not hash alias set.
> 	* ipa-inline-transform.c (inline_call): Drop strict aliasing of
> 	caller if needed.
> 	* ipa-icf-gimple.c (func_checker::compatible_types_p): Pass true
> 	to get_alias_set.
> 	* tree-streamer-out.c (pack_ts_type_common_value_fields): Do not
> 	stream TYPE_ALIAS_SET; sanity check that alias set 0 at LTO time will
> 	match what frontneds does.
> 	* fold-const.c (operand_equal_p): Be cureful about TBAA info before
> 	inlining even with -fno-strict-aliasing.
> 	* gimple.c (gimple_get_alias_set): Pass true to get_alias_set.
> 
> 	* misc.c (gnat_get_alias_set): Pass true to get_alias_set.
> 	* utils.c (relate_alias_sets): Likewise.
> 	* trans.c (validate_unchecked_conversion): Likewise.
> 
> 	* lto-symtab.c (warn_type_compatibility_p): Pass true to get_alias_set.
> 	* lto.c (compare_tree_sccs_1): Do not ocmpare TYPE_ALIAS_SET.
> 
> 	* gcc.c-torture/execute/alias-1.c: New testcase.
> 	* gcc.dg/lto/alias-1_0.c: New testcase.
> 	* gcc.dg/lto/alias-1_1.c: New testcase.
> 
> 	* c-common.c (parse_optimize_options): Remove hack about
> 	flag_strict_aliasing.
> 	(convert_vector_to_pointer_for_subscript): Pass true to get_alias_set.
> 
> 	* cp-objcp-common.c (cxx_get_alias_set): Pass true to get_alias_set.
> 	
> 	* rtti.c (typeid_ok_p): Pass true to get_alias_set.
> Index: tree.c
> ===================================================================
> --- tree.c	(revision 231020)
> +++ tree.c	(working copy)
> @@ -5971,7 +5971,8 @@ free_lang_data (void)
>       while the slots are still in the way the frontends generated them.  */
>    for (i = 0; i < itk_none; ++i)
>      if (integer_types[i])
> -      TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i]);
> +      TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i],
> +							 true);
>  
>    /* Traverse the IL resetting language specific information for
>       operands, expressions, etc.  */
> Index: cp/rtti.c
> ===================================================================
> --- cp/rtti.c	(revision 231020)
> +++ cp/rtti.c	(working copy)
> @@ -300,10 +300,10 @@ typeid_ok_p (void)
>    /* Make sure abi::__type_info_pseudo has the same alias set
>       as std::type_info.  */
>    if (! TYPE_ALIAS_SET_KNOWN_P (pseudo_type_info))
> -    TYPE_ALIAS_SET (pseudo_type_info) = get_alias_set (type_info_type);
> +    TYPE_ALIAS_SET (pseudo_type_info) = get_alias_set (type_info_type, true);
>    else
>      gcc_assert (TYPE_ALIAS_SET (pseudo_type_info)
> -		== get_alias_set (type_info_type));
> +		== get_alias_set (type_info_type, true));
>  
>    return true;
>  }
> Index: cp/cp-objcp-common.c
> ===================================================================
> --- cp/cp-objcp-common.c	(revision 231020)
> +++ cp/cp-objcp-common.c	(working copy)
> @@ -32,7 +32,7 @@ cxx_get_alias_set (tree t)
>    if (IS_FAKE_BASE_TYPE (t))
>      /* The base variant of a type must be in the same alias set as the
>         complete type.  */
> -    return get_alias_set (TYPE_CONTEXT (t));
> +    return get_alias_set (TYPE_CONTEXT (t), true);
>  
>    /* Punt on PMFs until we canonicalize functions properly.  */
>    if (TYPE_PTRMEMFUNC_P (t)
> Index: tree-streamer-in.c
> ===================================================================
> --- tree-streamer-in.c	(revision 231020)
> +++ tree-streamer-in.c	(working copy)
> @@ -366,7 +366,6 @@ unpack_ts_type_common_value_fields (stru
>    TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
>    TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
>    TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);
> -  TYPE_ALIAS_SET (expr) = bp_unpack_value (bp, 1) ? 0 : -1;
>    if (RECORD_OR_UNION_TYPE_P (expr))
>      {
>        TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
> Index: tree-ssa-alias.c
> ===================================================================
> --- tree-ssa-alias.c	(revision 231020)
> +++ tree-ssa-alias.c	(working copy)
> @@ -563,7 +563,10 @@ ao_ref_base_alias_set (ao_ref *ref)
>    base_ref = ref->ref;
>    while (handled_component_p (base_ref))
>      base_ref = TREE_OPERAND (base_ref, 0);
> -  ref->base_alias_set = get_alias_set (base_ref);
> +  /* Do not return 0 in case of strict aliasing; this function is used at
> +     IPA level by ipa-icf-gimple.c.  It is job of caller to give up on
> +     using TBAA oracle when asked to not do so.  */
> +  ref->base_alias_set = get_alias_set (base_ref, true);
>    return ref->base_alias_set;
>  }
>  
> @@ -574,7 +577,10 @@ ao_ref_alias_set (ao_ref *ref)
>  {
>    if (ref->ref_alias_set != -1)
>      return ref->ref_alias_set;
> -  ref->ref_alias_set = get_alias_set (ref->ref);
> +  /* Do not return 0 in case of strict aliasing; this function is used at
> +     IPA level by ipa-icf-gimple.c.  It is job of caller to give up on
> +     using TBAA oracle when asked to not do so.  */
> +  ref->ref_alias_set = get_alias_set (ref->ref, true);
>    return ref->ref_alias_set;
>  }
>  
> @@ -668,7 +674,7 @@ same_type_for_tbaa (tree type1, tree typ
>       would mean that conversions between them are useless, whereas they are
>       not (e.g. type and subtypes can have different modes).  So, in the end,
>       they are only guaranteed to have the same alias set.  */
> -  if (get_alias_set (type1) == get_alias_set (type2))
> +  if (get_alias_set (type1, true) == get_alias_set (type2, true))
>      return -1;
>  
>    /* The types are known to be not equal.  */
> Index: alias.c
> ===================================================================
> --- alias.c	(revision 231020)
> +++ alias.c	(working copy)
> @@ -406,7 +406,7 @@ alias_set_subset_of (alias_set_type set1
>    alias_set_entry *ase2;
>  
>    /* Everything is a subset of the "aliases everything" set.  */
> -  if (set2 == 0)
> +  if (set2 == 0 || !flag_strict_aliasing)
>      return true;
>  
>    /* Check if set1 is a subset of set2.  */
> @@ -467,7 +467,7 @@ alias_sets_conflict_p (alias_set_type se
>    alias_set_entry *ase2;
>  
>    /* The easy case.  */
> -  if (alias_sets_must_conflict_p (set1, set2))
> +  if (!flag_strict_aliasing || alias_sets_must_conflict_p (set1, set2))
>      return 1;
>  
>    /* See if the first alias set is a subset of the second.  */
> @@ -809,17 +809,21 @@ init_alias_set_entry (alias_set_type set
>  }
>  
>  /* Return the alias set for T, which may be either a type or an
> -   expression.  Call language-specific routine for help, if needed.  */
> +   expression.  Call language-specific routine for help, if needed.
> +   If STRICT is true, ignore value of flag_strict_aliasing.  This is needed
> +   in cases we are in -fno-strict-aliasing region but still need to compute
> +   alias sets for some reason (this is used, for example, by rtti code to copy
> +   alias set from type to type).  */
>  
>  alias_set_type
> -get_alias_set (tree t)
> +get_alias_set (tree t, bool strict)
>  {
>    alias_set_type set;
>  
>    /* If we're not doing any alias analysis, just assume everything
>       aliases everything else.  Also return 0 if this or its type is
>       an error.  */
> -  if (! flag_strict_aliasing || t == error_mark_node
> +  if ((! flag_strict_aliasing && !strict)|| t == error_mark_node
>        || (! TYPE_P (t)
>  	  && (TREE_TYPE (t) == 0 || TREE_TYPE (t) == error_mark_node)))
>      return 0;
> @@ -898,7 +902,7 @@ get_alias_set (tree t)
>        /* For arrays with unknown size the conservative answer is the
>  	 alias set of the element type.  */
>        if (TREE_CODE (t) == ARRAY_TYPE)
> -	return get_alias_set (TREE_TYPE (t));
> +	return get_alias_set (TREE_TYPE (t), true);
>  
>        /* But return zero as a conservative answer for incomplete types.  */
>        return 0;
> @@ -920,7 +924,7 @@ get_alias_set (tree t)
>       normal usage.  And indeed lets vectors be treated more like an
>       array slice.  */
>    else if (TREE_CODE (t) == VECTOR_TYPE)
> -    set = get_alias_set (TREE_TYPE (t));
> +    set = get_alias_set (TREE_TYPE (t), true);
>  
>    /* Unless the language specifies otherwise, treat array types the
>       same as their components.  This avoids the asymmetry we get
> @@ -933,7 +937,7 @@ get_alias_set (tree t)
>    else if (TREE_CODE (t) == ARRAY_TYPE
>  	   && (!TYPE_NONALIASED_COMPONENT (t)
>  	       || TYPE_STRUCTURAL_EQUALITY_P (t)))
> -    set = get_alias_set (TREE_TYPE (t));
> +    set = get_alias_set (TREE_TYPE (t), true);
>  
>    /* From the former common C and C++ langhook implementation:
>  
> @@ -997,7 +1001,7 @@ get_alias_set (tree t)
>  	 (see record_component_aliases) and thus it is safe it to use it for
>  	 pointers to types with TYPE_STRUCTURAL_EQUALITY_P.  */
>        if (TREE_CODE (p) == VOID_TYPE || TYPE_STRUCTURAL_EQUALITY_P (p))
> -	set = get_alias_set (ptr_type_node);
> +	set = get_alias_set (ptr_type_node, true);
>        else
>  	{
>  	  /* Rebuild pointer type starting from canonical types using
> @@ -1085,15 +1089,10 @@ get_alias_set (tree t)
>  alias_set_type
>  new_alias_set (void)
>  {
> -  if (flag_strict_aliasing)
> -    {
> -      if (alias_sets == 0)
> -	vec_safe_push (alias_sets, (alias_set_entry *) NULL);
> -      vec_safe_push (alias_sets, (alias_set_entry *) NULL);
> -      return alias_sets->length () - 1;
> -    }
> -  else
> -    return 0;
> +  if (alias_sets == 0)
> +    vec_safe_push (alias_sets, (alias_set_entry *) NULL);
> +  vec_safe_push (alias_sets, (alias_set_entry *) NULL);
> +  return alias_sets->length () - 1;
>  }
>  
>  /* Indicate that things in SUBSET can alias things in SUPERSET, but that
> @@ -1169,7 +1168,7 @@ record_alias_subset (alias_set_type supe
>  void
>  record_component_aliases (tree type)
>  {
> -  alias_set_type superset = get_alias_set (type);
> +  alias_set_type superset = get_alias_set (type, true);
>    tree field;
>  
>    if (superset == 0)
> @@ -1215,16 +1214,17 @@ record_component_aliases (tree type)
>  		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)));
> +		  gcc_checking_assert (get_alias_set (t, true)
> +				       == get_alias_set (TREE_TYPE (field),
> +							 true));
>  	      }
>  
> -	    record_alias_subset (superset, get_alias_set (t));
> +	    record_alias_subset (superset, get_alias_set (t, true));
>  	  }
>        break;
>  
>      case COMPLEX_TYPE:
> -      record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
> +      record_alias_subset (superset, get_alias_set (TREE_TYPE (type), true));
>        break;
>  
>      /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
> Index: alias.h
> ===================================================================
> --- alias.h	(revision 231020)
> +++ alias.h	(working copy)
> @@ -21,7 +21,7 @@ along with GCC; see the file COPYING3.
>  #define GCC_ALIAS_H
>  
>  extern alias_set_type new_alias_set (void);
> -extern alias_set_type get_alias_set (tree);
> +extern alias_set_type get_alias_set (tree, bool strict = false);
>  extern alias_set_type get_deref_alias_set (tree);
>  extern alias_set_type get_varargs_alias_set (void);
>  extern alias_set_type get_frame_alias_set (void);
> Index: lto/lto-symtab.c
> ===================================================================
> --- lto/lto-symtab.c	(revision 231020)
> +++ lto/lto-symtab.c	(working copy)
> @@ -276,8 +276,8 @@ warn_type_compatibility_p (tree prevaili
>       we make ptr_type_node to TBAA compatible with every other type.  */
>    if (type_with_alias_set_p (type) && type_with_alias_set_p (prevailing_type))
>      {
> -      alias_set_type set1 = get_alias_set (type);
> -      alias_set_type set2 = get_alias_set (prevailing_type);
> +      alias_set_type set1 = get_alias_set (type, true);
> +      alias_set_type set2 = get_alias_set (prevailing_type, true);
>  
>        if (set1 && set2 && set1 != set2 
>            && (!POINTER_TYPE_P (type) || !POINTER_TYPE_P (prevailing_type)
> Index: lto/lto.c
> ===================================================================
> --- lto/lto.c	(revision 231020)
> +++ lto/lto.c	(working copy)
> @@ -1166,7 +1166,9 @@ compare_tree_sccs_1 (tree t1, tree t2, t
>        compare_values (TYPE_READONLY);
>        compare_values (TYPE_PRECISION);
>        compare_values (TYPE_ALIGN);
> -      compare_values (TYPE_ALIAS_SET);
> +      /* Do not compare TYPE_ALIAS_SET.  Doing so introduce ordering issues
> +         with calls to get_alias_set which may initialize it for streamed
> + 	 in types.  */
>      }
>  
>    /* We don't want to compare locations, so there is nothing do compare
> Index: testsuite/gcc.c-torture/execute/alias-1.c
> ===================================================================
> --- testsuite/gcc.c-torture/execute/alias-1.c	(revision 0)
> +++ testsuite/gcc.c-torture/execute/alias-1.c	(revision 0)
> @@ -0,0 +1,19 @@
> +int val;
> +
> +int *ptr = &val;
> +float *ptr2 = &val;
> +
> +__attribute__((optimize ("-fno-strict-aliasing")))
> +typepun ()
> +{
> +  *ptr2=0;
> +}
> +
> +main()
> +{
> +  *ptr=1;
> +  typepun ();
> +  if (*ptr)
> +    __builtin_abort ();
> +}
> +
> Index: testsuite/gcc.dg/lto/alias-1_0.c
> ===================================================================
> --- testsuite/gcc.dg/lto/alias-1_0.c	(revision 0)
> +++ testsuite/gcc.dg/lto/alias-1_0.c	(revision 0)
> @@ -0,0 +1,22 @@
> +/* { dg-lto-do run } */
> +/* { dg-lto-options { { -O2 -flto } } } */
> +int val;
> +
> +int *ptr = &val;
> +float *ptr2 = &val;
> +
> +extern void typefun(void);
> +
> +void link_error (void);
> +
> +int
> +main()
> +{ 
> +  *ptr=1;
> +  typefun ();
> +  if (*ptr)
> +    /*link_error ();*/
> +    __builtin_abort ();
> +  return 0;
> +}
> +
> Index: testsuite/gcc.dg/lto/alias-1_1.c
> ===================================================================
> --- testsuite/gcc.dg/lto/alias-1_1.c	(revision 0)
> +++ testsuite/gcc.dg/lto/alias-1_1.c	(revision 0)
> @@ -0,0 +1,8 @@
> +/* { dg-options "-fno-strict-aliasing" } */
> +extern float *ptr2;
> +void
> +__attribute__((optimize ("-fno-strict-aliasing")))
> +typefun ()
> +{ 
> +  *ptr2=0;
> +}
> Index: c-family/c-common.c
> ===================================================================
> --- c-family/c-common.c	(revision 231048)
> +++ c-family/c-common.c	(working copy)
> @@ -9988,7 +9988,6 @@ parse_optimize_options (tree args, bool
>    bool ret = true;
>    unsigned opt_argc;
>    unsigned i;
> -  int saved_flag_strict_aliasing;
>    const char **opt_argv;
>    struct cl_decoded_option *decoded_options;
>    unsigned int decoded_options_count;
> @@ -10081,8 +10080,6 @@ parse_optimize_options (tree args, bool
>    for (i = 1; i < opt_argc; i++)
>      opt_argv[i] = (*optimize_args)[i];
>  
> -  saved_flag_strict_aliasing = flag_strict_aliasing;
> -
>    /* Now parse the options.  */
>    decode_cmdline_options_to_array_default_mask (opt_argc, opt_argv,
>  						&decoded_options,
> @@ -10093,9 +10090,6 @@ parse_optimize_options (tree args, bool
>  
>    targetm.override_options_after_change();
>  
> -  /* Don't allow changing -fstrict-aliasing.  */
> -  flag_strict_aliasing = saved_flag_strict_aliasing;
> -
>    optimize_args->truncate (0);
>    return ret;
>  }
> @@ -12930,8 +12924,8 @@ convert_vector_to_pointer_for_subscript
>  	  /* If the original vector isn't declared may_alias and it
>  	     isn't a bare vector look if the subscripting would
>  	     alias the vector we subscript, and if not, force ref-all.  */
> -	  alias_set_type vecset = get_alias_set (*vecp);
> -	  alias_set_type sset = get_alias_set (type);
> +	  alias_set_type vecset = get_alias_set (*vecp, true);
> +	  alias_set_type sset = get_alias_set (type, true);
>  	  if (!alias_sets_must_conflict_p (sset, vecset)
>  	      && !alias_set_subset_of (sset, vecset))
>  	    ref_all = true;
> Index: lto-streamer-out.c
> ===================================================================
> --- lto-streamer-out.c	(revision 231020)
> +++ lto-streamer-out.c	(working copy)
> @@ -1109,10 +1109,6 @@ hash_tree (struct streamer_tree_cache_d
>        hstate.commit_flag ();
>        hstate.add_int (TYPE_PRECISION (t));
>        hstate.add_int (TYPE_ALIGN (t));
> -      hstate.add_int ((TYPE_ALIAS_SET (t) == 0
> -					 || (!in_lto_p
> -					     && get_alias_set (t) == 0))
> -					? 0 : -1);
>      }
>  
>    if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
> Index: ipa-inline-transform.c
> ===================================================================
> --- ipa-inline-transform.c	(revision 231020)
> +++ ipa-inline-transform.c	(working copy)
> @@ -322,6 +322,23 @@ inline_call (struct cgraph_edge *e, bool
>    if (DECL_FUNCTION_PERSONALITY (callee->decl))
>      DECL_FUNCTION_PERSONALITY (to->decl)
>        = DECL_FUNCTION_PERSONALITY (callee->decl);
> +  if (!opt_for_fn (callee->decl, flag_strict_aliasing)
> +      && opt_for_fn (to->decl, flag_strict_aliasing)
> +      && (!callee->merged
> +	  || lookup_attribute ("optimization", DECL_ATTRIBUTES (e->caller->decl))
> +	  || lookup_attribute ("optimization", DECL_ATTRIBUTES (callee->decl))))
> +    {
> +      struct gcc_options opts = global_options;
> +      cl_optimization_restore (&opts,
> +	 TREE_OPTIMIZATION (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (to->decl)));
> +      opts.x_flag_strict_aliasing = false;
> +      if (dump_file)
> +	fprintf (dump_file, "Dropping flag_strict_aliasing on %s:%i\n",
> +		 to->name (), to->order);
> +      build_optimization_node (&opts);
> +      DECL_FUNCTION_SPECIFIC_OPTIMIZATION (to->decl)
> +	 = build_optimization_node (&opts);
> +    }
>  
>    /* If aliases are involved, redirect edge to the actual destination and
>       possibly remove the aliases.  */
> Index: ipa-icf-gimple.c
> ===================================================================
> --- ipa-icf-gimple.c	(revision 231020)
> +++ ipa-icf-gimple.c	(working copy)
> @@ -241,7 +241,7 @@ func_checker::compatible_types_p (tree t
>       For time being just avoid calling get_alias_set on types that are not
>       having alias sets defined at all.  */
>    if (type_with_alias_set_p (t1) && type_with_alias_set_p (t2)
> -      && get_alias_set (t1) != get_alias_set (t2))
> +      && get_alias_set (t1, true) != get_alias_set (t2, true))
>      return return_false_with_msg ("alias sets are different");
>  
>    return true;
> Index: tree-streamer-out.c
> ===================================================================
> --- tree-streamer-out.c	(revision 231020)
> +++ tree-streamer-out.c	(working copy)
> @@ -317,13 +321,18 @@ pack_ts_type_common_value_fields (struct
>    bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
>    bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
>    bp_pack_value (bp, TYPE_READONLY (expr), 1);
> -  /* Make sure to preserve the fact whether the frontend would assign
> -     alias-set zero to this type.  Do that only for main variants, because
> -     type variants alias sets are never computed.
> -     FIXME:  This does not work for pre-streamed builtin types.  */
> -  bp_pack_value (bp, (TYPE_ALIAS_SET (expr) == 0
> -		      || (!in_lto_p && TYPE_MAIN_VARIANT (expr) == expr
> -			  && get_alias_set (expr) == 0)), 1);
> +  /* We used to stream TYPE_ALIAS_SET == 0 information to let frontends mark
> +     types that are opaque for TBAA.  This however did not work as intended,
> +     becuase TYPE_ALIAS_SET == 0 was regularly lost in type merging.
> +
> +     Instead now double check that all aliaset set 0 types will be alias set
> +     0 in LTO world, too.  */
> +  gcc_checking_assert (!type_with_alias_set_p (expr)
> +		       || !canonical_type_used_p (expr)
> +		       || TYPE_ALIAS_SET (expr) != 0
> +		       || expr == char_type_node
> +		       || expr == signed_char_type_node
> +		       || expr == unsigned_char_type_node);
>    if (RECORD_OR_UNION_TYPE_P (expr))
>      {
>        bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
> Index: fold-const.c
> ===================================================================
> --- fold-const.c	(revision 231020)
> +++ fold-const.c	(working copy)
> @@ -2987,7 +2987,7 @@ operand_equal_p (const_tree arg0, const_
>  					   flags)))
>  		return 0;
>  	      /* Verify that accesses are TBAA compatible.  */
> -	      if (flag_strict_aliasing
> +	      if ((flag_strict_aliasing || !cfun->after_inlining)
>  		  && (!alias_ptr_types_compatible_p
>  		        (TREE_TYPE (TREE_OPERAND (arg0, 1)),
>  		         TREE_TYPE (TREE_OPERAND (arg1, 1)))
> Index: ada/gcc-interface/misc.c
> ===================================================================
> --- ada/gcc-interface/misc.c	(revision 231020)
> +++ ada/gcc-interface/misc.c	(working copy)
> @@ -592,13 +592,14 @@ gnat_get_alias_set (tree type)
>  {
>    /* If this is a padding type, use the type of the first field.  */
>    if (TYPE_IS_PADDING_P (type))
> -    return get_alias_set (TREE_TYPE (TYPE_FIELDS (type)));
> +    return get_alias_set (TREE_TYPE (TYPE_FIELDS (type)), true);
>  
>    /* If the type is an unconstrained array, use the type of the
>       self-referential array we make.  */
>    else if (TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
>      return
> -      get_alias_set (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (type)))));
> +      get_alias_set (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (type)))),
> +		     true);
>  
>    /* If the type can alias any other types, return the alias set 0.  */
>    else if (TYPE_P (type) && TYPE_UNIVERSAL_ALIASING_P (type))
> Index: ada/gcc-interface/utils.c
> ===================================================================
> --- ada/gcc-interface/utils.c	(revision 231020)
> +++ ada/gcc-interface/utils.c	(working copy)
> @@ -1520,14 +1520,14 @@ relate_alias_sets (tree gnu_new_type, tr
>  		      && TYPE_NONALIASED_COMPONENT (gnu_new_type)
>  			 != TYPE_NONALIASED_COMPONENT (gnu_old_type)));
>  
> -      TYPE_ALIAS_SET (gnu_new_type) = get_alias_set (gnu_old_type);
> +      TYPE_ALIAS_SET (gnu_new_type) = get_alias_set (gnu_old_type, true);
>        break;
>  
>      case ALIAS_SET_SUBSET:
>      case ALIAS_SET_SUPERSET:
>        {
> -	alias_set_type old_set = get_alias_set (gnu_old_type);
> -	alias_set_type new_set = get_alias_set (gnu_new_type);
> +	alias_set_type old_set = get_alias_set (gnu_old_type, true);
> +	alias_set_type new_set = get_alias_set (gnu_new_type, true);
>  
>  	/* Do nothing if the alias sets conflict.  This ensures that we
>  	   never call record_alias_subset several times for the same pair
> Index: ada/gcc-interface/trans.c
> ===================================================================
> --- ada/gcc-interface/trans.c	(revision 231020)
> +++ ada/gcc-interface/trans.c	(working copy)
> @@ -9702,11 +9702,13 @@ validate_unchecked_conversion (Node_Id g
>  				   ? TREE_TYPE (gnu_source_type)
>  				   : NULL_TREE;
>        tree gnu_target_desig_type = TREE_TYPE (gnu_target_type);
> -      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type);
> +      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type,
> +						       true);
>  
>        if (target_alias_set != 0
>  	  && (!POINTER_TYPE_P (gnu_source_type)
> -	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type),
> +	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type,
> +							true),
>  					 target_alias_set)))
>  	{
>  	  post_error_ne ("?possible aliasing problem for type&",
> @@ -9728,11 +9730,13 @@ validate_unchecked_conversion (Node_Id g
>  	  : NULL_TREE;
>        tree gnu_target_desig_type
>  	= TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_target_type)));
> -      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type);
> +      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type,
> +						       true);
>  
>        if (target_alias_set != 0
>  	  && (!TYPE_IS_FAT_POINTER_P (gnu_source_type)
> -	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type),
> +	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type,
> +							true),
>  					 target_alias_set)))
>  	{
>  	  post_error_ne ("?possible aliasing problem for type&",
> Index: gimple.c
> ===================================================================
> --- gimple.c	(revision 231020)
> +++ gimple.c	(working copy)
> @@ -2408,7 +2408,7 @@ gimple_get_alias_set (tree t)
>  
>        /* t1 == t can happen for boolean nodes which are always unsigned.  */
>        if (t1 != t)
> -	return get_alias_set (t1);
> +	return get_alias_set (t1, true);
>      }
>  
>    return -1;
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Fix verify_type ICE during Ada bootstrap
  2015-11-30 14:12             ` Richard Biener
@ 2015-11-30 17:11               ` Jan Hubicka
  0 siblings, 0 replies; 11+ messages in thread
From: Jan Hubicka @ 2015-11-30 17:11 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jan Hubicka, gcc-patches

> 
> I think you are doing too many things in one patch.  I'm fine with
> dropping the zero-alias-set streaming (but I'd rather not assert
> as FE get_alias_set langhook may assign zero to random tree nodes).

Ok, the assert was there mostly to double check that all zero alias
sets rematerialize correctly in LTO which I tested so it can go.
> 
> I'm also fine with handling flag_strict_aliasing conservatively
> during inlining - but the condition you placed on this handling
> needs a comment.  I couldn't decipher it ;)

OK, there is symmetric condition in ipa-inline-analysis, will comment on it.
It indeed can go in separately.
> 
> > +      if (dump_file)
> > +     fprintf (dump_file, "Dropping flag_strict_aliasing on %s:%i\n",
> > +              to->name (), to->order);
> 
> So I wonder if it makes sense to pessimize such inlining as well.

I don't know - even for Firefox that heavily mix -fstrict-aliasing
and -fno-strict-aliasing units this seems quite rare occasion and it
is hard to judge when dopping the flag_strict_aliasing.
> 
> The two above should be enough to fix the correctness issue.

We also need to prevent ipa-icf and fold_const from optimizing functions
early in a way that is not compatible with inlining -fno-strict-aliasing comdat
to -fstrict-aliasing function.

Honza
> 
> The parse_optimize_options hack looks indeed interesting, but we solved
> the issue differently by
> 
> 2014-11-27  Richard Biener  <rguenther@suse.de>
> 
>         PR middle-end/63704
>         * alias.c (mems_in_disjoint_alias_sets_p): Remove assert
>         and instead return false when !fstrict-aliasing.
> 
> So the hack can be removed as a separate commit after the first one
> above.  This should make optimize("fno-strict-aliasing") work.
> 
> 
> I don't really see why we need all the other changes and IMHO the
> get_alias_set interface change is ugly and fragile.  And this doesn't
> look like sth for stage3.
> 
> Thus please split the patch up.
> 
> Thanks,
> Richard.
> 
> > Honza
> > 
> > 	* tree.c (free_lang_data): Pass true to get_alias_set.
> > 	* tree-streamer-in.c (unpack_ts_type_common_value_fields): Do not stream
> > 	alias set.
> > 	* tree-ssa-alias.c (ao_ref_base_alias_set, ao_ref_alias_set): Pass true
> > 	to get_alias_set; comment.
> > 	(same_type_for_tbaa): Likewise.
> > 	* alias.c (alias_set_subset_of, alias_sets_conflict_p): When strict
> > 	aliasing is disabled, return true.
> > 	(get_alias_set): New parameter strict.
> > 	(new_alias_set): Always produce new alias set.
> > 	(record_component_aliases): Pass true to get_alias_set.
> > 	* alias.h (get_alias_set): New optional parameter STRICT.
> > 	* lto-streamer-out.c (hash_tree): Do not hash alias set.
> > 	* ipa-inline-transform.c (inline_call): Drop strict aliasing of
> > 	caller if needed.
> > 	* ipa-icf-gimple.c (func_checker::compatible_types_p): Pass true
> > 	to get_alias_set.
> > 	* tree-streamer-out.c (pack_ts_type_common_value_fields): Do not
> > 	stream TYPE_ALIAS_SET; sanity check that alias set 0 at LTO time will
> > 	match what frontneds does.
> > 	* fold-const.c (operand_equal_p): Be cureful about TBAA info before
> > 	inlining even with -fno-strict-aliasing.
> > 	* gimple.c (gimple_get_alias_set): Pass true to get_alias_set.
> > 
> > 	* misc.c (gnat_get_alias_set): Pass true to get_alias_set.
> > 	* utils.c (relate_alias_sets): Likewise.
> > 	* trans.c (validate_unchecked_conversion): Likewise.
> > 
> > 	* lto-symtab.c (warn_type_compatibility_p): Pass true to get_alias_set.
> > 	* lto.c (compare_tree_sccs_1): Do not ocmpare TYPE_ALIAS_SET.
> > 
> > 	* gcc.c-torture/execute/alias-1.c: New testcase.
> > 	* gcc.dg/lto/alias-1_0.c: New testcase.
> > 	* gcc.dg/lto/alias-1_1.c: New testcase.
> > 
> > 	* c-common.c (parse_optimize_options): Remove hack about
> > 	flag_strict_aliasing.
> > 	(convert_vector_to_pointer_for_subscript): Pass true to get_alias_set.
> > 
> > 	* cp-objcp-common.c (cxx_get_alias_set): Pass true to get_alias_set.
> > 	
> > 	* rtti.c (typeid_ok_p): Pass true to get_alias_set.
> > Index: tree.c
> > ===================================================================
> > --- tree.c	(revision 231020)
> > +++ tree.c	(working copy)
> > @@ -5971,7 +5971,8 @@ free_lang_data (void)
> >       while the slots are still in the way the frontends generated them.  */
> >    for (i = 0; i < itk_none; ++i)
> >      if (integer_types[i])
> > -      TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i]);
> > +      TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i],
> > +							 true);
> >  
> >    /* Traverse the IL resetting language specific information for
> >       operands, expressions, etc.  */
> > Index: cp/rtti.c
> > ===================================================================
> > --- cp/rtti.c	(revision 231020)
> > +++ cp/rtti.c	(working copy)
> > @@ -300,10 +300,10 @@ typeid_ok_p (void)
> >    /* Make sure abi::__type_info_pseudo has the same alias set
> >       as std::type_info.  */
> >    if (! TYPE_ALIAS_SET_KNOWN_P (pseudo_type_info))
> > -    TYPE_ALIAS_SET (pseudo_type_info) = get_alias_set (type_info_type);
> > +    TYPE_ALIAS_SET (pseudo_type_info) = get_alias_set (type_info_type, true);
> >    else
> >      gcc_assert (TYPE_ALIAS_SET (pseudo_type_info)
> > -		== get_alias_set (type_info_type));
> > +		== get_alias_set (type_info_type, true));
> >  
> >    return true;
> >  }
> > Index: cp/cp-objcp-common.c
> > ===================================================================
> > --- cp/cp-objcp-common.c	(revision 231020)
> > +++ cp/cp-objcp-common.c	(working copy)
> > @@ -32,7 +32,7 @@ cxx_get_alias_set (tree t)
> >    if (IS_FAKE_BASE_TYPE (t))
> >      /* The base variant of a type must be in the same alias set as the
> >         complete type.  */
> > -    return get_alias_set (TYPE_CONTEXT (t));
> > +    return get_alias_set (TYPE_CONTEXT (t), true);
> >  
> >    /* Punt on PMFs until we canonicalize functions properly.  */
> >    if (TYPE_PTRMEMFUNC_P (t)
> > Index: tree-streamer-in.c
> > ===================================================================
> > --- tree-streamer-in.c	(revision 231020)
> > +++ tree-streamer-in.c	(working copy)
> > @@ -366,7 +366,6 @@ unpack_ts_type_common_value_fields (stru
> >    TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
> >    TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
> >    TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);
> > -  TYPE_ALIAS_SET (expr) = bp_unpack_value (bp, 1) ? 0 : -1;
> >    if (RECORD_OR_UNION_TYPE_P (expr))
> >      {
> >        TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
> > Index: tree-ssa-alias.c
> > ===================================================================
> > --- tree-ssa-alias.c	(revision 231020)
> > +++ tree-ssa-alias.c	(working copy)
> > @@ -563,7 +563,10 @@ ao_ref_base_alias_set (ao_ref *ref)
> >    base_ref = ref->ref;
> >    while (handled_component_p (base_ref))
> >      base_ref = TREE_OPERAND (base_ref, 0);
> > -  ref->base_alias_set = get_alias_set (base_ref);
> > +  /* Do not return 0 in case of strict aliasing; this function is used at
> > +     IPA level by ipa-icf-gimple.c.  It is job of caller to give up on
> > +     using TBAA oracle when asked to not do so.  */
> > +  ref->base_alias_set = get_alias_set (base_ref, true);
> >    return ref->base_alias_set;
> >  }
> >  
> > @@ -574,7 +577,10 @@ ao_ref_alias_set (ao_ref *ref)
> >  {
> >    if (ref->ref_alias_set != -1)
> >      return ref->ref_alias_set;
> > -  ref->ref_alias_set = get_alias_set (ref->ref);
> > +  /* Do not return 0 in case of strict aliasing; this function is used at
> > +     IPA level by ipa-icf-gimple.c.  It is job of caller to give up on
> > +     using TBAA oracle when asked to not do so.  */
> > +  ref->ref_alias_set = get_alias_set (ref->ref, true);
> >    return ref->ref_alias_set;
> >  }
> >  
> > @@ -668,7 +674,7 @@ same_type_for_tbaa (tree type1, tree typ
> >       would mean that conversions between them are useless, whereas they are
> >       not (e.g. type and subtypes can have different modes).  So, in the end,
> >       they are only guaranteed to have the same alias set.  */
> > -  if (get_alias_set (type1) == get_alias_set (type2))
> > +  if (get_alias_set (type1, true) == get_alias_set (type2, true))
> >      return -1;
> >  
> >    /* The types are known to be not equal.  */
> > Index: alias.c
> > ===================================================================
> > --- alias.c	(revision 231020)
> > +++ alias.c	(working copy)
> > @@ -406,7 +406,7 @@ alias_set_subset_of (alias_set_type set1
> >    alias_set_entry *ase2;
> >  
> >    /* Everything is a subset of the "aliases everything" set.  */
> > -  if (set2 == 0)
> > +  if (set2 == 0 || !flag_strict_aliasing)
> >      return true;
> >  
> >    /* Check if set1 is a subset of set2.  */
> > @@ -467,7 +467,7 @@ alias_sets_conflict_p (alias_set_type se
> >    alias_set_entry *ase2;
> >  
> >    /* The easy case.  */
> > -  if (alias_sets_must_conflict_p (set1, set2))
> > +  if (!flag_strict_aliasing || alias_sets_must_conflict_p (set1, set2))
> >      return 1;
> >  
> >    /* See if the first alias set is a subset of the second.  */
> > @@ -809,17 +809,21 @@ init_alias_set_entry (alias_set_type set
> >  }
> >  
> >  /* Return the alias set for T, which may be either a type or an
> > -   expression.  Call language-specific routine for help, if needed.  */
> > +   expression.  Call language-specific routine for help, if needed.
> > +   If STRICT is true, ignore value of flag_strict_aliasing.  This is needed
> > +   in cases we are in -fno-strict-aliasing region but still need to compute
> > +   alias sets for some reason (this is used, for example, by rtti code to copy
> > +   alias set from type to type).  */
> >  
> >  alias_set_type
> > -get_alias_set (tree t)
> > +get_alias_set (tree t, bool strict)
> >  {
> >    alias_set_type set;
> >  
> >    /* If we're not doing any alias analysis, just assume everything
> >       aliases everything else.  Also return 0 if this or its type is
> >       an error.  */
> > -  if (! flag_strict_aliasing || t == error_mark_node
> > +  if ((! flag_strict_aliasing && !strict)|| t == error_mark_node
> >        || (! TYPE_P (t)
> >  	  && (TREE_TYPE (t) == 0 || TREE_TYPE (t) == error_mark_node)))
> >      return 0;
> > @@ -898,7 +902,7 @@ get_alias_set (tree t)
> >        /* For arrays with unknown size the conservative answer is the
> >  	 alias set of the element type.  */
> >        if (TREE_CODE (t) == ARRAY_TYPE)
> > -	return get_alias_set (TREE_TYPE (t));
> > +	return get_alias_set (TREE_TYPE (t), true);
> >  
> >        /* But return zero as a conservative answer for incomplete types.  */
> >        return 0;
> > @@ -920,7 +924,7 @@ get_alias_set (tree t)
> >       normal usage.  And indeed lets vectors be treated more like an
> >       array slice.  */
> >    else if (TREE_CODE (t) == VECTOR_TYPE)
> > -    set = get_alias_set (TREE_TYPE (t));
> > +    set = get_alias_set (TREE_TYPE (t), true);
> >  
> >    /* Unless the language specifies otherwise, treat array types the
> >       same as their components.  This avoids the asymmetry we get
> > @@ -933,7 +937,7 @@ get_alias_set (tree t)
> >    else if (TREE_CODE (t) == ARRAY_TYPE
> >  	   && (!TYPE_NONALIASED_COMPONENT (t)
> >  	       || TYPE_STRUCTURAL_EQUALITY_P (t)))
> > -    set = get_alias_set (TREE_TYPE (t));
> > +    set = get_alias_set (TREE_TYPE (t), true);
> >  
> >    /* From the former common C and C++ langhook implementation:
> >  
> > @@ -997,7 +1001,7 @@ get_alias_set (tree t)
> >  	 (see record_component_aliases) and thus it is safe it to use it for
> >  	 pointers to types with TYPE_STRUCTURAL_EQUALITY_P.  */
> >        if (TREE_CODE (p) == VOID_TYPE || TYPE_STRUCTURAL_EQUALITY_P (p))
> > -	set = get_alias_set (ptr_type_node);
> > +	set = get_alias_set (ptr_type_node, true);
> >        else
> >  	{
> >  	  /* Rebuild pointer type starting from canonical types using
> > @@ -1085,15 +1089,10 @@ get_alias_set (tree t)
> >  alias_set_type
> >  new_alias_set (void)
> >  {
> > -  if (flag_strict_aliasing)
> > -    {
> > -      if (alias_sets == 0)
> > -	vec_safe_push (alias_sets, (alias_set_entry *) NULL);
> > -      vec_safe_push (alias_sets, (alias_set_entry *) NULL);
> > -      return alias_sets->length () - 1;
> > -    }
> > -  else
> > -    return 0;
> > +  if (alias_sets == 0)
> > +    vec_safe_push (alias_sets, (alias_set_entry *) NULL);
> > +  vec_safe_push (alias_sets, (alias_set_entry *) NULL);
> > +  return alias_sets->length () - 1;
> >  }
> >  
> >  /* Indicate that things in SUBSET can alias things in SUPERSET, but that
> > @@ -1169,7 +1168,7 @@ record_alias_subset (alias_set_type supe
> >  void
> >  record_component_aliases (tree type)
> >  {
> > -  alias_set_type superset = get_alias_set (type);
> > +  alias_set_type superset = get_alias_set (type, true);
> >    tree field;
> >  
> >    if (superset == 0)
> > @@ -1215,16 +1214,17 @@ record_component_aliases (tree type)
> >  		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)));
> > +		  gcc_checking_assert (get_alias_set (t, true)
> > +				       == get_alias_set (TREE_TYPE (field),
> > +							 true));
> >  	      }
> >  
> > -	    record_alias_subset (superset, get_alias_set (t));
> > +	    record_alias_subset (superset, get_alias_set (t, true));
> >  	  }
> >        break;
> >  
> >      case COMPLEX_TYPE:
> > -      record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
> > +      record_alias_subset (superset, get_alias_set (TREE_TYPE (type), true));
> >        break;
> >  
> >      /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
> > Index: alias.h
> > ===================================================================
> > --- alias.h	(revision 231020)
> > +++ alias.h	(working copy)
> > @@ -21,7 +21,7 @@ along with GCC; see the file COPYING3.
> >  #define GCC_ALIAS_H
> >  
> >  extern alias_set_type new_alias_set (void);
> > -extern alias_set_type get_alias_set (tree);
> > +extern alias_set_type get_alias_set (tree, bool strict = false);
> >  extern alias_set_type get_deref_alias_set (tree);
> >  extern alias_set_type get_varargs_alias_set (void);
> >  extern alias_set_type get_frame_alias_set (void);
> > Index: lto/lto-symtab.c
> > ===================================================================
> > --- lto/lto-symtab.c	(revision 231020)
> > +++ lto/lto-symtab.c	(working copy)
> > @@ -276,8 +276,8 @@ warn_type_compatibility_p (tree prevaili
> >       we make ptr_type_node to TBAA compatible with every other type.  */
> >    if (type_with_alias_set_p (type) && type_with_alias_set_p (prevailing_type))
> >      {
> > -      alias_set_type set1 = get_alias_set (type);
> > -      alias_set_type set2 = get_alias_set (prevailing_type);
> > +      alias_set_type set1 = get_alias_set (type, true);
> > +      alias_set_type set2 = get_alias_set (prevailing_type, true);
> >  
> >        if (set1 && set2 && set1 != set2 
> >            && (!POINTER_TYPE_P (type) || !POINTER_TYPE_P (prevailing_type)
> > Index: lto/lto.c
> > ===================================================================
> > --- lto/lto.c	(revision 231020)
> > +++ lto/lto.c	(working copy)
> > @@ -1166,7 +1166,9 @@ compare_tree_sccs_1 (tree t1, tree t2, t
> >        compare_values (TYPE_READONLY);
> >        compare_values (TYPE_PRECISION);
> >        compare_values (TYPE_ALIGN);
> > -      compare_values (TYPE_ALIAS_SET);
> > +      /* Do not compare TYPE_ALIAS_SET.  Doing so introduce ordering issues
> > +         with calls to get_alias_set which may initialize it for streamed
> > + 	 in types.  */
> >      }
> >  
> >    /* We don't want to compare locations, so there is nothing do compare
> > Index: testsuite/gcc.c-torture/execute/alias-1.c
> > ===================================================================
> > --- testsuite/gcc.c-torture/execute/alias-1.c	(revision 0)
> > +++ testsuite/gcc.c-torture/execute/alias-1.c	(revision 0)
> > @@ -0,0 +1,19 @@
> > +int val;
> > +
> > +int *ptr = &val;
> > +float *ptr2 = &val;
> > +
> > +__attribute__((optimize ("-fno-strict-aliasing")))
> > +typepun ()
> > +{
> > +  *ptr2=0;
> > +}
> > +
> > +main()
> > +{
> > +  *ptr=1;
> > +  typepun ();
> > +  if (*ptr)
> > +    __builtin_abort ();
> > +}
> > +
> > Index: testsuite/gcc.dg/lto/alias-1_0.c
> > ===================================================================
> > --- testsuite/gcc.dg/lto/alias-1_0.c	(revision 0)
> > +++ testsuite/gcc.dg/lto/alias-1_0.c	(revision 0)
> > @@ -0,0 +1,22 @@
> > +/* { dg-lto-do run } */
> > +/* { dg-lto-options { { -O2 -flto } } } */
> > +int val;
> > +
> > +int *ptr = &val;
> > +float *ptr2 = &val;
> > +
> > +extern void typefun(void);
> > +
> > +void link_error (void);
> > +
> > +int
> > +main()
> > +{ 
> > +  *ptr=1;
> > +  typefun ();
> > +  if (*ptr)
> > +    /*link_error ();*/
> > +    __builtin_abort ();
> > +  return 0;
> > +}
> > +
> > Index: testsuite/gcc.dg/lto/alias-1_1.c
> > ===================================================================
> > --- testsuite/gcc.dg/lto/alias-1_1.c	(revision 0)
> > +++ testsuite/gcc.dg/lto/alias-1_1.c	(revision 0)
> > @@ -0,0 +1,8 @@
> > +/* { dg-options "-fno-strict-aliasing" } */
> > +extern float *ptr2;
> > +void
> > +__attribute__((optimize ("-fno-strict-aliasing")))
> > +typefun ()
> > +{ 
> > +  *ptr2=0;
> > +}
> > Index: c-family/c-common.c
> > ===================================================================
> > --- c-family/c-common.c	(revision 231048)
> > +++ c-family/c-common.c	(working copy)
> > @@ -9988,7 +9988,6 @@ parse_optimize_options (tree args, bool
> >    bool ret = true;
> >    unsigned opt_argc;
> >    unsigned i;
> > -  int saved_flag_strict_aliasing;
> >    const char **opt_argv;
> >    struct cl_decoded_option *decoded_options;
> >    unsigned int decoded_options_count;
> > @@ -10081,8 +10080,6 @@ parse_optimize_options (tree args, bool
> >    for (i = 1; i < opt_argc; i++)
> >      opt_argv[i] = (*optimize_args)[i];
> >  
> > -  saved_flag_strict_aliasing = flag_strict_aliasing;
> > -
> >    /* Now parse the options.  */
> >    decode_cmdline_options_to_array_default_mask (opt_argc, opt_argv,
> >  						&decoded_options,
> > @@ -10093,9 +10090,6 @@ parse_optimize_options (tree args, bool
> >  
> >    targetm.override_options_after_change();
> >  
> > -  /* Don't allow changing -fstrict-aliasing.  */
> > -  flag_strict_aliasing = saved_flag_strict_aliasing;
> > -
> >    optimize_args->truncate (0);
> >    return ret;
> >  }
> > @@ -12930,8 +12924,8 @@ convert_vector_to_pointer_for_subscript
> >  	  /* If the original vector isn't declared may_alias and it
> >  	     isn't a bare vector look if the subscripting would
> >  	     alias the vector we subscript, and if not, force ref-all.  */
> > -	  alias_set_type vecset = get_alias_set (*vecp);
> > -	  alias_set_type sset = get_alias_set (type);
> > +	  alias_set_type vecset = get_alias_set (*vecp, true);
> > +	  alias_set_type sset = get_alias_set (type, true);
> >  	  if (!alias_sets_must_conflict_p (sset, vecset)
> >  	      && !alias_set_subset_of (sset, vecset))
> >  	    ref_all = true;
> > Index: lto-streamer-out.c
> > ===================================================================
> > --- lto-streamer-out.c	(revision 231020)
> > +++ lto-streamer-out.c	(working copy)
> > @@ -1109,10 +1109,6 @@ hash_tree (struct streamer_tree_cache_d
> >        hstate.commit_flag ();
> >        hstate.add_int (TYPE_PRECISION (t));
> >        hstate.add_int (TYPE_ALIGN (t));
> > -      hstate.add_int ((TYPE_ALIAS_SET (t) == 0
> > -					 || (!in_lto_p
> > -					     && get_alias_set (t) == 0))
> > -					? 0 : -1);
> >      }
> >  
> >    if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
> > Index: ipa-inline-transform.c
> > ===================================================================
> > --- ipa-inline-transform.c	(revision 231020)
> > +++ ipa-inline-transform.c	(working copy)
> > @@ -322,6 +322,23 @@ inline_call (struct cgraph_edge *e, bool
> >    if (DECL_FUNCTION_PERSONALITY (callee->decl))
> >      DECL_FUNCTION_PERSONALITY (to->decl)
> >        = DECL_FUNCTION_PERSONALITY (callee->decl);
> > +  if (!opt_for_fn (callee->decl, flag_strict_aliasing)
> > +      && opt_for_fn (to->decl, flag_strict_aliasing)
> > +      && (!callee->merged
> > +	  || lookup_attribute ("optimization", DECL_ATTRIBUTES (e->caller->decl))
> > +	  || lookup_attribute ("optimization", DECL_ATTRIBUTES (callee->decl))))
> > +    {
> > +      struct gcc_options opts = global_options;
> > +      cl_optimization_restore (&opts,
> > +	 TREE_OPTIMIZATION (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (to->decl)));
> > +      opts.x_flag_strict_aliasing = false;
> > +      if (dump_file)
> > +	fprintf (dump_file, "Dropping flag_strict_aliasing on %s:%i\n",
> > +		 to->name (), to->order);
> > +      build_optimization_node (&opts);
> > +      DECL_FUNCTION_SPECIFIC_OPTIMIZATION (to->decl)
> > +	 = build_optimization_node (&opts);
> > +    }
> >  
> >    /* If aliases are involved, redirect edge to the actual destination and
> >       possibly remove the aliases.  */
> > Index: ipa-icf-gimple.c
> > ===================================================================
> > --- ipa-icf-gimple.c	(revision 231020)
> > +++ ipa-icf-gimple.c	(working copy)
> > @@ -241,7 +241,7 @@ func_checker::compatible_types_p (tree t
> >       For time being just avoid calling get_alias_set on types that are not
> >       having alias sets defined at all.  */
> >    if (type_with_alias_set_p (t1) && type_with_alias_set_p (t2)
> > -      && get_alias_set (t1) != get_alias_set (t2))
> > +      && get_alias_set (t1, true) != get_alias_set (t2, true))
> >      return return_false_with_msg ("alias sets are different");
> >  
> >    return true;
> > Index: tree-streamer-out.c
> > ===================================================================
> > --- tree-streamer-out.c	(revision 231020)
> > +++ tree-streamer-out.c	(working copy)
> > @@ -317,13 +321,18 @@ pack_ts_type_common_value_fields (struct
> >    bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
> >    bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
> >    bp_pack_value (bp, TYPE_READONLY (expr), 1);
> > -  /* Make sure to preserve the fact whether the frontend would assign
> > -     alias-set zero to this type.  Do that only for main variants, because
> > -     type variants alias sets are never computed.
> > -     FIXME:  This does not work for pre-streamed builtin types.  */
> > -  bp_pack_value (bp, (TYPE_ALIAS_SET (expr) == 0
> > -		      || (!in_lto_p && TYPE_MAIN_VARIANT (expr) == expr
> > -			  && get_alias_set (expr) == 0)), 1);
> > +  /* We used to stream TYPE_ALIAS_SET == 0 information to let frontends mark
> > +     types that are opaque for TBAA.  This however did not work as intended,
> > +     becuase TYPE_ALIAS_SET == 0 was regularly lost in type merging.
> > +
> > +     Instead now double check that all aliaset set 0 types will be alias set
> > +     0 in LTO world, too.  */
> > +  gcc_checking_assert (!type_with_alias_set_p (expr)
> > +		       || !canonical_type_used_p (expr)
> > +		       || TYPE_ALIAS_SET (expr) != 0
> > +		       || expr == char_type_node
> > +		       || expr == signed_char_type_node
> > +		       || expr == unsigned_char_type_node);
> >    if (RECORD_OR_UNION_TYPE_P (expr))
> >      {
> >        bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
> > Index: fold-const.c
> > ===================================================================
> > --- fold-const.c	(revision 231020)
> > +++ fold-const.c	(working copy)
> > @@ -2987,7 +2987,7 @@ operand_equal_p (const_tree arg0, const_
> >  					   flags)))
> >  		return 0;
> >  	      /* Verify that accesses are TBAA compatible.  */
> > -	      if (flag_strict_aliasing
> > +	      if ((flag_strict_aliasing || !cfun->after_inlining)
> >  		  && (!alias_ptr_types_compatible_p
> >  		        (TREE_TYPE (TREE_OPERAND (arg0, 1)),
> >  		         TREE_TYPE (TREE_OPERAND (arg1, 1)))
> > Index: ada/gcc-interface/misc.c
> > ===================================================================
> > --- ada/gcc-interface/misc.c	(revision 231020)
> > +++ ada/gcc-interface/misc.c	(working copy)
> > @@ -592,13 +592,14 @@ gnat_get_alias_set (tree type)
> >  {
> >    /* If this is a padding type, use the type of the first field.  */
> >    if (TYPE_IS_PADDING_P (type))
> > -    return get_alias_set (TREE_TYPE (TYPE_FIELDS (type)));
> > +    return get_alias_set (TREE_TYPE (TYPE_FIELDS (type)), true);
> >  
> >    /* If the type is an unconstrained array, use the type of the
> >       self-referential array we make.  */
> >    else if (TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
> >      return
> > -      get_alias_set (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (type)))));
> > +      get_alias_set (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (type)))),
> > +		     true);
> >  
> >    /* If the type can alias any other types, return the alias set 0.  */
> >    else if (TYPE_P (type) && TYPE_UNIVERSAL_ALIASING_P (type))
> > Index: ada/gcc-interface/utils.c
> > ===================================================================
> > --- ada/gcc-interface/utils.c	(revision 231020)
> > +++ ada/gcc-interface/utils.c	(working copy)
> > @@ -1520,14 +1520,14 @@ relate_alias_sets (tree gnu_new_type, tr
> >  		      && TYPE_NONALIASED_COMPONENT (gnu_new_type)
> >  			 != TYPE_NONALIASED_COMPONENT (gnu_old_type)));
> >  
> > -      TYPE_ALIAS_SET (gnu_new_type) = get_alias_set (gnu_old_type);
> > +      TYPE_ALIAS_SET (gnu_new_type) = get_alias_set (gnu_old_type, true);
> >        break;
> >  
> >      case ALIAS_SET_SUBSET:
> >      case ALIAS_SET_SUPERSET:
> >        {
> > -	alias_set_type old_set = get_alias_set (gnu_old_type);
> > -	alias_set_type new_set = get_alias_set (gnu_new_type);
> > +	alias_set_type old_set = get_alias_set (gnu_old_type, true);
> > +	alias_set_type new_set = get_alias_set (gnu_new_type, true);
> >  
> >  	/* Do nothing if the alias sets conflict.  This ensures that we
> >  	   never call record_alias_subset several times for the same pair
> > Index: ada/gcc-interface/trans.c
> > ===================================================================
> > --- ada/gcc-interface/trans.c	(revision 231020)
> > +++ ada/gcc-interface/trans.c	(working copy)
> > @@ -9702,11 +9702,13 @@ validate_unchecked_conversion (Node_Id g
> >  				   ? TREE_TYPE (gnu_source_type)
> >  				   : NULL_TREE;
> >        tree gnu_target_desig_type = TREE_TYPE (gnu_target_type);
> > -      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type);
> > +      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type,
> > +						       true);
> >  
> >        if (target_alias_set != 0
> >  	  && (!POINTER_TYPE_P (gnu_source_type)
> > -	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type),
> > +	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type,
> > +							true),
> >  					 target_alias_set)))
> >  	{
> >  	  post_error_ne ("?possible aliasing problem for type&",
> > @@ -9728,11 +9730,13 @@ validate_unchecked_conversion (Node_Id g
> >  	  : NULL_TREE;
> >        tree gnu_target_desig_type
> >  	= TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_target_type)));
> > -      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type);
> > +      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type,
> > +						       true);
> >  
> >        if (target_alias_set != 0
> >  	  && (!TYPE_IS_FAT_POINTER_P (gnu_source_type)
> > -	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type),
> > +	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type,
> > +							true),
> >  					 target_alias_set)))
> >  	{
> >  	  post_error_ne ("?possible aliasing problem for type&",
> > Index: gimple.c
> > ===================================================================
> > --- gimple.c	(revision 231020)
> > +++ gimple.c	(working copy)
> > @@ -2408,7 +2408,7 @@ gimple_get_alias_set (tree t)
> >  
> >        /* t1 == t can happen for boolean nodes which are always unsigned.  */
> >        if (t1 != t)
> > -	return get_alias_set (t1);
> > +	return get_alias_set (t1, true);
> >      }
> >  
> >    return -1;
> > 
> > 
> 
> -- 
> Richard Biener <rguenther@suse.de>
> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2015-11-30 17:09 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-24  8:25 Fix verify_type ICE during Ada bootstrap Jan Hubicka
2015-11-24  9:00 ` Richard Biener
2015-11-24 18:55   ` Jan Hubicka
2015-11-24 19:45     ` Jan Hubicka
2015-11-25 10:55       ` Richard Biener
2015-11-27  7:30         ` Jan Hubicka
2015-11-30  7:22           ` Jan Hubicka
2015-11-30  7:55             ` Eric Botcazou
2015-11-30  8:05               ` Jan Hubicka
2015-11-30 14:12             ` Richard Biener
2015-11-30 17:11               ` Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).