https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90668
Bug ID: 90668 Summary: loop invariant moving a dependent store out of a loop Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- The test case below was reduced from an example discussed by the WG14 C Object Model Study Group. It looks like the lim pass allows the store to *q to be moved out of the loop based on an simplistic TBAA assumption, overwriting the store to p[0]. Richard, your thoughts? __attribute__((noinline, noclone)) void f (int n, int *p, void *q) { for (int i = 0; i < n; ++i) { int t = p[i]; *(void**)q = (void*)0xdeadbeef; // moved out of the loop p[i] = t + i; } } int main (void) { int *p = __builtin_malloc (sizeof p); *p = 0; f (1, p, p); __builtin_printf ("*p = %#x\n", *p); // prints 0xdeadbeef when 0 is expected } The -fdump-tree-lim2-details output shows: Querying dependencies of ref 2 in loop 1: independent Executing store motion of MEM[(void * *)q_11(D)] from loop 1 Moving statement q__lsm.4 = MEM[(void * *)q_11(D)]; (cost 0) out of loop 1. ... __attribute__((noinline, noclone)) f (int n, int * p, void * q) { void * q__lsm.4; int t; int i; long unsigned int _1; long unsigned int _2; int * _3; int _4; <bb 2> [local count: 118111600]: if (n_8(D) > 0) goto <bb 5>; [89.00%] else goto <bb 4>; [11.00%] <bb 5> [local count: 105119324]: q__lsm.4_6 = MEM[(void * *)q_11(D)]; <bb 3> [local count: 955630224]: # i_17 = PHI <0(5), i_14(6)> _1 = (long unsigned int) i_17; _2 = _1 * 4; _3 = p_9(D) + _2; t_10 = *_3; q__lsm.4_5 = 3735928559B; _4 = t_10 + i_17; *_3 = _4; i_14 = i_17 + 1; if (n_8(D) > i_14) goto <bb 6>; [89.00%] else goto <bb 7>; [11.00%] <bb 6> [local count: 850510900]: goto <bb 3>; [100.00%] <bb 7> [local count: 105119324]: # q__lsm.4_15 = PHI <q__lsm.4_5(3)> MEM[(void * *)q_11(D)] = q__lsm.4_15; <bb 4> [local count: 118111601]: return; }