https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57359
--- Comment #29 from Richard Biener <rguenth at gcc dot gnu.org> --- And another testcase showing that with a conditional invariant store we may _never_ apply store-motion since conditional means we do not know the original order of stores in the loop. *sigh* typedef int A; typedef float B; float x[256]; void __attribute__((noinline,noclone)) foo(long unk, long ack) { B *q = x; for (long i = 0; i < unk; ++i) { q[i] = 42; if (ack & i) *((A*)q + 4) = 1; } } int main(void) { foo(5, 3); if (x[4] != 42) __builtin_abort(); return 0; } implementation-wise it should still work, in hoist_memory_references, when we computed the whole set of refs to apply store-motion to in a loop, track the sequencing of stores from entry to the latch edge and at merge points reject (parts of?) the sequence when there are mismatches in ordering. For the above there'd be { q[i], *((A*)q + 4) } and { q[i] } and thus a mismatch. If we reject only parts of the sequence those parts would need to be disambiguated against the previous stores in the sequence w/o TBAA. Trying to code that up now.