I am not 100% convinced on the third transformation,
> The final optimization notices that q is never written to, so we can replace q[0] by its initial value 0:
Can we? q is at a language level, possibly aliased with the write immediately above to (p+1), and we know it's aliased because of the if statement.
Now, that's a C rule, and the article does note that it is only using C syntax to express LLVM. So, I guess, what are LLVM's aliasing rules?
(Indeed, there was originally a write to q, which we replaced with an aliased write to q, so it seems to me that on the whole, the various optimizations are assuming different things about aliasing.)
> Can we? q is at a language level, possibly aliased with the write immediately above to (p+1)
It's not, because writing to a one-past-the-end pointer is UB.
> Indeed, there was originally a write to q, which we replaced with an aliased write to q, so it seems to me that on the whole, the various optimizations are assuming different things about aliasing.
That optimization pass doesn't know anything about aliasing, it just replaced an integer with another integer that's equal to the first.
> The final optimization notices that q is never written to, so we can replace q[0] by its initial value 0:
Can we? q is at a language level, possibly aliased with the write immediately above to (p+1), and we know it's aliased because of the if statement.
Now, that's a C rule, and the article does note that it is only using C syntax to express LLVM. So, I guess, what are LLVM's aliasing rules?
(Indeed, there was originally a write to q, which we replaced with an aliased write to q, so it seems to me that on the whole, the various optimizations are assuming different things about aliasing.)