[LLVMdev] Problem with linking modules which use a shared type

Jeremy Lakeman Jeremy.Lakeman at gmail.com
Thu Jun 27 19:35:51 PDT 2013


I've tripped over this behaviour as well. I ended up working around the
problem by creating a new context every time I wanted to link modules
together. Which led to me accidently generating one module using two
different contexts. Which isn't an error that is detected by module
verification. It only causes issues for comparisons like Type equality that
compare pointers, and those types of problems can be tricky to debug.


On Thu, Jun 27, 2013 at 8:14 PM, Marcus Frenkel <
marcus.frenkel at fernuni-hagen.de> wrote:

> Hi,
>
> I stumbled upon a strange thing regarding types and module linking, which
> I don't quite get, so maybe someone around here can enlighten me.
>
> Consider the following code, which will create 2 modules m1 and m2, and a
> named structured type %T = { i32 }; m1 contains only a function definition
> f(%T), m2 contains a function declaration f(%T) and a function definition
> h(%T), where h will call f in its body. Note that all functions in m1 and
> m2 are based upon the same structured type %T:
>
>     LLVMContext context;
>     BasicBlock* b;
>
>     // modules
>     Module *m1 = new Module( "m1", context ),
>            *m2 = new Module( "m2", context );
>
>     // types
>     vector<Type*> types;
>
>     types.push_back( IntegerType::get( context, 32 ) );
>
>     Type* sType = StructType::create( types, "T" );
>
>     types.clear();
>     types.push_back( sType );
>
>     FunctionType* ft = FunctionType::get( Type::getVoidTy( context ),
> types, false );
>
>     // m1
>     Function* f = Function::Create( ft, GlobalValue::ExternalLinkage, "f",
> m1 );
>
>     b = BasicBlock::Create( context, "b", f );
>     ReturnInst::Create( context, b );
>
>     verifyModule(*m1);
>
>     // m2
>     Function* fDecl = Function::Create( ft, GlobalValue::ExternalLinkage,
> "f", m2 );
>     Function* h = Function::Create( ft, GlobalValue::ExternalLinkage, "h",
> m2 );
>
>     vector<Value*> args;
>     args.push_back( h->arg_begin() );
>
>     b = BasicBlock::Create( context, "b", h );
>     CallInst::Create( fDecl, args, "", b );
>     ReturnInst::Create( context, b );
>
>     verifyModule(*m2);
>
>
> Each module for itself is okay and passes the verification, leading to the
> following IR code:
>
>     ; ModuleID = 'm1'
>
>     %T = type { i32 }
>
>     define void @f(%T) {
>     b:
>       ret void
>     }
>
>     =====================
>     ; ModuleID = 'm2'
>
>     %T = type { i32 }
>
>     declare void @f(%T)
>
>     define void @h(%T) {
>     b:
>       call void @f(%T %0)
>       ret void
>     }
>
>
> However, if both modules are linked together as per
>
>     // link
>     Linker::LinkModules( m1, m2, Linker::DestroySource, nullptr );
>     verifyModule(*m1);
>
>
> the type %T in both modules will not be unified, but instead two separate
> types %T and %0 will be introduced, leading to the following IR code, which
> of course won't pass the verification any more due to type
> incompatibilities in the function call:
>
>     ; ModuleID = 'm1'
>
>     %0 = type { i32 }
>     %T = type { i32 }
>
>     define void @f(%0) {
>     b:
>       ret void
>     }
>
>     define void @h(%T) {
>     b:
>       call void @f(%T %0)
>       ret void
>     }
>
>
> Even more strange, if both modules and the types are created separately
> from each other (meaning, that the type %T is created for both modules
> anew), but within the same LLVMContext, the call to LinkModules will result
> in a proper module with a unified type %T.
>
> Is that a bug or a feature of LLVM? I thought that types will be handled
> at context level and not module level, so that it should be clear that %T
> in both m1 and m2 can be unified, given that they even are based upon the
> same llvm::Type type (which becomes even more strange with the fact, that
> they will be unified, when they are *not* based upon the same llvm::Type
> type).
>
> Any explanation of that behavior would be much appreciated!
>
>
> Cheers,
> Marcus
> ______________________________**_________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/**mailman/listinfo/llvmdev<http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130628/f39cc8f8/attachment.html>


More information about the llvm-dev mailing list