Now we have (at least) three different IR formats that are very similar but have slight differences:
1. LLVM IR. Created for LLVM internal use and may only work with specific LLVM version(s) (correct me if I'm wrong here), is not portable across HW architectures.
2. WebAssembly. Made for web browsers.
3. SPIR-V. Made for OpenCL and Vulkan shaders/kernels.
All of the above have a specification, a binary representation, a text representation and associated tooling. Some (or most?) of the tools seem to operate by doing a source level translation from WASM or SPIR-V into LLVM, then doing optimizations or JIT and possibly converting the resulting LLVM IR back to WASM or SPIR-V. In my experience, the tooling with WASM and SPIR-V is inferior to LLVM IR tools or native code tools (binutils etc).
There's a lot of duplicate work going on here, but I understand that it's difficult to get the stakeholders of Web browsers, GPU APIs and compiler infrastructure to even discuss what could/should be done.
Compiler IR's suitable for AOT compilation (ie. the whole code is compiled before it's executed, although it might be done at runtime) are a game changer on how we deal with programming languages and runtimes and a huge improvement on Java-like bytecode+JIT which never quite delivered what it promised.
What would you use that for, if you had it?
Universities should teach more about mainframe architectures.