The following fixes the assert in mems_in_disjoint_alias_sets_p trigger. What the comment says can easily happen by using attribute((optimize("O3"))) inside a -fno-strict-aliasing TU. Dependent on luck a global variable may get a alias-set non-zero MEM if expanded from the -O3 context and thus the assert triggers for uses in a -fno-strict-aliasing function.
Fixed by ignoring recorded alias-sets for -fno-strict-aliasing like we do everywhere else. Another possibility is to not allow changing -fstrict-aliasing via the optimize attribute (but then the same may happen via LTO of a -O0 and a -O3 unit and pre-recorded type mems). Bootstrap & regtest pending on x86_64-unknown-linux-gnu. Richard. 2014-11-26 Richard Biener <rguent...@suse.de> PR middle-end/63704 * alias.c (mems_in_disjoint_alias_sets_p): Remove assert and instead return false when !fstrict-aliasing. Index: gcc/alias.c =================================================================== --- gcc/alias.c (revision 218078) +++ gcc/alias.c (working copy) @@ -417,17 +417,9 @@ get_alias_set_entry (alias_set_type alia static inline int mems_in_disjoint_alias_sets_p (const_rtx mem1, const_rtx mem2) { -/* Perform a basic sanity check. Namely, that there are no alias sets - if we're not using strict aliasing. This helps to catch bugs - whereby someone uses PUT_CODE, but doesn't clear MEM_ALIAS_SET, or - where a MEM is allocated in some way other than by the use of - gen_rtx_MEM, and the MEM_ALIAS_SET is not cleared. If we begin to - use alias sets to indicate that spilled registers cannot alias each - other, we might need to remove this check. */ - gcc_assert (flag_strict_aliasing - || (!MEM_ALIAS_SET (mem1) && !MEM_ALIAS_SET (mem2))); - - return ! alias_sets_conflict_p (MEM_ALIAS_SET (mem1), MEM_ALIAS_SET (mem2)); + return (flag_strict_aliasing + && ! alias_sets_conflict_p (MEM_ALIAS_SET (mem1), + MEM_ALIAS_SET (mem2))); } /* Return true if the first alias set is a subset of the second. */