There's no reason why VLAs have to be allocated uniformly on the stack. The C standard doesn't say that "auto" = stack. It just says that it has to be automatically deallocated when it's out of scope.
But even as implemented today, in practice, it all works fine if you're not working with really large arrays. In a lot of scenarios, you do not. This isn't really any different than using recursion when you reasonably assume that recursion depth is not going to be large. Sometimes it's just easier and clearer all around.
That it the main reason why so many CVEs are related to memory corruption in C code as cause, in practice things do not work fine.
Which was the main theme at Linux Kernel Security Summit 2018.
Just for info, if not wanting to bother watching Google's talk, 68% of Linux kernel exploits were caused by out of bounds errors, including those caused by VLAs misuse.
Languages like Ada do have them, but then again the language also protects against stack corruption.