------- Additional Comments From rguenth at gcc dot gnu dot org 2005-02-10 09:49 ------- The difference between foo_void and foo_void_offset is that for foo_void PRE cannot see that (struct Foo *) &i[0] is equivalent to (struct Foo *) &i. As such, for foo_void we end up with
<bb 0>: __p_2 = &i[0]; this_6 = (struct Foo *) &i[0]; this_6->i[0] = 1; <L3>:; i.3_7 = (struct Foo *) &i; D.1777_8 = i.3_7->i[0]; return D.1777_8; while for foo_void_offset the two uses of i are redundant and one is removed: <bb 0>: __p_2 = &i[0]; this_6 = (struct Foo *) &i[0]; this_6->i[0] = 1; <L3>:; D.1786_7 = this_6; D.1785_8 = D.1786_7->i[0]; return D.1785_8; So it seems we either need to teach PRE the equivalency between (struct Foo *) &i[0] and (struct Foo *) &i, or fold should canonicalize them to one form (which one? I guess &i[0]). -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19637