The issue isn’t just that src->data and dest->data might overlap, which TBAA doesn’t forbid anyway (although that’s what restrict can help with). It’s that dest->data might alias src->len, and magically change the length midloop. I doubt there’s any legitimate image manipulation where that would happen, but the compiler doesn’t know that...
This is exactly why I don't propose to do away with UB but to limit what compilers can do with UB. The programmer in C cannot be prevented from writing terrible code where e.g. a loop counter is written over by an aliased pointer in the middle of the loop - the current standard doesn't prevent it either. In fact, strictly conforming C code can use char pointers to randomly write over any aliased variables if I understand it correctly. The positive thing about UB is that it makes this the programmers problem, not the compilers problem. The negative thing is that in current interpretations, the compiler is free to detect such an error and then instead of either failing to compile with a warning or just letting things happen as the programmer has specified, it can introduce global program failures because "it's impossible to have UB".