You're implying that GCC doesn't have a separation between language front-end and compilation back-end, but that's not true.
GCC has a consistent internal representation known as GENERIC where the front-ends and back-ends meet just like LLVM.
This missing separation is even a problem for writing tests in GCC: Often it would be quite easy to write a small program in GIMPLE-IR (or RTL) and test your optimization pass against it. But you can't write GIMPLE-IR (it needs to go through GENERIC all the time), so you need to write a C file that is then translated into the IR you want to test again. This is sometimes not so easy with all that different optimization passes that run before your pass and hopefully that doesn't change in the future either.... There was some work on this (I don't know about the current status) but almost all of GCC's tests are still integration tests against C files (I think they addressed this by extending the C-front end to be able to parse functions marked with __gimple as Gimple-IR). Also GIMPLE didn't start as a separate IR. It started as a more restricted tree-structure. Even today operands are still tree's and optimization passes are called tree-<something>.c.
With LLVM I can write a toy compiler that outputs LLVM IR with printf and then just pipe it into llc to compile it. That's pretty cool. I didn't want to imply that GCC has NO separation between IRs but the whole story is much messier compared to LLVM. Which is actually fine, LLVM is much younger than GCC and could learn a lot from it. And GCC is still pretty great in the use cases it was intended for.
https://gcc.gnu.org/wiki/GimpleFrontEnd
I'm not sure how complete and usable it is though.
And there's three separate forms of GIMPLE while you're at it.
It's way easier to work with LLVM IR.
LLVM-IR has enabled this nice separation between the language front-end and the compilation back-end. GCC could have done that too: they didn't for political reasons. Why? Someone could have used GCC's C++ front-end for its proprietary compilation pipeline. Today this is nearly impossible to change in GCC.
There are also some other advantages for LLVM I like: it supports multiple architectures in a single binary. With GCC I need to compile the compiler either for x64 or arm but not both. GCC is still great but it's not surprising that LLVM is so successful.