bscarlet / llvm-general

Rich LLVM bindings for Haskell (with transfer of LLVM IR to and from C++, detailed compilation pass control, etc.)
http://hackage.haskell.org/package/llvm-general
132 stars 38 forks source link

Invalid type for pointer element #145

Closed tinco closed 9 years ago

tinco commented 9 years ago

Hi,

I ran into this exception, and I'm not certain what causes it:

Assertion failed: (isValidElementType(EltTy) && "Invalid type for pointer element!"), function get, file Type.cpp, line 732.

I think I had this same exception a couple of months ago, and back then I found a solution to it. But now it happened again and I forgot what the problem last time was. I suppose somewhere my code tries to dereference a pointer to something that's not a valid pointer element. But I get no information about what that element type is, no backtrace either.

Is there a way to get more information?

As an aside, why is this C++ code? This is just IR code generation right? Perhaps we can work something out to do this in pure Haskell, or do you feel IR is so complicated it would be a lot of work?

bscarlet commented 9 years ago

That error indicates you tried to construct a pointer type which is not valid; there are a few types X for which (pointer to X) is not valid in llvm IR.

http://llvm.org/doxygen/Type_8cpp_source.html#l00765

I'd guess the most likely case is that you're trying to make a pointer to void. In llvm IR you should use i8* or i64* or whatever's appropriate.

Since LLVM asserts at these points, rather than throwing or some such, a backtrace would be hard. There is a verification pass, which you can apply with LLVM.General.Analysis.verify, but it can't catch errors of construction like this one.

llvm-general uses FFI to C++ code because it gives you access to more of LLVM than generating textual IR. It does the Haskell-IR to C++ IR (and back) in particular using the C++ API instead of serialized IR to avoid adding unnecessary overhead. For applications involving intensive optimization passes, that overhead is often irrelevant; but for others (e.g. haskell generation of small LLVM snippets for JIT) it can be more important.

I would like to build a second Haskell-only serializer/deserializer pair in llvm-general-pure (and QuickCheck them against the C++ versions), so that a Haskell project could opt out of linking in the LLVM libraries entirely if it just wanted to generate textual IR to pass to LLVM in another process.

tinco commented 9 years ago

None of my code explicitly constructs a pointer to anything other than integers. I added trace points at every instance of the PointerType constructor, and even just replaced PointerType with IntegerType just to be sure, still the error. So I think one of the instructions implicitly calls this function..

bscarlet commented 9 years ago

Can you make a test case and simplify it down to something reasonable to share? Without more information on the circumstances of your issue there's not much more I can do.

bscarlet commented 9 years ago

For lack of a more detailed description of the circumstances necessary to trigger this bug, I can't proceed on my end, so I'm going to close this bug. If you can offer a test case please re-open.