There was a time where they did different things, but through various refactors they’ve ended up with the same behavior. At this point the difference is that GetPawn() is like just putting Controller->Pawn in your code and you don’t have the overhead of a function call while GetControlledPawn() is callable by blueprints (since an inlined function can’t be a UFUNCTION).
Your pointing this out has made us chat about it and GetControlledPawn() is probably going to get renamed something like K2_GetPawn() to try and make it clearer that it is not really intended for C++ calling.