------- Comment #7 from rguenth at gcc dot gnu dot org 2005-10-09 09:47 -------
The non-null check is now removed for the foo_char() case by VRP (note that
the non-null check for the two viod-cases are _not_ removed by VRP but by DOM1.
The propagation of the initialization in foo_void_offset is layed ground
for by FRE, which changes
iftmp.3_6 = (struct Foo *) __p_5;
if (iftmp.3_6 != 0B) goto <L0>; else goto <L1>;
<L0>:;
this_11 = (struct Foo * const) iftmp.3_6;
this_11->i[0] = 1;
iftmp.3_12 = iftmp.3_6;
goto <bb 3> (<L2>);
<L1>:;
iftmp.3_10 = iftmp.3_6;
<L2>:;
D.2114_7 = (struct Foo *) &i[0];
D.2113_8 = D.2114_7->i[0];
return D.2113_8;
to
iftmp.3_6 = (struct Foo *) __p_5;
if (iftmp.3_6 != 0B) goto <L0>; else goto <L1>;
<L0>:;
this_11 = iftmp.3_6;
this_11->i[0] = 1;
iftmp.3_12 = iftmp.3_6;
goto <bb 3> (<L2>);
<L1>:;
iftmp.3_10 = iftmp.3_6;
<L2>:;
D.2114_7 = iftmp.3_6;
D.2113_8 = D.2114_7->i[0];
which can then be optimized further. This doesn't happen for the exact
same example with void * exchanged with char * -- is FRE paying attention
to some strict-aliasing rules here? Note there is no difference in alias
information after CCP1.
For the record, the char* example mentioned would look like
int foo_char(void)
{
int i[2];
new (reinterpret_cast<char *>(&i[0])) Foo();
return reinterpret_cast<Foo *>(&i[0])->i[0];
}
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19637