No, p+1 is OK because you are allowed to make a pointer one past the end in C (so that common pointer loops work as expected) but you cannot dereference them.
So now I think it's the first optimization the one that is wrong. If you replace a variable with another, don't you need to keep information of the original variable?
I mean, if a==b and you do *a=1 you can replace it with *b=1, but then you need to keep the information that 'a' was written to, so other optimizations (the third one) don't think it wasn't. Or am I missing something else here?
Edit: sorry for the code block, otherwise the asterisks are removed.
It constructs a pointer to the "one past the end" element, but that is fine, and the original program never dereferences that pointer. Again: there is no UB in the original program.
But then, why such a long article for a code whose second line is a UB ('p+1' is undefined)?