[llvm-dev] Kaleidoscope tutorial: extern functions failing

Eli Baum via llvm-dev llvm-dev at lists.llvm.org
Sun Jan 6 18:20:51 PST 2019

Hi all,

I am new to LLVM and have been working through the Kaleidoscope tutorial.
Everything is working fine so far except for local externs (as opposed to
things like the math functions, which are working). Note that I have seen
this bug with the reference code listing, as well as my own code. link to
code: https://llvm.org/docs/tutorial/LangImpl05.html#full-code-listing

[c34n10 kaleidoscope] ./toy
ready> extern sin(x); sin(1);
ready> Read extern:
declare double @sin(double)

ready> ready> Evaluated to 0.841471
ready> extern putchard(x); putchard(120);
ready> Read extern:
declare double @putchard(double)

ready> ready> Failure value returned from cantFail wrapped call
UNREACHABLE executed at ~/project/llvm/include/llvm/Support/Error.h:732!
Aborted (core dumped)

sin is, of course, defined in libm. putchard is declared in my code, per
the tutorial, as

/// putchard - putchar that takes a double and returns 0.
extern "C" DLLEXPORT double putchard(double X) {
  fputc((char)X, stderr);
  return 0;

Other posts online suggest that this issue could be caused by not compiling
with -rdynamic, but I am.

The actual error is occuring with the following code (on the cantFail line)

auto ExprSymbol = TheJIT->findSymbol("__anon_expr");
assert(ExprSymbol && "Function not found");

// cast to double-returning function
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());

and some investigation with GDB reveals that the hasError flag of
ExprSymbol.getAddress() is true, which is why the cantFail is failing. As
to why that flag is set, I'm at a loss. I have run through GDB with both
the sin and putchard examples, to try and see where they are diverging. I'm
not totally sure, but I think the divergence might be happening on line 347
of RuntimeDyld.cpp:

if (auto IOrErr = processRelocationRef(SectionID, I, Obj, LocalSections,

That is, in the sin example, this expression is false; in the putchard
example, it is true. However there may be something earlier on that I
missed – there were a few thousand lines of GDB logging to diff through.

It appears not to be an issue with the function itself, nor the
compilation/link process: from within GDB, I can successfully run call
putchard(120), so the symbol is definitely being included in the
executable. Just for some reason the JIT can't find it.

Finally, my makefile looks like

LIBS=core orcjit native analysis executionengine instcombine object
runtimedyld scalaropts support
FLAGS=`llvm-config --cxxflags --ldflags --system-libs --libs $(LIBS)`

%: %.cpp
        clang++ -v -g3 -O0 $^ -o $@ $(FLAGS) -rdynamic

Please let me know if I can provide any additional code or debug
information. I don't know a ton about LLVM so am a bit lost as to where to
go from here.

(Note: I also have posted this question on the LLVM IRC channel, and on

Thank you so much! I'm very excited to start working with LLVM and have
just been stuck on this issue for a couple of days.

Eli Baum
eli.baum at yale.edu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190106/6fbc8cf2/attachment.html>

More information about the llvm-dev mailing list