===================================================================
@@ -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. */
===================================================================
@@ -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;
===================================================================
@@ -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
===================================================================
@@ -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);
===================================================================
@@ -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;
}
===================================================================
@@ -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)))
===================================================================
@@ -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)
===================================================================
@@ -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);
===================================================================
@@ -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;
}
===================================================================
@@ -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);
===================================================================
@@ -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;
+}
+
===================================================================
@@ -0,0 +1,7 @@
+/* { dg-options "-fno-strict-aliasing" } */
+extern float *ptr2;
+__attribute__((optimize ("-fno-strict-aliasing")))
+typefun ()
+{
+ *ptr2=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 ();
+}
+
===================================================================
@@ -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. */