MIPS compilers for C emit "addu" instructions for signed integer additions rather than using "add", to avoid overflow traps.
Using unsigned arithmetic for signed is not just so that C programs relying on the behavior do not blow up. When overflow behavior is reversible wraparound, the compiler more freedoms in rearranging a calculation. Suppose the programmer has written some a + b + c, and ensured that there is no overflow (when it's added left to right, as the abstract semantics says). If the addition mechanism has reversible overflow, the compiler can rearrange it to do the additions in any order. The result will be the same, correct one that (a + b) + c would produce.
But the idea that two's complement itself "wraps around" is mostly a myth. Two's complement has a fixed range of representation, and a result of adding two elements from that representation can be out of that range. In that case, the truncated value whose bit pattern corresponds to the unsigned arithmetic is not the correct result.
Or just does what C does, make it UB and the programmers will be aware of implementation of overflows and won't suffer because of added checks. They will do the checks themselves if they want and handle their numbers with care
Imo the answer always boils down to performance. Java has no UB yet it works on billion devices (citation needed). It is doable, just costly.
Some examples:
1. When C came out, you couldn't assume a two's complement machine. So some architectures would yield different results on signed over/underflow than others, and some architectures might trap on overflow. Hence, signed overflow is undefined in C.
2. Did you know the Lisp Machine had a C compiler? It did. Because pointers on the Lisp machine were tagged and bounds-checked to ensure memory safety, this compiler implemented C pointers with fat pointers, containing a reference to an object and an offset within that object. Most machines you are familiar with allow indirecting through arbitrary integers; the Lisp Machine is an example of one that does not, trapping on invalid pointer accesses. Having C and C programs available in both environments mean that indirecting through a pointer that does not point to or inside some pre-existing static or dynamically allocated object is undefined.
3. Operating systems with virtual memory can arrange things such that indirecting through 0 (NULL) will raise a segmentation violation in user code, guaranteeing a pointer value that is always invalid -- but inside the kernel you may want to access memory location 0. So accessing null pointers is undefined.
By leaving these undefined, you are not committing implementors to adapt the abstract machine to the underlying hardware in cases where hardware can widely differ, allowing for simple implementations that yield fast code on all architectures they compile for yet still allowing for a useful subset of C code to be 100% portable.