The overhead in this example comes mostly from Crystal’s stdlib runtime, not LLVM.
The following Crystal code resembles the C implementation more closely:
require "lib_c"
require "c/stdio"
LibC.printf pointerof("HELLO!\n".@c)
Compiled with --prelude=empty --no-debug
this emits 33 lines LLVM IR and works pretty similar as the C example with only minimal overhead.
Obviously, you wouldn’t want to write a larger program like this. And for writing any serious application, you will need some kind of libraries and enhancements to a minimal runtime. Crystal’s stdlib just provides a lot of features you’ll probably need anyway, right from the start.