https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71002
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> --- So PRE sees: <bb 2>: # .MEM_3 = VDEF <.MEM_1(D)> MEM[(struct &)this_2(D)] ={v} {CLOBBER}; # .MEM_14 = VDEF <.MEM_3> MEM[(struct &)this_2(D)] ={v} {CLOBBER}; # .MEM_15 = VDEF <.MEM_14> MEM[(struct short_t &)this_2(D)].h.is_short = 1; # .MEM_16 = VDEF <.MEM_15> MEM[(struct short_t &)this_2(D)].h.length = 0; # .MEM_17 = VDEF <.MEM_16> MEM[(struct short_t &)this_2(D)].data[0] = 0; # VUSE <.MEM_17> _19 = BIT_FIELD_REF <MEM[(const struct string *)this_2(D)], 8, 0>; _20 = _19 & 1; if (_20 != 0) goto <bb 3>; else goto <bb 6>; <bb 3>: # VUSE <.MEM_17> _21 = BIT_FIELD_REF <MEM[(const struct string *)str_5(D)], 8, 0>; _22 = _21 & 1; if (_22 != 0) goto <bb 4>; else goto <bb 5>; <bb 5>: # .MEM_34 = VDEF <.MEM_17> short_backup = MEM[(const struct short_t &)this_2(D)]; # .MEM_35 = VDEF <.MEM_34> MEM[(struct long_t *)this_2(D)] = MEM[(const struct long_t *)str_5(D)]; # .MEM_36 = VDEF <.MEM_35> MEM[(struct short_t *)str_5(D)] = short_backup; # .MEM_37 = VDEF <.MEM_36> short_backup ={v} {CLOBBER}; goto <bb 10>; <bb 10>: # .MEM_29 = PHI <.MEM_33(13), .MEM_37(5)> # VUSE <.MEM_29> _9 = MEM[(const struct short_t &)this_2(D)].h.length; _10 = (long unsigned int) _9; goto <bb 12>; and it concludes that on the path bb2 -> bb5 -> bb10 nothing can clobber MEM[(const struct short_t &)this_2(D)].h.length and thus it is safe to replace it with zero (from the init in bb2). The "obvious" clobbering candidate is # .MEM_35 = VDEF <.MEM_34> MEM[(struct long_t *)this_2(D)] = MEM[(const struct long_t *)str_5(D)]; but that is storing using a different type. So the error must happen earlier. It might be as early as the BIT_FIELD_REF folding of the is_short read which does _19 = BIT_FIELD_REF <MEM[(const struct string *)_4], 8, 0>; It is DOM who threads further reads from the above again not considering the above store clobbering a read via 'struct string' (which does not include long_t in its alias subsets). Thus mine (to fix optimize_bit_field_compare).