https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69776
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
extern void *malloc (__SIZE_TYPE__);
extern void abort (void);
void __attribute__((noinline,noclone))
foo (int *pi)
{
if (*pi != 1)
abort ();
}
int
main()
{
void *p = malloc(sizeof (double));
int *pi = p;
double *pd = p;
*pi = 1;
int a = *pi;
*pd = 0;
*pi = a;
foo (pi);
return 0;
}
FRE removes *pi = a because it stores the same value as *pi = 1 which is
found via
val = vn_reference_lookup (gimple_assign_lhs (stmt),
gimple_vuse (stmt), VN_WALK, NULL);
and thus treats the *pi = a store as a load, losing the fact that it
cannot TBAA disambiguate against other stores.