Define "runs fine". You can execute a function call to f2() just as you can execute a function call to f1(), that's not a problem. The behavior of a program that dereferences the pointer returned by either of those function calls is undefined.
There's no guarantee that it will work correctly as it is undefined behavior. The two examples are functionally the same. The address returned will still contain the location of where x was, x's value (2) will probably still be there after the function returns. But it could be re-purposed at any time so it becomes unsafe to use.
Funny but very illustrative link. I will read it all. Thanks for explaining it. By-the-way, when a function returns a value, that is also related with the local memory defined within the function because 2 is stored somewhere in the memory. Then, why does the "value return" has no problem?