Signed integer overflow is undefined, so the only obligation is that the code operates correctly when signed integer overflow doesn't happen. So, yes all those options are permissible, because as far as the C standard specifies, it's "add i,j; if false jump to random; store k".
If you want to add a definition for signed integer overflow (as C++ is considering, see http://wg21.link/P0907r0 ) then it would be defined and the compiler would no longer get to consider "if signed overflow" and "if false" the same.