https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111231
--- Comment #30 from Richard Biener <rguenth at gcc dot gnu.org> --- I have tested the following since that might confuse the redundant store removal sanity checks. It bootstraps fine on x86-64-unknown-linux-gnu but causes FAIL: gcc.dg/tree-ssa/ssa-dse-36.c scan-tree-dump-times dse1 "Deleted redundant call" 3 FAIL: gcc.dg/tree-ssa/ssa-dse-36.c scan-tree-dump-times dse1 "Deleted redundant store" 3 in particular foo1 and foo2 are no longer optimized. Specifically foo1: - x = {}; + MEM <char[10]> [(struct X *)&x] = {}; + memset (&x.mem1, 0, 10); the lack of the 'memset' removal looks fishy since memset uses alias set zero while the earlier store uses the alias set of struct X (but contains alias set zero because of the char[] members). For foo2: x = {}; + x.mem1[5] = 0; the issue is less clear since 'x' is also involved in the store to x.mem1[5] (but that store also uses alias-set zero). This shows the situation is a bit odd wrt the behavior of a whole-aggregate store vs. a component-wise store. But again in both cases a later conflict check with say *(int *)p, while conflicting with the memset and x.mem1[5] stores, would not conflict with the x = {} store. So this fallout is to be expected and desired. diff --git a/gcc/alias.cc b/gcc/alias.cc index 808e2095d9b..bacae30db18 100644 --- a/gcc/alias.cc +++ b/gcc/alias.cc @@ -427,9 +427,7 @@ alias_set_subset_of (alias_set_type set1, alias_set_type set2) /* Check if set1 is a subset of set2. */ ase2 = get_alias_set_entry (set2); - if (ase2 != 0 - && (ase2->has_zero_child - || (ase2->children && ase2->children->get (set1)))) + if (ase2 != 0 && ase2->children && ase2->children->get (set1)) return true; /* As a special case we consider alias set of "void *" to be both subset