My understanding is that the problem with VLIW is that it exposes too much. Anything you expose via the instruction set becomes fixed permanently, so if you have say 4X wide VLIW there is no way to
ever make it wider or change how things like dispatching work. The only way to do that would be to start pipelining and scheduling VLIW chunks, in which case you are back where you started.
Instruction level parallelism achieved by decoding a single stream and then sorting and scheduling requires more silicon and a bit more power, but low power high performance superscalar chips like modern ARM64 CPUs have shown that the cost is not that high and that you can go very wide. The M1's Firestorm cores are 8X wide from what I read, which is better than Itanium.
Since the whole superscalar architecture is hidden, it can evolve freely.
That being said I don't think VLIW was a horrible idea at the time, and it might still have a chance if it were revived in specialized high performance or ultra-low-power use cases. The mistake was betting the farm on it.
The other big thing we learned since then is that the important part of RISC wasn't reduced instruction set size, but uniform instruction size and encoding. That allows you to decode arbitrarily wide chunks of instructions in parallel without crazy brute force hacks like those required to do parallel decoding of the variable length X86 instruction stream. The problem with CISC isn't how many instructions there are, but the complexity of the encoding and the presence of a lot of confounding requirements that arise from instructions that to very different things at once (e.g. complex math with memory operands). You want the instruction stream to be trivial to decode and easy to schedule.
In the end the best approach seems to be a simple general purpose instruction set augmented with special instructions for common special cases that can be greatly accelerated this way (e.g. vector operations, floating point, cryptography, etc.), and all with a logical fixed length encoding that is easy to decode in parallel. Load-store architecture and a relaxed memory ordering model seem to also be performance wins since separation of concerns simplifies the scheduler. The future (for conventional CPUs) looks a lot like ARM64 and RISC-V.