I'm still a proponent of C as portable assembly, and any sort of optimizations / UB that gets used resulting in warning messages that can improve the source code of the program rather than the one time artifacts the compiler produces.
I'm curious, are you working on such a C compiler?
For the two decades I've used C, I've not had a compiler that resembles "portable assembly." The unoptimized code they generate is extremely naive and far removed from anything an assembly programmer would write, easily resulting in many times more instructions than a simple & straightforward assembly implementation. As one might expect, the performance of such code is atrocious.
With gcc and clang, optimizations are absolutely mandatory if you want compilers to generate anything resembling good assembly. And it is still an uphill fight to avoid silly code. Just last week I scratched my head because gcc insisted on recreating a constant that is already there in a register, in that very same register it is recreating it in [1]. You could force it to keep the value in a register by creating a top level variable and use the asm("register") extension, but that just resulted in gcc making copies of that value into other registers.
Also worth pointing out that there's a lot of stuff in assembly that you cannot express in C directly. You want a rotate instead of two shifts and OR? You absolutely have to have an optimizing compiler, because rotate does not exist in C. Want to shift and test carry? No, that is not possible in C. Compiler extensions give you access to some things (e.g. popcnt) but the vast majority of assembly is only achievable indirectly by assuming the compiler can optimize your code and figure out what instruction you want. Also those extensions hardly make it portable..
I also think the vast majority of C code I see looks very different from assembly; it is written under the assumption of an optimizing compiler, which converts idiomatic C to somewhat idiomatic assembly.
C cannot express quite a few useful things that assembly can. Things like tail calls, stack management, non-flat address space just cannot be expressed.