You are correct in saying that it is tun + offset which is dereferenced (not tun itself).
(BTW tun is obviously a pointer in the code given, no need to take its address.)
That means that the compiler knows, if it reaches the if, that tun+offset is not NULL, but not necessarily that tun is not NULL.
That would be true in general. But what everyone here seems to have missed, is that offset is known at compile time.
If offset is NULL, then either tun is NULL and we enter the realm of undefined behavior and the compiler is permitted to remove the check, or tune is not NULL in which case the test is dead code.
If however offset is non NULL, then tun must be non NULL if the test is reached.
To summarize, if sk is the first member of tun (offset zero), then the compiler has all rights to remove the test. If not, this is a compiler bug.