Straight to the point -- I'm trying to link two (or more) llvm modules together, and I'm facing a certain odd error from LLVM.
I don't want to post too much code, so I'll use a bunch of pseudo here.
I have 3 modules, let's say A, B, and C. A is the main module; I initialise llvm::Linker
with it. B and C are secondary modules; I call linker.linkInModule(B and C)
.
All 3 modules have, among other things, these two types defined:
%String = type { i8*, i64 }
%Character = type { i8*, i64 }
Note that they have the same member types. Furthermore, a function foo
is defined as such (in module B):
define i1 @_ZN9Character7hasDataEv(%Character*) { }
This function is declared in modules A and C. Now, all seems well and good -- this function is called from both modules A and C, and the IR looks normal, like so:
%21 = call i1 @_ZN9Character7hasDataEv(%Character* %4)
Here comes the problem: when all 3 modules are linked together, something happens to these types:
%2
(%String
) and %3
(%Character
).Strangely, while this transformation occurs in both modules A and C, the bug only occurs in C -- note that A is the so-called "main" module.
The function definition of the linked file is now
define i1 @_ZN9Character7hasDataEv(%2*)
Note how %Character
, or %3
, got turned into %2
. Furthermore, at the callsite, in what is presumably an attempt to un-merge the types, I get this:
%10 = call i1 bitcast (i1 (%2*)* @_ZN9Character7hasDataEv to i1 (%3*)*)(%2* %2)
Curiously, although the function was casted from i1 (%2*)
to %3 (%2*)
, the argument passed (arg. 1) is still of type %2
. What's going on?
Note that in module A, whatever is going on is done properly, and there is no error. This happens for a number of functions, but only in module C.
I've tried reproducing it by copy-pasting these to .ll
files and calling llvm-link
followed by llvm-dis
, but 1. the types are not merged, and 2. there is no such bug.
Thanks...?
Okay, turns out that, after some poking around in the llvm IRC channel, llvm::Linker was meant to be used with an empty llvm::Module as the starting module.
Also, in my use-case I am reusing the same llvm::Type (the actual thing in memory) across different modules that I link together. They said it wasn't illegal, but that it was never tested, so... ¯\_(ツ)_/¯
So anyway, the problem was fixed by starting with an empty module to pass to the linker.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With