https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93946
--- Comment #18 from sandra at gcc dot gnu.org --- Hmmm, it looks to me like things are going wrong in the tree fre1 pass too. I commented out the redundant zero store in the test case to see what would happen, like long __attribute__((noipa)) foo (struct bb *bv, void *ptr) { struct aa *a = ptr; struct bb *b = ptr; bv->b.u.f = 1; a->a.u.i = 0; /* b->b.u.f = 0; */ return bv->b.u.f; } fre1 gets this as input: __attribute__((noipa, noinline, noclone, no_icf)) foo (struct bb * bv, void * ptr) { struct bb * b; struct aa * a; long int _8; <bb 2> : bv_5(D)->b.u.f = 1; MEM[(struct aa *)ptr_1(D)].a.u.i = 0; _8 = bv_5(D)->b.u.f; return _8; } and produces this output: __attribute__((noipa, noinline, noclone, no_icf)) foo (struct bb * bv, void * ptr) { struct bb * b; struct aa * a; <bb 2> : bv_5(D)->b.u.f = 1; MEM[(struct aa *)ptr_1(D)].a.u.i = 0; return 1; } This is with -O2. Again, it seems like something is not realizing that pointer parameters can be aliased no matter what their types are. Or perhaps that is just a symptom of some other underlying bug. :-S