I have been following along with the LLVM Kaleidoscope ("My First Language Frontend With LLVM Tutorial") tutorial and have run into a strange bug in chapter 3. Those familiar with the tutorial know that on exit, the program prints the generated LLVM IR for the entire program, however when I try to print TheModule's generated code, top-level expressions are omitted from the IR. This includes function calls and binary operations that are not located within the scope of another function.
Oddly, when I type a top-level expression into the terminal, the main loop appropriately prints the top-level expression IR code.
I haven't modified any of the source code (as to not introduce any user bugs), and compiled with the same flags as shown just above the source code in the tutorial.
Here's the program running + the final module output:
$ ./toy
ready> 4+5;
ready> Read top-level expression:define double @__anon_expr() {
entry:
ret double 9.000000e+00
}
ready> def foo(a b) a*a + 2*a*b + b*b;
ready> Read function definition:define double @foo(double %a, double %b) {
entry:
%multmp = fmul double %a, %a
%multmp1 = fmul double 2.000000e+00, %a
%multmp2 = fmul double %multmp1, %b
%addtmp = fadd double %multmp, %multmp2
%multmp3 = fmul double %b, %b
%addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4
}
ready> def bar(a) foo(a, 4.0) + bar(31337);
ready> Read function definition:define double @bar(double %a) {
entry:
%calltmp = call double @foo(double %a, double 4.000000e+00)
%calltmp1 = call double @bar(double 3.133700e+04)
%addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp
}
ready> extern cos(x);
ready> Read extern: declare double @cos(double)
ready> cos(1.234);
ready> Read top-level expression:define double @__anon_expr() {
entry:
%calltmp = call double @cos(double 1.234000e+00)
ret double %calltmp
}
ready> ready> ; ModuleID = 'my cool jit'
source_filename = "my cool jit"
define double @foo(double %a, double %b) {
entry:
%multmp = fmul double %a, %a
%multmp1 = fmul double 2.000000e+00, %a
%multmp2 = fmul double %multmp1, %b
%addtmp = fadd double %multmp, %multmp2
%multmp3 = fmul double %b, %b
%addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4
}
define double @bar(double %a) {
entry:
%calltmp = call double @foo(double %a, double 4.000000e+00)
%calltmp1 = call double @bar(double 3.133700e+04)
%addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp
}
declare double @cos(double)
I am on macOS Tahoe 26.4.1 (Apple Silicon), Clang 22.1.4
If anyone can immediately see what's wrong with the tutorial or if this is a known issue, please let me know of any work-arounds/updated docs.
Thank you!