Our aliasing code is failing pretty badly in disambiguating memory addresses,
which in turn can lead to missing opportunities to remove memory operations.
Here's an exmaple taken from GCC itself (find_unreachable_blocks):
typedef unsigned int size_t;
extern void *xmalloc (size_t) __attribute__ ((__malloc__));
struct basic_block_def *dest;
typedef struct edge_def *edge;
typedef struct basic_block_def *basic_block;
extern int n_basic_blocks;
extern edge frob ();
find_unreachable_blocks (int frobit)
basic_block *tos, *worklist, bb;
tos = worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
edge e = frob();
if (!(e->dest->flags & 4))
e->dest->flags |= 4;
*tos++ = e->dest;
The store into e->dest->flags does not affect e or e->dest. Thus we only need
to load e->dest once. Unfortunately, we load it twice.
I'll be checking this testcase into the testsuite (xfailed appropriately).
Confirmed, CCing Daniel because he is working on structure aliasing right now.
This is basically PR 13761 almong other bugs.
Fixed by Daniel's patches.
We get now:
D.1542 = xmalloc ((long unsigned int) n_basic_blocks * 4);
e = frob ();
D.1544 = e->dest;
D.1545 = D.1544->flags;
if ((D.1545 & 4) == 0) goto <L0>; else goto <L1>;
D.1544->flags = D.1545 | 4;
*(struct basic_block_def * *) D.1542 = D.1544;