How to design asynchronous LIFO?
It's easy to show that you cannot design an asychronous FIFO that you can prove never re-orders data.

The problem is the distinction between the last data pushed, and the data currently being pushed. If a simultaneous pop occurs, which data does it return?

In a synchronous FIFO, you cannot get a simultaneous pop and push by design. They simply cannot exist. When you have two asynchronous clock domains, it is possible.

There are two considerations. One is can you crash the logic? The other is can you define what you mean by 'correct order' for inputs and outputs. 

Whether you can crash the logic is a well-studied problem, metastability, and there's both good and bad news. The bad news news is that it's impossible to completely rule out crashing the logic. The good news is that, with proper design, you can make the possibility of a crash very small, and by adding extra logic in one latch increments, you can further reduce the probability exponentially, until it becomes likely you'll never see a crash in the age of the universe. 

The solution for metastability works well with a FIFO, when correct order is defined in each clock domain exclusively, and only the timing of the correct datum being emitted is uncertain. Unfortunately, in a LIFO, correct order is defined across the domains. When you come to test whether your LIFO works, you can create simultaneous push/pop to within 10nS tolerance, or to within 1nS, or to within 10pS (if you have fast enough logic), but you can never create a reproducible 'simultaneous', and so never prove whether your LIFO is working or not.

However, if you accept that in near-simultaneous push/pop situations that sometimes data order may be switched from what you expected, it is possible to design logic that is unlikely to fail. 

When faced with metastability, designers often set about chasing their tails to try to decide whether metastability is happening, and if so, block until it has resolved. Unfortunately, all attempted solutions of this type end up simply moving the metastability problem, not solving it. They create a Gordian Knot of extra logic gates that can be difficult to navigate. Alexander's Sword (Occam's Razor) is to note that with asynchronous domains, metastability always occurs, and you might as well face the problem of specification head on. 

A one-paragraph primer on metastability, to save you chasing references. Consider two edges 1uS apart. You need logic with an order of 1MHz bandwidth to resolve them. Now sweep the edge timing from +1uS through to -1uS. When they're 1nS apart, you need 1GHz bandwidth. As they approach coincidence, you approach needing an infinite bandwidth, which you can never have. Your finite bandwidth logic will settle exponentially, so you need to wait for it to resolve. Every one extra time constant you wait, it will resolve a further proportion of initial conditions, so the unresolved proportion falls exponentially. If it doesn't resolve in the time you've allowed, then you can get the crash.

It's worth looking at how other logic types deal with the problem of asynchronous timing. Let's look at latches, FIFOs and dual-port RAMs. 

Latches specify a setup and hold time. If the data and clock transition closer than these, the behaviour is unspecified. 

With FIFOs, the specification uncertainty is whether the new data comes out this clock, or the next one, which is rarely a problem. 

You could consider a dual-port RAM to be a collection of addressable one-deep LIFOs. Usually the asynchronous ports nature is to avoid logic crashes if simultaneous accesses occur, as data integrity is usually handled by their use a ping-pong buffers, reading rarely occurs at the same address writing is happening. Should a single location be hit with both a read and a write at the same time, then the tautologous 'write completed' concept comes into play. Good luck with specifying which data you get ahead of time.

With a LIFO, it's the logic data order that's at issue, which is likely to be a killer.